Run the same cleanup with scaffolding content as when copying. (#15541)

* Run the same cleanup with scaffolding content as when copying.

- Added a new ContentScaffoldedNotification
- Published the notification when a new scaffold has been created from a blueprint (content template)
- Linked up the ComplextPEContent handler to do the same cleanup for the new notification as when copying.
- registered handlers to the event for blocklist, blockgrid and nested content

* PR pattern matching suggestion

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
(cherry picked from commit dff90c6ec0)
This commit is contained in:
Sven Geusens
2024-01-10 12:22:36 +01:00
committed by Zeegaan
parent f381e8391c
commit 9da46462f7
5 changed files with 82 additions and 8 deletions

View File

@@ -0,0 +1,18 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Core.Notifications;
/// <summary>
/// Notification that is send out when a Content item has been scaffolded from an original item and basic cleaning has been performed
/// </summary>
public sealed class ContentScaffoldedNotification : ScaffoldedNotification<IContent>
{
public ContentScaffoldedNotification(IContent original, IContent scaffold, int parentId, EventMessages messages)
: base(original, scaffold, parentId, messages)
{
}
}

View File

@@ -0,0 +1,23 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
namespace Umbraco.Cms.Core.Notifications;
public abstract class ScaffoldedNotification<T> : CancelableObjectNotification<T>
where T : class
{
protected ScaffoldedNotification(T original, T scaffold, int parentId, EventMessages messages)
: base(original, messages)
{
Scaffold = scaffold;
ParentId = parentId;
}
public T Original => Target;
public T Scaffold { get; }
public int ParentId { get; }
}

View File

@@ -357,10 +357,13 @@ public static partial class UmbracoBuilderExtensions
builder
.AddNotificationHandler<ContentSavingNotification, BlockListPropertyNotificationHandler>()
.AddNotificationHandler<ContentCopyingNotification, BlockListPropertyNotificationHandler>()
.AddNotificationHandler<ContentScaffoldedNotification, BlockListPropertyNotificationHandler>()
.AddNotificationHandler<ContentSavingNotification, BlockGridPropertyNotificationHandler>()
.AddNotificationHandler<ContentCopyingNotification, BlockGridPropertyNotificationHandler>()
.AddNotificationHandler<ContentScaffoldedNotification, BlockGridPropertyNotificationHandler>()
.AddNotificationHandler<ContentSavingNotification, NestedContentPropertyHandler>()
.AddNotificationHandler<ContentCopyingNotification, NestedContentPropertyHandler>()
.AddNotificationHandler<ContentScaffoldedNotification, NestedContentPropertyHandler>()
.AddNotificationHandler<ContentCopiedNotification, FileUploadPropertyEditor>()
.AddNotificationHandler<ContentDeletedNotification, FileUploadPropertyEditor>()
.AddNotificationHandler<MediaDeletedNotification, FileUploadPropertyEditor>()

View File

@@ -10,9 +10,16 @@ using Umbraco.Extensions;
namespace Umbraco.Cms.Core.PropertyEditors;
/// <summary>
/// Handles nested Udi keys when
/// - saving: Empty keys get generated
/// - copy: keys get replaced by new ones while keeping references intact
/// - scaffolding: keys get replaced by new ones while keeping references intact
/// </summary>
public abstract class ComplexPropertyEditorContentNotificationHandler :
INotificationHandler<ContentSavingNotification>,
INotificationHandler<ContentCopyingNotification>
INotificationHandler<ContentCopyingNotification>,
INotificationHandler<ContentScaffoldedNotification>
{
protected abstract string EditorAlias { get; }
@@ -31,6 +38,12 @@ public abstract class ComplexPropertyEditorContentNotificationHandler :
}
}
public void Handle(ContentScaffoldedNotification notification)
{
IEnumerable<IProperty> props = notification.Scaffold.GetPropertiesByEditor(EditorAlias);
UpdatePropertyValues(props, false);
}
protected abstract string FormatPropertyValue(string rawJson, bool onlyMissingKeys);
private void UpdatePropertyValues(IEnumerable<IProperty> props, bool onlyMissingKeys)

View File

@@ -19,6 +19,7 @@ using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Editors;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Models.Validation;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Persistence.Querying;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Routing;
@@ -683,17 +684,33 @@ public class ContentController : ContentControllerBase
[OutgoingEditorModelEvent]
public ActionResult<ContentItemDisplay?> GetEmptyBlueprint(int blueprintId, int parentId)
{
IContent? blueprint = _contentService.GetBlueprintById(blueprintId);
if (blueprint == null)
IContent? scaffold;
using (ICoreScope scope = _scopeProvider.CreateCoreScope())
{
return NotFound();
IContent? blueprint = _contentService.GetBlueprintById(blueprintId);
if (blueprint is null)
{
return NotFound();
}
scaffold = (IContent)blueprint.DeepClone();
scaffold.Id = 0;
scaffold.Name = string.Empty;
scaffold.ParentId = parentId;
var scaffoldedNotification = new ContentScaffoldedNotification(blueprint, scaffold, parentId, new EventMessages());
if (scope.Notifications.PublishCancelable(scaffoldedNotification))
{
scope.Complete();
return Problem("Scaffolding was cancelled");
}
scope.Complete();
}
blueprint.Id = 0;
blueprint.Name = string.Empty;
blueprint.ParentId = parentId;
ContentItemDisplay? mapped = _umbracoMapper.Map<ContentItemDisplay>(blueprint);
ContentItemDisplay? mapped = _umbracoMapper.Map<ContentItemDisplay>(scaffold);
if (mapped is not null)
{