V14: Create seperate Create and Update in ContentTypeServiceBase (#16714)
* Create seperate Create and Update in ContentTypeServiceBase * Fix up notification for update --------- Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -86,6 +86,18 @@ public abstract class DocumentTypeControllerBase : ManagementApiControllerBase
|
||||
.WithTitle("Operation not permitted")
|
||||
.WithDetail("The attempted operation was not permitted, likely due to a permission/configuration mismatch with the operation.")
|
||||
.Build()),
|
||||
ContentTypeOperationStatus.CancelledByNotification => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Cancelled by notification")
|
||||
.WithDetail("The attempted operation was cancelled by a notification.")
|
||||
.Build()),
|
||||
ContentTypeOperationStatus.NameCannotBeEmpty => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Name cannot be empty")
|
||||
.WithDetail("The name of the content type cannot be empty")
|
||||
.Build()),
|
||||
ContentTypeOperationStatus.NameTooLong => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Name was too long")
|
||||
.WithDetail("Name cannot be more than 255 characters in length.")
|
||||
.Build()),
|
||||
_ => new ObjectResult("Unknown content type operation status") { StatusCode = StatusCodes.Status500InternalServerError },
|
||||
});
|
||||
|
||||
|
||||
@@ -40,7 +40,12 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase<
|
||||
UpdateTemplates(contentType, model);
|
||||
|
||||
// save content type
|
||||
await SaveAsync(contentType, userKey);
|
||||
Attempt<ContentTypeOperationStatus> creationAttempt = await _contentTypeService.CreateAsync(contentType, userKey);
|
||||
|
||||
if(creationAttempt.Success is false)
|
||||
{
|
||||
return Attempt.FailWithStatus<IContentType?, ContentTypeOperationStatus>(creationAttempt.Result, contentType);
|
||||
}
|
||||
|
||||
return Attempt.SucceedWithStatus<IContentType?, ContentTypeOperationStatus>(ContentTypeOperationStatus.Success, contentType);
|
||||
}
|
||||
@@ -58,9 +63,11 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase<
|
||||
UpdateHistoryCleanup(contentType, model);
|
||||
UpdateTemplates(contentType, model);
|
||||
|
||||
await SaveAsync(contentType, userKey);
|
||||
Attempt<ContentTypeOperationStatus> attempt = await _contentTypeService.UpdateAsync(contentType, userKey);
|
||||
|
||||
return Attempt.SucceedWithStatus<IContentType?, ContentTypeOperationStatus>(ContentTypeOperationStatus.Success, contentType);
|
||||
return attempt.Success
|
||||
? Attempt.SucceedWithStatus<IContentType?, ContentTypeOperationStatus>(ContentTypeOperationStatus.Success, contentType)
|
||||
: Attempt.FailWithStatus<IContentType?, ContentTypeOperationStatus>(attempt.Result, null);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ContentTypeAvailableCompositionsResult>> GetAvailableCompositionsAsync(
|
||||
@@ -93,9 +100,6 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase<
|
||||
contentType.SetDefaultTemplate(allowedTemplates.FirstOrDefault(t => t.Key == model.DefaultTemplateKey));
|
||||
}
|
||||
|
||||
private async Task SaveAsync(IContentType contentType, Guid userKey)
|
||||
=> await _contentTypeService.SaveAsync(contentType, userKey);
|
||||
|
||||
protected override IContentType CreateContentType(IShortStringHelper shortStringHelper, int parentId)
|
||||
=> new ContentType(shortStringHelper, parentId);
|
||||
|
||||
|
||||
@@ -603,6 +603,75 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Attempt<ContentTypeOperationStatus>> CreateAsync(TItem item, Guid performingUserKey) => await InternalSaveAsync(item, performingUserKey);
|
||||
|
||||
public async Task<Attempt<ContentTypeOperationStatus>> UpdateAsync(TItem item, Guid performingUserKey) => await InternalSaveAsync(item, performingUserKey);
|
||||
|
||||
private async Task<Attempt<ContentTypeOperationStatus>> InternalSaveAsync(TItem item, Guid performingUserKey)
|
||||
{
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope();
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
|
||||
Attempt<ContentTypeOperationStatus> validationAttempt = ValidateCommon(item);
|
||||
if (validationAttempt.Success is false)
|
||||
{
|
||||
return Attempt.Fail(validationAttempt.Result);
|
||||
}
|
||||
|
||||
SavingNotification<TItem> savingNotification = GetSavingNotification(item, eventMessages);
|
||||
if (await scope.Notifications.PublishCancelableAsync(savingNotification))
|
||||
{
|
||||
scope.Complete();
|
||||
return Attempt.Fail(ContentTypeOperationStatus.CancelledByNotification);
|
||||
}
|
||||
|
||||
scope.WriteLock(WriteLockIds);
|
||||
|
||||
// validate the DAG transform, within the lock
|
||||
ValidateLocked(item); // throws if invalid
|
||||
|
||||
int userId = await _userIdKeyResolver.GetAsync(performingUserKey);
|
||||
item.CreatorId = userId;
|
||||
if (item.Description == string.Empty)
|
||||
{
|
||||
item.Description = null;
|
||||
}
|
||||
|
||||
Repository.Save(item); // also updates content/media/member items
|
||||
|
||||
// figure out impacted content types
|
||||
ContentTypeChange<TItem>[] changes = ComposeContentTypeChanges(item).ToArray();
|
||||
|
||||
// Publish this in scope, see comment at GetContentTypeRefreshedNotification for more info.
|
||||
await _eventAggregator.PublishAsync(GetContentTypeRefreshedNotification(changes, eventMessages));
|
||||
|
||||
scope.Notifications.Publish(GetContentTypeChangedNotification(changes, eventMessages));
|
||||
|
||||
SavedNotification<TItem> savedNotification = GetSavedNotification(item, eventMessages);
|
||||
savedNotification.WithStateFrom(savingNotification);
|
||||
scope.Notifications.Publish(savedNotification);
|
||||
|
||||
Audit(AuditType.Save, userId, item.Id);
|
||||
scope.Complete();
|
||||
|
||||
return Attempt.Succeed(ContentTypeOperationStatus.Success);
|
||||
}
|
||||
|
||||
private Attempt<ContentTypeOperationStatus> ValidateCommon(TItem item)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.Name))
|
||||
{
|
||||
return Attempt.Fail(ContentTypeOperationStatus.NameCannotBeEmpty);
|
||||
}
|
||||
|
||||
if (item.Name.Length > 255)
|
||||
{
|
||||
return Attempt.Fail(ContentTypeOperationStatus.NameTooLong);
|
||||
}
|
||||
|
||||
return Attempt.Succeed(ContentTypeOperationStatus.Success);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delete
|
||||
|
||||
@@ -67,16 +67,31 @@ public interface IContentTypeBaseService<TItem> : IContentTypeBaseService, IServ
|
||||
|
||||
bool HasChildren(Guid id);
|
||||
|
||||
[Obsolete("Please use the respective Create or Update instead")]
|
||||
void Save(TItem? item, int userId = Constants.Security.SuperUserId);
|
||||
|
||||
[Obsolete("Please use the respective Create or Update instead")]
|
||||
Task SaveAsync(TItem item, Guid performingUserKey)
|
||||
{
|
||||
Save(item);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Obsolete("Please use the respective Create or Update instead")]
|
||||
void Save(IEnumerable<TItem> items, int userId = Constants.Security.SuperUserId);
|
||||
|
||||
Task<Attempt<ContentTypeOperationStatus>> CreateAsync(TItem item, Guid performingUserKey)
|
||||
{
|
||||
Save(item);
|
||||
return Task.FromResult(Attempt.Succeed(ContentTypeOperationStatus.Success));
|
||||
}
|
||||
|
||||
Task<Attempt<ContentTypeOperationStatus>> UpdateAsync(TItem item, Guid performingUserKey)
|
||||
{
|
||||
Save(item);
|
||||
return Task.FromResult(Attempt.Succeed(ContentTypeOperationStatus.Success));
|
||||
}
|
||||
|
||||
void Delete(TItem item, int userId = Constants.Security.SuperUserId);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -5,6 +5,8 @@ public enum ContentTypeOperationStatus
|
||||
Success,
|
||||
DuplicateAlias,
|
||||
InvalidAlias,
|
||||
NameCannotBeEmpty,
|
||||
NameTooLong,
|
||||
InvalidPropertyTypeAlias,
|
||||
PropertyTypeAliasCannotEqualContentTypeAlias,
|
||||
DuplicatePropertyTypeAlias,
|
||||
@@ -17,5 +19,6 @@ public enum ContentTypeOperationStatus
|
||||
MissingContainer,
|
||||
DuplicateContainer,
|
||||
NotFound,
|
||||
NotAllowed
|
||||
NotAllowed,
|
||||
CancelledByNotification,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user