Merge pull request #10080 from umbraco/netcore/feature/fileservice-events

Netcore: Migrate fileservice events
This commit is contained in:
Mole
2021-04-09 10:45:21 +02:00
committed by GitHub
26 changed files with 542 additions and 224 deletions

View File

@@ -0,0 +1,14 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
namespace Umbraco.Cms.Core.Events
{
public abstract class CreatedNotification<T> : ObjectNotification<T> where T : class
{
protected CreatedNotification(T target, EventMessages messages) : base(target, messages)
{
}
public T CreatedEntity => Target;
}
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
namespace Umbraco.Cms.Core.Events
{
public abstract class CreatingNotification<T> : CancelableObjectNotification<T> where T : class
{
protected CreatingNotification(T target, EventMessages messages) : base(target, messages)
{
}
public T CreatedEntity => Target;
}
}

View File

@@ -34,6 +34,8 @@ namespace Umbraco.Cms.Core.Cache
INotificationHandler<UserGroupDeletedNotification>,
INotificationHandler<MemberGroupDeletedNotification>,
INotificationHandler<MemberGroupSavedNotification>,
INotificationHandler<TemplateDeletedNotification>,
INotificationHandler<TemplateSavedNotification>,
INotificationHandler<DataTypeDeletedNotification>,
INotificationHandler<DataTypeSavedNotification>,
INotificationHandler<RelationTypeDeletedNotification>,
@@ -72,12 +74,6 @@ namespace Umbraco.Cms.Core.Cache
_logger.LogInformation("Initializing Umbraco internal event handlers for cache refreshing.");
// bind to stylesheet events
Bind(() => FileService.SavedStylesheet += FileService_SavedStylesheet,
() => FileService.SavedStylesheet -= FileService_SavedStylesheet);
Bind(() => FileService.DeletedStylesheet += FileService_DeletedStylesheet,
() => FileService.DeletedStylesheet -= FileService_DeletedStylesheet);
// bind to content type events
Bind(() => ContentTypeService.Changed += ContentTypeService_Changed,
() => ContentTypeService.Changed -= ContentTypeService_Changed);
@@ -86,12 +82,6 @@ namespace Umbraco.Cms.Core.Cache
Bind(() => MemberTypeService.Changed += MemberTypeService_Changed,
() => MemberTypeService.Changed -= MemberTypeService_Changed);
// bind to template events
Bind(() => FileService.SavedTemplate += FileService_SavedTemplate,
() => FileService.SavedTemplate -= FileService_SavedTemplate);
Bind(() => FileService.DeletedTemplate += FileService_DeletedTemplate,
() => FileService.DeletedTemplate -= FileService_DeletedTemplate);
// bind to media events - handles all media changes
Bind(() => MediaService.TreeChanged += MediaService_TreeChanged,
() => MediaService.TreeChanged -= MediaService_TreeChanged);
@@ -309,29 +299,27 @@ namespace Umbraco.Cms.Core.Cache
/// <summary>
/// Removes cache for template
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FileService_DeletedTemplate(IFileService sender, DeleteEventArgs<ITemplate> e)
/// <param name="notification"></param>
public void Handle(TemplateDeletedNotification notification)
{
foreach (var entity in e.DeletedEntities)
foreach (ITemplate entity in notification.DeletedEntities)
{
_distributedCache.RemoveTemplateCache(entity.Id);
}
}
/// <summary>
/// Refresh cache for template
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FileService_SavedTemplate(IFileService sender, SaveEventArgs<ITemplate> e)
/// <param name="notification"></param>
public void Handle(TemplateSavedNotification notification)
{
foreach (var entity in e.SavedEntities)
foreach (ITemplate entity in notification.SavedEntities)
{
_distributedCache.RefreshTemplateCache(entity.Id);
}
}
// TODO: our weird events handling wants this for now
private void FileService_DeletedStylesheet(IFileService sender, DeleteEventArgs<IStylesheet> e) { }
private void FileService_SavedStylesheet(IFileService sender, SaveEventArgs<IStylesheet> e) { }
#endregion
#region MacroService

View File

@@ -83,6 +83,8 @@ namespace Umbraco.Cms.Core.Compose
.AddNotificationHandler<MemberGroupSavedNotification, DistributedCacheBinder>()
.AddNotificationHandler<DataTypeDeletedNotification, DistributedCacheBinder>()
.AddNotificationHandler<DataTypeSavedNotification, DistributedCacheBinder>()
.AddNotificationHandler<TemplateDeletedNotification, DistributedCacheBinder>()
.AddNotificationHandler<TemplateSavedNotification, DistributedCacheBinder>()
.AddNotificationHandler<RelationTypeDeletedNotification, DistributedCacheBinder>()
.AddNotificationHandler<RelationTypeSavedNotification, DistributedCacheBinder>()
.AddNotificationHandler<DomainDeletedNotification, DistributedCacheBinder>()

View File

@@ -12,6 +12,7 @@ using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Infrastructure.Services.Notifications;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Services.Implement
@@ -74,10 +75,11 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <inheritdoc />
public void SaveStylesheet(IStylesheet stylesheet, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var saveEventArgs = new SaveEventArgs<IStylesheet>(stylesheet);
if (scope.Events.DispatchCancelable(SavingStylesheet, this, saveEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new StylesheetSavingNotification(stylesheet, eventMessages);
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -85,8 +87,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_stylesheetRepository.Save(stylesheet);
saveEventArgs.CanCancel = false;
scope.Events.Dispatch(SavedStylesheet, this, saveEventArgs);
scope.Notifications.Publish(new StylesheetSavedNotification(stylesheet, eventMessages).WithStateFrom(savingNotification));
Audit(AuditType.Save, userId, -1, "Stylesheet");
scope.Complete();
@@ -96,25 +97,26 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <inheritdoc />
public void DeleteStylesheet(string path, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var stylesheet = _stylesheetRepository.Get(path);
IStylesheet stylesheet = _stylesheetRepository.Get(path);
if (stylesheet == null)
{
scope.Complete();
return;
}
var deleteEventArgs = new DeleteEventArgs<IStylesheet>(stylesheet);
if (scope.Events.DispatchCancelable(DeletingStylesheet, this, deleteEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var deletingNotification = new StylesheetDeletingNotification(stylesheet, eventMessages);
if (scope.Notifications.PublishCancelable(deletingNotification))
{
scope.Complete();
return; // causes rollback // causes rollback
return; // causes rollback
}
_stylesheetRepository.Delete(stylesheet);
deleteEventArgs.CanCancel = false;
scope.Events.Dispatch(DeletedStylesheet, this, deleteEventArgs);
scope.Notifications.Publish(new StylesheetDeletedNotification(stylesheet, eventMessages).WithStateFrom(deletingNotification));
Audit(AuditType.Delete, userId, -1, "Stylesheet");
scope.Complete();
@@ -198,18 +200,18 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <inheritdoc />
public void SaveScript(IScript script, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var saveEventArgs = new SaveEventArgs<IScript>(script);
if (scope.Events.DispatchCancelable(SavingScript, this, saveEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new ScriptSavingNotification(script, eventMessages);
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
}
_scriptRepository.Save(script);
saveEventArgs.CanCancel = false;
scope.Events.Dispatch(SavedScript, this, saveEventArgs);
scope.Notifications.Publish(new ScriptSavedNotification(script, eventMessages).WithStateFrom(savingNotification));
Audit(AuditType.Save, userId, -1, "Script");
scope.Complete();
@@ -219,25 +221,25 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <inheritdoc />
public void DeleteScript(string path, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var script = _scriptRepository.Get(path);
IScript script = _scriptRepository.Get(path);
if (script == null)
{
scope.Complete();
return;
}
var deleteEventArgs = new DeleteEventArgs<IScript>(script);
if (scope.Events.DispatchCancelable(DeletingScript, this, deleteEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var deletingNotification = new ScriptDeletingNotification(script, eventMessages);
if (scope.Notifications.PublishCancelable(deletingNotification))
{
scope.Complete();
return;
}
_scriptRepository.Delete(script);
deleteEventArgs.CanCancel = false;
scope.Events.Dispatch(DeletedScript, this, deleteEventArgs);
scope.Notifications.Publish(new ScriptDeletedNotification(script, eventMessages).WithStateFrom(deletingNotification));
Audit(AuditType.Delete, userId, -1, "Script");
scope.Complete();
@@ -318,16 +320,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// This fixes: http://issues.umbraco.org/issue/U4-7953
contentTypeName);
var evtMsgs = EventMessagesFactory.Get();
// TODO: This isn't pretty because we we're required to maintain backwards compatibility so we could not change
// the event args here. The other option is to create a different event with different event
// args specifically for this method... which also isn't pretty. So fix this in v8!
var additionalData = new Dictionary<string, object>
{
{ "CreateTemplateForContentType", true },
{ "ContentTypeAlias", contentTypeAlias },
};
EventMessages eventMessages = EventMessagesFactory.Get();
if (contentTypeAlias != null && contentTypeAlias.Length > 255)
{
@@ -342,27 +335,23 @@ namespace Umbraco.Cms.Core.Services.Implement
template.Content = content;
}
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var saveEventArgs = new SaveEventArgs<ITemplate>(template, true, evtMsgs, additionalData);
if (scope.Events.DispatchCancelable(SavingTemplate, this, saveEventArgs))
var savingEvent = new TemplateSavingNotification(template, eventMessages, true, contentTypeAlias);
if (scope.Notifications.PublishCancelable(savingEvent))
{
scope.Complete();
return OperationResult.Attempt.Fail<OperationResultType, ITemplate>(OperationResultType.FailedCancelledByEvent, evtMsgs, template);
return OperationResult.Attempt.Fail<OperationResultType, ITemplate>(OperationResultType.FailedCancelledByEvent, eventMessages, template);
}
_templateRepository.Save(template);
saveEventArgs.CanCancel = false;
scope.Events.Dispatch(SavedTemplate, this, saveEventArgs);
scope.Notifications.Publish(new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingEvent));
Audit(AuditType.Save, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template));
scope.Complete();
}
return OperationResult.Attempt.Succeed<OperationResultType, ITemplate>(OperationResultType.Success, evtMsgs, template);
return OperationResult.Attempt.Succeed<OperationResultType, ITemplate>(OperationResultType.Success, eventMessages, template);
}
/// <summary>
@@ -536,9 +525,11 @@ namespace Umbraco.Cms.Core.Services.Implement
}
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
if (scope.Events.DispatchCancelable(SavingTemplate, this, new SaveEventArgs<ITemplate>(template)))
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new TemplateSavingNotification(template, eventMessages);
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -546,7 +537,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_templateRepository.Save(template);
scope.Events.Dispatch(SavedTemplate, this, new SaveEventArgs<ITemplate>(template, false));
scope.Notifications.Publish(new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingNotification));
Audit(AuditType.Save, userId, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
@@ -560,19 +551,23 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <param name="userId">Optional id of the user</param>
public void SaveTemplate(IEnumerable<ITemplate> templates, int userId = Cms.Core.Constants.Security.SuperUserId)
{
var templatesA = templates.ToArray();
using (var scope = ScopeProvider.CreateScope())
ITemplate[] templatesA = templates.ToArray();
using (IScope scope = ScopeProvider.CreateScope())
{
if (scope.Events.DispatchCancelable(SavingTemplate, this, new SaveEventArgs<ITemplate>(templatesA)))
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new TemplateSavingNotification(templatesA, eventMessages);
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
}
foreach (var template in templatesA)
foreach (ITemplate template in templatesA)
{
_templateRepository.Save(template);
}
scope.Events.Dispatch(SavedTemplate, this, new SaveEventArgs<ITemplate>(templatesA, false));
scope.Notifications.Publish(new TemplateSavedNotification(templatesA, eventMessages).WithStateFrom(savingNotification));
Audit(AuditType.Save, userId, -1, UmbracoObjectTypes.Template.GetName());
scope.Complete();
@@ -586,17 +581,18 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <param name="userId"></param>
public void DeleteTemplate(string alias, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var template = _templateRepository.Get(alias);
ITemplate template = _templateRepository.Get(alias);
if (template == null)
{
scope.Complete();
return;
}
var args = new DeleteEventArgs<ITemplate>(template);
if (scope.Events.DispatchCancelable(DeletingTemplate, this, args))
EventMessages eventMessages = EventMessagesFactory.Get();
var deletingNotification = new TemplateDeletingNotification(template, eventMessages);
if (scope.Notifications.PublishCancelable(deletingNotification))
{
scope.Complete();
return;
@@ -604,8 +600,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_templateRepository.Delete(template);
args.CanCancel = false;
scope.Events.Dispatch(DeletedTemplate, this, args);
scope.Notifications.Publish(new TemplateDeletedNotification(template, eventMessages).WithStateFrom(deletingNotification));
Audit(AuditType.Delete, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template));
scope.Complete();
@@ -757,7 +752,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (snippetName.IsNullOrWhiteSpace() == false)
{
//create the file
var snippetPathAttempt = TryGetSnippetPath(snippetName);
Attempt<string> snippetPathAttempt = TryGetSnippetPath(snippetName);
if (snippetPathAttempt.Success == false)
{
throw new InvalidOperationException("Could not load snippet with name " + snippetName);
@@ -780,21 +775,25 @@ namespace Umbraco.Cms.Core.Services.Implement
}
}
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var newEventArgs = new NewEventArgs<IPartialView>(partialView, true, partialView.Alias, -1);
if (scope.Events.DispatchCancelable(CreatingPartialView, this, newEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var creatingNotification = new PartialViewCreatingNotification(partialView, eventMessages);
if (scope.Notifications.PublishCancelable(creatingNotification))
{
scope.Complete();
return Attempt<IPartialView>.Fail();
}
var repository = GetPartialViewRepository(partialViewType);
if (partialViewContent != null) partialView.Content = partialViewContent;
IPartialViewRepository repository = GetPartialViewRepository(partialViewType);
if (partialViewContent != null)
{
partialView.Content = partialViewContent;
}
repository.Save(partialView);
newEventArgs.CanCancel = false;
scope.Events.Dispatch(CreatedPartialView, this, newEventArgs);
scope.Notifications.Publish(new PartialViewCreatedNotification(partialView, eventMessages).WithStateFrom(creatingNotification));
Audit(AuditType.Save, userId, -1, partialViewType.ToString());
@@ -816,26 +815,26 @@ namespace Umbraco.Cms.Core.Services.Implement
private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var repository = GetPartialViewRepository(partialViewType);
var partialView = repository.Get(path);
IPartialViewRepository repository = GetPartialViewRepository(partialViewType);
IPartialView partialView = repository.Get(path);
if (partialView == null)
{
scope.Complete();
return true;
}
var deleteEventArgs = new DeleteEventArgs<IPartialView>(partialView);
if (scope.Events.DispatchCancelable(DeletingPartialView, this, deleteEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var deletingNotification = new PartialViewDeletingNotification(partialView, eventMessages);
if (scope.Notifications.PublishCancelable(deletingNotification))
{
scope.Complete();
return false;
}
repository.Delete(partialView);
deleteEventArgs.CanCancel = false;
scope.Events.Dispatch(DeletedPartialView, this, deleteEventArgs);
scope.Notifications.Publish(new PartialViewDeletedNotification(partialView, eventMessages).WithStateFrom(deletingNotification));
Audit(AuditType.Delete, userId, -1, partialViewType.ToString());
scope.Complete();
@@ -856,20 +855,21 @@ namespace Umbraco.Cms.Core.Services.Implement
private Attempt<IPartialView> SavePartialView(IPartialView partialView, PartialViewType partialViewType, int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
using (IScope scope = ScopeProvider.CreateScope())
{
var saveEventArgs = new SaveEventArgs<IPartialView>(partialView);
if (scope.Events.DispatchCancelable(SavingPartialView, this, saveEventArgs))
EventMessages eventMessages = EventMessagesFactory.Get();
var savingNotification = new PartialViewSavingNotification(partialView, eventMessages);
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return Attempt<IPartialView>.Fail();
}
var repository = GetPartialViewRepository(partialViewType);
IPartialViewRepository repository = GetPartialViewRepository(partialViewType);
repository.Save(partialView);
saveEventArgs.CanCancel = false;
Audit(AuditType.Save, userId, -1, partialViewType.ToString());
scope.Events.Dispatch(SavedPartialView, this, saveEventArgs);
scope.Notifications.Publish(new PartialViewSavedNotification(partialView, eventMessages).WithStateFrom(savingNotification));
scope.Complete();
}
@@ -1060,99 +1060,5 @@ namespace Umbraco.Cms.Core.Services.Implement
}
// TODO: Method to change name and/or alias of view template
#region Event Handlers
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<ITemplate>> DeletingTemplate;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<ITemplate>> DeletedTemplate;
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<IScript>> DeletingScript;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<IScript>> DeletedScript;
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<IStylesheet>> DeletingStylesheet;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<IStylesheet>> DeletedStylesheet;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<ITemplate>> SavingTemplate;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<ITemplate>> SavedTemplate;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<IScript>> SavingScript;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<IScript>> SavedScript;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<IStylesheet>> SavingStylesheet;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<IStylesheet>> SavedStylesheet;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<IPartialView>> SavingPartialView;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IFileService, SaveEventArgs<IPartialView>> SavedPartialView;
/// <summary>
/// Occurs before Create
/// </summary>
public static event TypedEventHandler<IFileService, NewEventArgs<IPartialView>> CreatingPartialView;
/// <summary>
/// Occurs after Create
/// </summary>
public static event TypedEventHandler<IFileService, NewEventArgs<IPartialView>> CreatedPartialView;
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<IPartialView>> DeletingPartialView;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IFileService, DeleteEventArgs<IPartialView>> DeletedPartialView;
#endregion
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class PartialViewCreatedNotification : CreatedNotification<IPartialView>
{
public PartialViewCreatedNotification(IPartialView target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class PartialViewCreatingNotification : CreatingNotification<IPartialView>
{
public PartialViewCreatingNotification(IPartialView target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class PartialViewDeletedNotification : DeletedNotification<IPartialView>
{
public PartialViewDeletedNotification(IPartialView target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class PartialViewDeletingNotification : DeletingNotification<IPartialView>
{
public PartialViewDeletingNotification(IPartialView target, EventMessages messages) : base(target, messages)
{
}
public PartialViewDeletingNotification(IEnumerable<IPartialView> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class PartialViewSavedNotification : SavedNotification<IPartialView>
{
public PartialViewSavedNotification(IPartialView target, EventMessages messages) : base(target, messages)
{
}
public PartialViewSavedNotification(IEnumerable<IPartialView> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class PartialViewSavingNotification : SavingNotification<IPartialView>
{
public PartialViewSavingNotification(IPartialView target, EventMessages messages) : base(target, messages)
{
}
public PartialViewSavingNotification(IEnumerable<IPartialView> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class ScriptDeletedNotification : DeletedNotification<IScript>
{
public ScriptDeletedNotification(IScript target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class ScriptDeletingNotification : DeletingNotification<IScript>
{
public ScriptDeletingNotification(IScript target, EventMessages messages) : base(target, messages)
{
}
public ScriptDeletingNotification(IEnumerable<IScript> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class ScriptSavedNotification : SavedNotification<IScript>
{
public ScriptSavedNotification(IScript target, EventMessages messages) : base(target, messages)
{
}
public ScriptSavedNotification(IEnumerable<IScript> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class ScriptSavingNotification : SavingNotification<IScript>
{
public ScriptSavingNotification(IScript target, EventMessages messages) : base(target, messages)
{
}
public ScriptSavingNotification(IEnumerable<IScript> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class StylesheetDeletedNotification : DeletedNotification<IStylesheet>
{
public StylesheetDeletedNotification(IStylesheet target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class StylesheetDeletingNotification : DeletingNotification<IStylesheet>
{
public StylesheetDeletingNotification(IStylesheet target, EventMessages messages) : base(target, messages)
{
}
public StylesheetDeletingNotification(IEnumerable<IStylesheet> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class StylesheetSavedNotification : SavedNotification<IStylesheet>
{
public StylesheetSavedNotification(IStylesheet target, EventMessages messages) : base(target, messages)
{
}
public StylesheetSavedNotification(IEnumerable<IStylesheet> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class StylesheetSavingNotification : SavingNotification<IStylesheet>
{
public StylesheetSavingNotification(IStylesheet target, EventMessages messages) : base(target, messages)
{
}
public StylesheetSavingNotification(IEnumerable<IStylesheet> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class TemplateDeletedNotification : DeletedNotification<ITemplate>
{
public TemplateDeletedNotification(ITemplate target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class TemplateDeletingNotification : DeletingNotification<ITemplate>
{
public TemplateDeletingNotification(ITemplate target, EventMessages messages) : base(target, messages)
{
}
public TemplateDeletingNotification(IEnumerable<ITemplate> target, EventMessages messages) : base(target, messages)
{
}
}
}

View File

@@ -0,0 +1,49 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class TemplateSavedNotification : SavedNotification<ITemplate>
{
private const string s_templateForContentTypeKey = "CreateTemplateForContentType";
private const string s_contentTypeAliasKey = "ContentTypeAlias";
public TemplateSavedNotification(ITemplate target, EventMessages messages) : base(target, messages)
{
}
public TemplateSavedNotification(IEnumerable<ITemplate> target, EventMessages messages) : base(target, messages)
{
}
public bool CreateTemplateForContentType
{
get
{
State.TryGetValue(s_templateForContentTypeKey, out var result);
if (result is not bool createTemplate)
{
return false;
}
return createTemplate;
}
set => State[s_templateForContentTypeKey] = value;
}
public string ContentTypeAlias
{
get
{
State.TryGetValue(s_contentTypeAliasKey, out var result);
return result as string;
}
set => State[s_contentTypeAliasKey] = value;
}
}
}

View File

@@ -0,0 +1,64 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Infrastructure.Services.Notifications
{
public class TemplateSavingNotification : SavingNotification<ITemplate>
{
private const string s_templateForContentTypeKey = "CreateTemplateForContentType";
private const string s_contentTypeAliasKey = "ContentTypeAlias";
public TemplateSavingNotification(ITemplate target, EventMessages messages) : base(target, messages)
{
}
public TemplateSavingNotification(IEnumerable<ITemplate> target, EventMessages messages) : base(target, messages)
{
}
public TemplateSavingNotification(ITemplate target, EventMessages messages, bool createTemplateForContentType,
string contentTypeAlias) : base(target, messages)
{
CreateTemplateForContentType = createTemplateForContentType;
ContentTypeAlias = contentTypeAlias;
}
public TemplateSavingNotification(IEnumerable<ITemplate> target, EventMessages messages,
bool createTemplateForContentType,
string contentTypeAlias) : base(target, messages)
{
CreateTemplateForContentType = createTemplateForContentType;
ContentTypeAlias = contentTypeAlias;
}
public bool CreateTemplateForContentType
{
get
{
State.TryGetValue(s_templateForContentTypeKey, out var result);
if (result is not bool createTemplate)
{
return false;
}
return createTemplate;
}
set => State[s_templateForContentTypeKey] = value;
}
public string ContentTypeAlias
{
get
{
State.TryGetValue(s_contentTypeAliasKey, out var result);
return result as string;
}
set => State[s_contentTypeAliasKey] = value;
}
}
}

View File

@@ -42,9 +42,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache
var definitions = new IEventDefinition[]
{
new EventDefinition<IFileService, SaveEventArgs<IStylesheet>>(null, FileService, new SaveEventArgs<IStylesheet>(Enumerable.Empty<IStylesheet>())),
new EventDefinition<IFileService, DeleteEventArgs<IStylesheet>>(null, FileService, new DeleteEventArgs<IStylesheet>(Enumerable.Empty<IStylesheet>())),
new EventDefinition<IContentTypeService, SaveEventArgs<IContentType>>(null, ContentTypeService, new SaveEventArgs<IContentType>(Enumerable.Empty<IContentType>())),
new EventDefinition<IContentTypeService, DeleteEventArgs<IContentType>>(null, ContentTypeService, new DeleteEventArgs<IContentType>(Enumerable.Empty<IContentType>())),
new EventDefinition<IMediaTypeService, SaveEventArgs<IMediaType>>(null, MediaTypeService, new SaveEventArgs<IMediaType>(Enumerable.Empty<IMediaType>())),
@@ -53,9 +50,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache
new EventDefinition<IMemberTypeService, SaveEventArgs<IMemberType>>(null, MemberTypeService, new SaveEventArgs<IMemberType>(Enumerable.Empty<IMemberType>())),
new EventDefinition<IMemberTypeService, DeleteEventArgs<IMemberType>>(null, MemberTypeService, new DeleteEventArgs<IMemberType>(Enumerable.Empty<IMemberType>())),
new EventDefinition<IFileService, SaveEventArgs<ITemplate>>(null, FileService, new SaveEventArgs<ITemplate>(Enumerable.Empty<ITemplate>())),
new EventDefinition<IFileService, DeleteEventArgs<ITemplate>>(null, FileService, new DeleteEventArgs<ITemplate>(Enumerable.Empty<ITemplate>())),
// not managed
//new EventDefinition<IContentService, SaveEventArgs<IContent>>(null, ContentService, new SaveEventArgs<IContent>(Enumerable.Empty<IContent>()), "SavedBlueprint"),
//new EventDefinition<IContentService, DeleteEventArgs<IContent>>(null, ContentService, new DeleteEventArgs<IContent>(Enumerable.Empty<IContent>()), "DeletedBlueprint"),

View File

@@ -11,6 +11,7 @@ using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
using Umbraco.Cms.Infrastructure.ModelsBuilder.Building;
using Umbraco.Cms.Infrastructure.Services.Notifications;
using Umbraco.Cms.Infrastructure.WebAssets;
using Umbraco.Cms.Web.Common.ModelBinders;
using Umbraco.Cms.Web.Common.ModelsBuilder;
@@ -98,7 +99,7 @@ namespace Umbraco.Extensions
// TODO: I feel like we could just do builder.AddNotificationHandler<ModelsBuilderNotificationHandler>() and it
// would automatically just register for all implemented INotificationHandler{T}?
builder.AddNotificationHandler<UmbracoApplicationStarting, ModelsBuilderNotificationHandler>();
builder.AddNotificationHandler<TemplateSavingNotification, ModelsBuilderNotificationHandler>();
builder.AddNotificationHandler<ServerVariablesParsing, ModelsBuilderNotificationHandler>();
builder.AddNotificationHandler<ModelBindingError, ModelsBuilderNotificationHandler>();
builder.AddNotificationHandler<UmbracoApplicationStarting, LiveModelsProvider>();

View File

@@ -11,6 +11,7 @@ using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Implement;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
using Umbraco.Cms.Infrastructure.Services.Notifications;
using Umbraco.Cms.Infrastructure.WebAssets;
using Umbraco.Cms.Web.Common.ModelBinders;
@@ -19,7 +20,10 @@ namespace Umbraco.Cms.Web.Common.ModelsBuilder
/// <summary>
/// Handles <see cref="UmbracoApplicationStarting"/> and <see cref="ServerVariablesParsing"/> notifications to initialize MB
/// </summary>
internal class ModelsBuilderNotificationHandler : INotificationHandler<UmbracoApplicationStarting>, INotificationHandler<ServerVariablesParsing>, INotificationHandler<ModelBindingError>
internal class ModelsBuilderNotificationHandler :
INotificationHandler<ServerVariablesParsing>,
INotificationHandler<ModelBindingError>,
INotificationHandler<TemplateSavingNotification>
{
private readonly ModelsBuilderSettings _config;
private readonly IShortStringHelper _shortStringHelper;
@@ -35,19 +39,6 @@ namespace Umbraco.Cms.Web.Common.ModelsBuilder
_modelsBuilderDashboardProvider = modelsBuilderDashboardProvider;
}
/// <summary>
/// Handles the <see cref="UmbracoApplicationStarting"/> notification
/// </summary>
public void Handle(UmbracoApplicationStarting notification)
{
// always setup the dashboard
// note: UmbracoApiController instances are automatically registered
if (_config.ModelsMode != ModelsMode.Nothing)
{
FileService.SavingTemplate += FileService_SavingTemplate;
}
}
/// <summary>
/// Handles the <see cref="ServerVariablesParsing"/> notification to add custom urls and MB mode
/// </summary>
@@ -99,21 +90,26 @@ namespace Umbraco.Cms.Web.Common.ModelsBuilder
/// Used to check if a template is being created based on a document type, in this case we need to
/// ensure the template markup is correct based on the model name of the document type
/// </summary>
private void FileService_SavingTemplate(IFileService sender, SaveEventArgs<ITemplate> e)
public void Handle(TemplateSavingNotification notification)
{
// don't do anything if this special key is not found
if (!e.AdditionalData.ContainsKey("CreateTemplateForContentType"))
if (_config.ModelsMode == ModelsMode.Nothing)
{
return;
}
// Don't do anything if we're not requested to create a template for a content type
if (notification.CreateTemplateForContentType is false)
{
return;
}
// ensure we have the content type alias
if (!e.AdditionalData.ContainsKey("ContentTypeAlias"))
if (notification.ContentTypeAlias is null)
{
throw new InvalidOperationException("The additionalData key: ContentTypeAlias was not found");
throw new InvalidOperationException("ContentTypeAlias was not found on the notification");
}
foreach (ITemplate template in e.SavedEntities)
foreach (ITemplate template in notification.SavedEntities)
{
// if it is in fact a new entity (not been saved yet) and the "CreateTemplateForContentType" key
// is found, then it means a new template is being created based on the creation of a document type
@@ -121,7 +117,7 @@ namespace Umbraco.Cms.Web.Common.ModelsBuilder
{
// ensure is safe and always pascal cased, per razor standard
// + this is how we get the default model name in Umbraco.ModelsBuilder.Umbraco.Application
var alias = e.AdditionalData["ContentTypeAlias"].ToString();
var alias = notification.ContentTypeAlias;
var name = template.Name; // will be the name of the content type since we are creating
var className = UmbracoServices.GetClrName(_shortStringHelper, name, alias);