|
|
|
@ -6,6 +6,7 @@ |
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Linq; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using NodaTime; |
|
|
|
using Squidex.Domain.Apps.Core.Contents; |
|
|
|
@ -38,6 +39,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
Capacity = int.MaxValue; |
|
|
|
} |
|
|
|
|
|
|
|
private Task LoadContext(ContentCommand command, bool optimize) |
|
|
|
{ |
|
|
|
return context.LoadAsync(command.AppId, command.SchemaId, command, optimize); |
|
|
|
} |
|
|
|
|
|
|
|
protected override bool IsDeleted() |
|
|
|
{ |
|
|
|
return Snapshot.IsDeleted; |
|
|
|
@ -94,6 +100,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
|
|
|
|
await CreateCore(c); |
|
|
|
|
|
|
|
// Skip validation for singleton contents because it is published from command middleware.
|
|
|
|
if (context.Schema.SchemaDef.IsSingleton) |
|
|
|
{ |
|
|
|
ChangeStatus(c.AsChange(Status.Published)); |
|
|
|
@ -173,7 +180,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
|
|
|
|
if (c.DueTime > SystemClock.Instance.GetCurrentInstant()) |
|
|
|
{ |
|
|
|
ScheduleStatus(c, c.DueTime.Value); |
|
|
|
ChangeStatusScheduled(c, c.DueTime.Value); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@ -251,12 +258,17 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
{ |
|
|
|
await GuardContent.CanChangeStatus(c, Snapshot, context.Workflow, context.Repository, context.Schema); |
|
|
|
|
|
|
|
if (c.Status != Snapshot.Status) |
|
|
|
if (c.Status == Snapshot.Status) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// Check for script to skip cloning if no script configured.
|
|
|
|
if (!c.DoNotScript && context.HasScript(c => c.Change)) |
|
|
|
{ |
|
|
|
var change = GetChange(c.Status); |
|
|
|
|
|
|
|
// Clone the data, so that we do not change it in cases of errors.
|
|
|
|
var data = Snapshot.Data.Clone(); |
|
|
|
|
|
|
|
var newData = await context.ExecuteScriptAndTransformAsync(s => s.Change, |
|
|
|
@ -268,7 +280,16 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
StatusOld = Snapshot.EditingStatus |
|
|
|
}); |
|
|
|
|
|
|
|
if (!newData.Equals(Snapshot.Data)) |
|
|
|
// Just update the previous data event to improve performance and add less events.
|
|
|
|
var previousEvent = |
|
|
|
GetUncomittedEvents().Select(x => x.Payload) |
|
|
|
.OfType<ContentDataCommand>().FirstOrDefault(); |
|
|
|
|
|
|
|
if (previousEvent != null) |
|
|
|
{ |
|
|
|
previousEvent.Data = newData; |
|
|
|
} |
|
|
|
else if (!newData.Equals(Snapshot.Data)) |
|
|
|
{ |
|
|
|
Update(c, newData); |
|
|
|
} |
|
|
|
@ -281,16 +302,18 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
|
|
|
|
ChangeStatus(c); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private async Task UpdateCore(UpdateContent c, Func<ContentData, ContentData> newDataFunc, bool partial) |
|
|
|
private async Task UpdateCore(UpdateContent c, Func<ContentData, ContentData> update, bool partial) |
|
|
|
{ |
|
|
|
await GuardContent.CanUpdate(c, Snapshot, context.Workflow); |
|
|
|
|
|
|
|
var dataNew = newDataFunc(Snapshot.Data); |
|
|
|
var newData = update(Snapshot.Data); |
|
|
|
|
|
|
|
if (!dataNew.Equals(Snapshot.Data)) |
|
|
|
if (newData.Equals(Snapshot.Data)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!c.DoNotValidate) |
|
|
|
{ |
|
|
|
if (partial) |
|
|
|
@ -305,11 +328,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
|
|
|
|
if (!c.DoNotScript) |
|
|
|
{ |
|
|
|
dataNew = await context.ExecuteScriptAndTransformAsync(s => s.Update, |
|
|
|
newData = await context.ExecuteScriptAndTransformAsync(s => s.Update, |
|
|
|
new ScriptVars |
|
|
|
{ |
|
|
|
Operation = "Update", |
|
|
|
Data = dataNew, |
|
|
|
Data = newData, |
|
|
|
DataOld = Snapshot.Data, |
|
|
|
Status = Snapshot.EditingStatus, |
|
|
|
StatusOld = default |
|
|
|
@ -318,11 +341,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
|
|
|
|
if (!c.DoNotValidate) |
|
|
|
{ |
|
|
|
await context.ValidateContentAsync(dataNew); |
|
|
|
await context.ValidateContentAsync(newData); |
|
|
|
} |
|
|
|
|
|
|
|
Update(c, dataNew); |
|
|
|
} |
|
|
|
Update(c, newData); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task DeleteCore(DeleteContent c) |
|
|
|
@ -361,29 +383,29 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
Raise(command, new ContentStatusChanged { Change = GetChange(command.Status) }); |
|
|
|
} |
|
|
|
|
|
|
|
private void CreateDraft(CreateContentDraft command, Status status) |
|
|
|
private void ChangeStatusScheduled(ChangeContentStatus command, Instant dueTime) |
|
|
|
{ |
|
|
|
Raise(command, new ContentDraftCreated { Status = status }); |
|
|
|
Raise(command, new ContentStatusScheduled { DueTime = dueTime }); |
|
|
|
} |
|
|
|
|
|
|
|
private void Delete(DeleteContent command) |
|
|
|
private void CancelChangeStatus(ChangeContentStatus command) |
|
|
|
{ |
|
|
|
Raise(command, new ContentDeleted()); |
|
|
|
Raise(command, new ContentSchedulingCancelled()); |
|
|
|
} |
|
|
|
|
|
|
|
private void DeleteDraft(DeleteContentDraft command) |
|
|
|
private void CreateDraft(CreateContentDraft command, Status status) |
|
|
|
{ |
|
|
|
Raise(command, new ContentDraftDeleted()); |
|
|
|
Raise(command, new ContentDraftCreated { Status = status }); |
|
|
|
} |
|
|
|
|
|
|
|
private void CancelChangeStatus(ChangeContentStatus command) |
|
|
|
private void Delete(DeleteContent command) |
|
|
|
{ |
|
|
|
Raise(command, new ContentSchedulingCancelled()); |
|
|
|
Raise(command, new ContentDeleted()); |
|
|
|
} |
|
|
|
|
|
|
|
private void ScheduleStatus(ChangeContentStatus command, Instant dueTime) |
|
|
|
private void DeleteDraft(DeleteContentDraft command) |
|
|
|
{ |
|
|
|
Raise(command, new ContentStatusScheduled { DueTime = dueTime }); |
|
|
|
Raise(command, new ContentDraftDeleted()); |
|
|
|
} |
|
|
|
|
|
|
|
private void Raise<T, TEvent>(T command, TEvent @event) where T : class where TEvent : AppEvent |
|
|
|
@ -406,10 +428,5 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject |
|
|
|
return StatusChange.Change; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private Task LoadContext(ContentCommand command, bool optimize) |
|
|
|
{ |
|
|
|
return context.LoadAsync(command.AppId, command.SchemaId, command, optimize); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|