Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

127 lines
4.4 KiB

// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Threading.Tasks;
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Contents.Guards
{
public static class GuardContent
{
public static void CanCreate(ISchemaEntity schema, CreateContent command)
{
Guard.NotNull(command, nameof(command));
Validate.It(() => "Cannot created content.", e =>
{
ValidateData(command, e);
});
if (schema.SchemaDef.IsSingleton && command.ContentId != schema.Id)
{
throw new DomainException("Singleton content cannot be created.");
}
}
public static async Task CanUpdate(IContentEntity content, IContentWorkflow contentWorkflow, UpdateContent command)
{
Guard.NotNull(command, nameof(command));
Validate.It(() => "Cannot update content.", e =>
{
ValidateData(command, e);
});
await ValidateCanUpdate(content, contentWorkflow);
}
public static async Task CanPatch(IContentEntity content, IContentWorkflow contentWorkflow, PatchContent command)
{
Guard.NotNull(command, nameof(command));
Validate.It(() => "Cannot patch content.", e =>
{
ValidateData(command, e);
});
await ValidateCanUpdate(content, contentWorkflow);
}
public static void CanDiscardChanges(bool isPending, DiscardChanges command)
{
Guard.NotNull(command, nameof(command));
if (!isPending)
{
throw new DomainException("The content has no pending changes.");
}
}
public static Task CanChangeStatus(ISchemaEntity schema, IContentEntity content, IContentWorkflow contentWorkflow, ChangeContentStatus command)
{
Guard.NotNull(command, nameof(command));
if (schema.SchemaDef.IsSingleton && command.Status != Status.Published)
{
throw new DomainException("Singleton content cannot be changed.");
}
return Validate.It(() => "Cannot change status.", async e =>
{
if (!await contentWorkflow.CanMoveToAsync(content, command.Status))
{
if (content.Status == command.Status && content.Status == Status.Published)
{
if (!content.IsPending)
{
e("Content has no changes to publish.", nameof(command.Status));
}
}
else
{
e($"Cannot change status from {content.Status} to {command.Status}.", nameof(command.Status));
}
}
if (command.DueTime.HasValue && command.DueTime.Value < SystemClock.Instance.GetCurrentInstant())
{
e("Due time must be in the future.", nameof(command.DueTime));
}
});
}
public static void CanDelete(ISchemaEntity schema, DeleteContent command)
{
Guard.NotNull(command, nameof(command));
if (schema.SchemaDef.IsSingleton)
{
throw new DomainException("Singleton content cannot be deleted.");
}
}
private static void ValidateData(ContentDataCommand command, AddValidation e)
{
if (command.Data == null)
{
e(Not.Defined("Data"), nameof(command.Data));
}
}
private static async Task ValidateCanUpdate(IContentEntity content, IContentWorkflow contentWorkflow)
{
if (!await contentWorkflow.CanUpdateAsync(content))
{
throw new DomainException($"The workflow does not allow updates at status {content.Status}");
}
}
}
}