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