mirror of https://github.com/Squidex/squidex.git
1 changed files with 113 additions and 0 deletions
@ -0,0 +1,113 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
using Squidex.Domain.Apps.Entities.Contents; |
||||
|
using Squidex.Domain.Apps.Entities.Contents.Commands; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Commands; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
|
||||
|
namespace Squidex.Extensions.Samples.Middleware |
||||
|
{ |
||||
|
public sealed class DoubleLinkedContentMiddleware : ICustomCommandMiddleware |
||||
|
{ |
||||
|
private readonly IContentLoader contentLoader; |
||||
|
|
||||
|
public DoubleLinkedContentMiddleware(IContentLoader contentLoader) |
||||
|
{ |
||||
|
this.contentLoader = contentLoader; |
||||
|
} |
||||
|
|
||||
|
public async Task HandleAsync(CommandContext context, NextDelegate next) |
||||
|
{ |
||||
|
await next(context); |
||||
|
|
||||
|
if (context.Command is UpdateContent update && context.IsCompleted && update.SchemaId.Name == "source") |
||||
|
{ |
||||
|
// After a change is made, the content is put to the command context.
|
||||
|
var content = context.Result<IContentEntity>(); |
||||
|
|
||||
|
var contentPrevious = |
||||
|
await contentLoader.GetAsync( |
||||
|
content.AppId.Id, |
||||
|
content.Id, |
||||
|
content.Version - 1); |
||||
|
|
||||
|
// The data might have been changed within the domain object. Therefore we do not use the data fro mthe command.
|
||||
|
var oldReferenceId = GetReference(contentPrevious?.Data); |
||||
|
var newReferenceId = GetReference(content.Data); |
||||
|
|
||||
|
// If nothing has been changed we can just stop here.
|
||||
|
if (newReferenceId == oldReferenceId) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (oldReferenceId != null) |
||||
|
{ |
||||
|
var oldReferenced = await contentLoader.GetAsync(content.AppId.Id, DomainId.Create(oldReferenceId)); |
||||
|
|
||||
|
if (oldReferenced != null) |
||||
|
{ |
||||
|
var data = oldReferenced.Data.Clone(); |
||||
|
|
||||
|
// Remove the reference from the old referenced content.
|
||||
|
data.Remove("referencing"); |
||||
|
|
||||
|
await UpdateReferencing(context, oldReferenced, data); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (newReferenceId != null) |
||||
|
{ |
||||
|
var newReferenced = await contentLoader.GetAsync(content.AppId.Id, DomainId.Create(newReferenceId)); |
||||
|
|
||||
|
if (newReferenced != null) |
||||
|
{ |
||||
|
var data = newReferenced.Data.Clone(); |
||||
|
|
||||
|
// Add the reference to the new referenced content.
|
||||
|
data["referencing"] = new ContentFieldData |
||||
|
{ |
||||
|
["iv"] = JsonValue.Array(content.Id) |
||||
|
}; |
||||
|
|
||||
|
await UpdateReferencing(context, newReferenced, data); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static async Task UpdateReferencing(CommandContext context, IContentEntity reference, ContentData data) |
||||
|
{ |
||||
|
await context.CommandBus.PublishAsync(new UpdateContent |
||||
|
{ |
||||
|
AppId = reference.AppId, |
||||
|
SchemaId = reference.SchemaId, |
||||
|
ContentId = reference.Id, |
||||
|
DoNotScript = true, |
||||
|
DoNotValidate = true, |
||||
|
Data = data, |
||||
|
// Also set the expected version, otherwise it will be overriden with the version from the request.
|
||||
|
ExpectedVersion = reference.Version |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private static string GetReference(ContentData data) |
||||
|
{ |
||||
|
if (data != null && data.TryGetValue("reference", out ContentFieldData fieldData)) |
||||
|
{ |
||||
|
return fieldData.Values.OfType<JsonArray>().SelectMany(x => x).SingleOrDefault()?.ToString(); |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue