Create scoped notification publishing - particularly for "ed" notifications that must run after the current scope has completed

This commit is contained in:
Kenn Jacobsen
2021-03-03 17:08:21 +01:00
parent 134a92e4d9
commit 8e745eb13c
10 changed files with 232 additions and 190 deletions

View File

@@ -0,0 +1,34 @@
using System.Threading.Tasks;
namespace Umbraco.Cms.Core.Events
{
public interface IScopedNotificationPublisher
{
/// <summary>
/// Publishes a cancelable notification to the notification subscribers
/// </summary>
/// <param name="notification"></param>
/// <returns>True if the notification was cancelled by a subscriber, false otherwise</returns>
bool PublishCancelable(ICancelableNotification notification);
/// <summary>
/// Publishes a cancelable notification to the notification subscribers
/// </summary>
/// <param name="notification"></param>
/// <returns>True if the notification was cancelled by a subscriber, false otherwise</returns>
Task<bool> PublishCancelableAsync(ICancelableNotification notification);
/// <summary>
/// Publishes a notification to the notification subscribers
/// </summary>
/// <param name="notification"></param>
/// <remarks>The notification is published upon successful completion of the current scope, i.e. when things have been saved/published/deleted etc.</remarks>
void Publish(INotification notification);
/// <summary>
/// Invokes publishing of all pending notifications within the current scope
/// </summary>
/// <param name="completed"></param>
void ScopeExit(bool completed);
}
}

View File

@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Umbraco.Cms.Core.Events
{
public class ScopedNotificationPublisher : IScopedNotificationPublisher
{
private readonly IEventAggregator _eventAggregator;
private readonly List<INotification> _notificationOnScopeCompleted;
public ScopedNotificationPublisher(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_notificationOnScopeCompleted = new List<INotification>();
}
public bool PublishCancelable(ICancelableNotification notification)
{
if (notification == null)
{
throw new ArgumentNullException(nameof(notification));
}
_eventAggregator.Publish(notification);
return notification.Cancel;
}
public async Task<bool> PublishCancelableAsync(ICancelableNotification notification)
{
if (notification == null)
{
throw new ArgumentNullException(nameof(notification));
}
await _eventAggregator.PublishAsync(notification);
return notification.Cancel;
}
public void Publish(INotification notification)
{
if (notification == null)
{
throw new ArgumentNullException(nameof(notification));
}
_notificationOnScopeCompleted.Add(notification);
}
public void ScopeExit(bool completed)
{
try
{
if (completed)
{
foreach (var notification in _notificationOnScopeCompleted)
{
_eventAggregator.Publish(notification);
}
}
}
finally
{
_notificationOnScopeCompleted.Clear();
}
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Infrastructure.Persistence;
@@ -30,6 +30,11 @@ namespace Umbraco.Cms.Core.Scoping
/// </summary>
IEventDispatcher Events { get; }
/// <summary>
/// Gets the scope notification publisher
/// </summary>
IScopedNotificationPublisher Notifications { get; }
/// <summary>
/// Gets the repositories cache mode.
/// </summary>

View File

@@ -19,6 +19,7 @@ namespace Umbraco.Cms.Core.Scoping
private readonly ScopeProvider _scopeProvider;
private readonly CoreDebugSettings _coreDebugSettings;
private readonly IMediaFileSystem _mediaFileSystem;
private readonly IEventAggregator _eventAggregator;
private readonly ILogger<Scope> _logger;
private readonly IsolationLevel _isolationLevel;
@@ -35,12 +36,15 @@ namespace Umbraco.Cms.Core.Scoping
private EventMessages _messages;
private ICompletable _fscope;
private IEventDispatcher _eventDispatcher;
// eventually this may need to be injectable - for now we'll create it explicitly and let future needs determine if it should be injectable
private IScopedNotificationPublisher _notificationPublisher;
// initializes a new scope
private Scope(
ScopeProvider scopeProvider,
CoreDebugSettings coreDebugSettings,
IMediaFileSystem mediaFileSystem,
IEventAggregator eventAggregator,
ILogger<Scope> logger,
FileSystems fileSystems,
Scope parent,
@@ -56,6 +60,7 @@ namespace Umbraco.Cms.Core.Scoping
_scopeProvider = scopeProvider;
_coreDebugSettings = coreDebugSettings;
_mediaFileSystem = mediaFileSystem;
_eventAggregator = eventAggregator;
_logger = logger;
Context = scopeContext;
@@ -69,6 +74,7 @@ namespace Umbraco.Cms.Core.Scoping
Detachable = detachable;
#if DEBUG_SCOPES
_scopeProvider.RegisterScope(this);
Console.WriteLine("create " + InstanceId.ToString("N").Substring(0, 8));
@@ -124,6 +130,7 @@ namespace Umbraco.Cms.Core.Scoping
ScopeProvider scopeProvider,
CoreDebugSettings coreDebugSettings,
IMediaFileSystem mediaFileSystem,
IEventAggregator eventAggregator,
ILogger<Scope> logger,
FileSystems fileSystems,
bool detachable,
@@ -134,7 +141,7 @@ namespace Umbraco.Cms.Core.Scoping
bool? scopeFileSystems = null,
bool callContext = false,
bool autoComplete = false)
: this(scopeProvider, coreDebugSettings, mediaFileSystem, logger, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
: this(scopeProvider, coreDebugSettings, mediaFileSystem, eventAggregator, logger, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
{ }
// initializes a new scope in a nested scopes chain, with its parent
@@ -142,6 +149,7 @@ namespace Umbraco.Cms.Core.Scoping
ScopeProvider scopeProvider,
CoreDebugSettings coreDebugSettings,
IMediaFileSystem mediaFileSystem,
IEventAggregator eventAggregator,
ILogger<Scope> logger,
FileSystems fileSystems,
Scope parent,
@@ -151,7 +159,7 @@ namespace Umbraco.Cms.Core.Scoping
bool? scopeFileSystems = null,
bool callContext = false,
bool autoComplete = false)
: this(scopeProvider, coreDebugSettings, mediaFileSystem, logger, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
: this(scopeProvider, coreDebugSettings, mediaFileSystem, eventAggregator, logger, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
{ }
public Guid InstanceId { get; } = Guid.NewGuid();
@@ -314,6 +322,16 @@ namespace Umbraco.Cms.Core.Scoping
}
}
public IScopedNotificationPublisher Notifications
{
get
{
EnsureNotDisposed();
if (ParentScope != null) return ParentScope.Notifications;
return _notificationPublisher ?? (_notificationPublisher = new ScopedNotificationPublisher(_eventAggregator));
}
}
/// <inheritdoc />
public bool Complete()
{
@@ -453,7 +471,10 @@ namespace Umbraco.Cms.Core.Scoping
{
// deal with events
if (onException == false)
{
_eventDispatcher?.ScopeExit(completed);
_notificationPublisher?.ScopeExit(completed);
}
}, () =>
{
// if *we* created it, then get rid of it

View File

@@ -26,8 +26,9 @@ namespace Umbraco.Cms.Core.Scoping
private readonly FileSystems _fileSystems;
private readonly CoreDebugSettings _coreDebugSettings;
private readonly IMediaFileSystem _mediaFileSystem;
private readonly IEventAggregator _eventAggregator;
public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, IOptions<CoreDebugSettings> coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger<ScopeProvider> logger, ILoggerFactory loggerFactory, IRequestCache requestCache)
public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, IOptions<CoreDebugSettings> coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger<ScopeProvider> logger, ILoggerFactory loggerFactory, IRequestCache requestCache, IEventAggregator eventAggregator)
{
DatabaseFactory = databaseFactory;
_fileSystems = fileSystems;
@@ -36,6 +37,7 @@ namespace Umbraco.Cms.Core.Scoping
_logger = logger;
_loggerFactory = loggerFactory;
_requestCache = requestCache;
_eventAggregator = eventAggregator;
// take control of the FileSystems
_fileSystems.IsScoped = () => AmbientScope != null && AmbientScope.ScopedFileSystems;
@@ -253,7 +255,7 @@ namespace Umbraco.Cms.Core.Scoping
IEventDispatcher eventDispatcher = null,
bool? scopeFileSystems = null)
{
return new Scope(this, _coreDebugSettings, _mediaFileSystem, _loggerFactory.CreateLogger<Scope>(), _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems);
return new Scope(this, _coreDebugSettings, _mediaFileSystem, _eventAggregator, _loggerFactory.CreateLogger<Scope>(), _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems);
}
/// <inheritdoc />
@@ -309,13 +311,13 @@ namespace Umbraco.Cms.Core.Scoping
{
var ambientContext = AmbientContext;
var newContext = ambientContext == null ? new ScopeContext() : null;
var scope = new Scope(this, _coreDebugSettings, _mediaFileSystem, _loggerFactory.CreateLogger<Scope>(), _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
var scope = new Scope(this, _coreDebugSettings, _mediaFileSystem, _eventAggregator, _loggerFactory.CreateLogger<Scope>(), _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
// assign only if scope creation did not throw!
SetAmbient(scope, newContext ?? ambientContext);
return scope;
}
var nested = new Scope(this, _coreDebugSettings, _mediaFileSystem, _loggerFactory.CreateLogger<Scope>(), _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
var nested = new Scope(this, _coreDebugSettings, _mediaFileSystem, _eventAggregator, _loggerFactory.CreateLogger<Scope>(), _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
SetAmbient(nested, AmbientContext);
return nested;
}

View File

@@ -33,7 +33,6 @@ namespace Umbraco.Cms.Core.Services.Implement
private readonly IShortStringHelper _shortStringHelper;
private readonly ILogger<ContentService> _logger;
private IQuery<IContent> _queryNotTrashed;
private readonly IEventAggregator _eventAggregator;
#region Constructors
@@ -41,7 +40,7 @@ namespace Umbraco.Cms.Core.Services.Implement
IEventMessagesFactory eventMessagesFactory,
IDocumentRepository documentRepository, IEntityRepository entityRepository, IAuditRepository auditRepository,
IContentTypeRepository contentTypeRepository, IDocumentBlueprintRepository documentBlueprintRepository, ILanguageRepository languageRepository,
Lazy<IPropertyValidationService> propertyValidationService, IShortStringHelper shortStringHelper, IEventAggregator eventAggregator)
Lazy<IPropertyValidationService> propertyValidationService, IShortStringHelper shortStringHelper)
: base(provider, loggerFactory, eventMessagesFactory)
{
_documentRepository = documentRepository;
@@ -52,7 +51,6 @@ namespace Umbraco.Cms.Core.Services.Implement
_languageRepository = languageRepository;
_propertyValidationService = propertyValidationService;
_shortStringHelper = shortStringHelper;
_eventAggregator = eventAggregator;
_logger = loggerFactory.CreateLogger<ContentService>();
}
@@ -750,15 +748,10 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
if (raiseEvents)
if (raiseEvents && scope.Notifications.PublishCancelable(new SavingNotification<IContent>(content, evtMsgs)))
{
var notification = new SavingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
{
scope.Complete();
return OperationResult.Cancel(evtMsgs);
}
scope.Complete();
return OperationResult.Cancel(evtMsgs);
}
scope.WriteLock(Cms.Core.Constants.Locks.ContentTree);
@@ -780,7 +773,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (raiseEvents)
{
_eventAggregator.Publish(new SavedNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IContent>(content, evtMsgs));
}
var changeType = TreeChangeTypes.RefreshNode;
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(content, changeType).ToEventArgs());
@@ -809,15 +802,10 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
if (raiseEvents)
if (raiseEvents && scope.Notifications.PublishCancelable(new SavingNotification<IContent>(contentsA, evtMsgs)))
{
var notification = new SavingNotification<IContent>(contentsA, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
{
scope.Complete();
return OperationResult.Cancel(evtMsgs);
}
scope.Complete();
return OperationResult.Cancel(evtMsgs);
}
var treeChanges = contentsA.Select(x => new TreeChange<IContent>(x, TreeChangeTypes.RefreshNode));
@@ -834,7 +822,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (raiseEvents)
{
_eventAggregator.Publish(new SavedNotification<IContent>(contentsA, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IContent>(contentsA, evtMsgs));
}
scope.Events.Dispatch(TreeChanged, this, treeChanges.ToEventArgs());
Audit(AuditType.Save, userId == -1 ? 0 : userId, Cms.Core.Constants.System.Root, "Saved multiple content");
@@ -878,9 +866,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var allLangs = _languageRepository.GetMany().ToList();
var notification = new SavingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(content, evtMsgs)))
{
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
}
@@ -920,14 +906,9 @@ namespace Umbraco.Cms.Core.Services.Implement
var evtMsgs = EventMessagesFactory.Get();
if (raiseEvents)
if (raiseEvents && scope.Notifications.PublishCancelable(new SavingNotification<IContent>(content, evtMsgs)))
{
var notification = new SavingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
{
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
}
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
}
var varies = content.ContentType.VariesByCulture();
@@ -990,9 +971,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var allLangs = _languageRepository.GetMany().ToList();
var notification = new SavingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(content, evtMsgs)))
{
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
}
@@ -1063,9 +1042,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.WriteLock(Cms.Core.Constants.Locks.ContentTree);
var notification = new SavingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(content, evtMsgs)))
{
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
}
@@ -1235,7 +1212,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// raise the Saved event, always
if (raiseEvents)
{
_eventAggregator.Publish(new SavedNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IContent>(content, evtMsgs));
}
if (unpublishing) // we have tried to unpublish - won't happen in a branch
@@ -1243,7 +1220,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (unpublishResult.Success) // and succeeded, trigger events
{
// events and audit
_eventAggregator.Publish(new UnpublishedNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new UnpublishedNotification<IContent>(content, evtMsgs));
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(content, TreeChangeTypes.RefreshBranch).ToEventArgs());
if (culturesUnpublishing != null)
@@ -1298,7 +1275,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (!branchOne) // for branches, handled by SaveAndPublishBranch
{
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(content, changeType).ToEventArgs());
_eventAggregator.Publish(new PublishedNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new PublishedNotification<IContent>(content, evtMsgs));
}
// it was not published and now is... descendants that were 'published' (but
@@ -1307,7 +1284,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (!branchOne && isNew == false && previouslyPublished == false && HasChildren(content.Id))
{
var descendants = GetPublishedDescendantsLocked(content).ToArray();
_eventAggregator.Publish(new PublishedNotification<IContent>(descendants, evtMsgs));
scope.Notifications.Publish(new PublishedNotification<IContent>(descendants, evtMsgs));
}
switch (publishResult.Result)
@@ -1400,9 +1377,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (pendingCultures.Count == 0)
continue; //shouldn't happen but no point in processing this document if there's nothing there
var notification = new SavingNotification<IContent>(d, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(d, evtMsgs)))
{
results.Add(new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, d));
continue;
@@ -1462,9 +1437,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (pendingCultures.Count == 0)
continue; //shouldn't happen but no point in processing this document if there's nothing there
var notification = new SavingNotification<IContent>(d, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(d, evtMsgs)))
{
results.Add(new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, d));
continue;
@@ -1721,7 +1694,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// trigger events for the entire branch
// (SaveAndPublishBranchOne does *not* do it)
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(document, TreeChangeTypes.RefreshBranch).ToEventArgs());
_eventAggregator.Publish(new PublishedNotification<IContent>(publishedDocuments, evtMsgs));
scope.Notifications.Publish(new PublishedNotification<IContent>(publishedDocuments, evtMsgs));
scope.Complete();
}
@@ -1745,9 +1718,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (culturesToPublish.Count == 0) // empty = already published
return new PublishResult(PublishResultType.SuccessPublishAlready, evtMsgs, document);
var notification = new SavingNotification<IContent>(document, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(document, evtMsgs)))
{
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, document);
}
@@ -1776,9 +1747,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new DeletingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingNotification<IContent>(content, evtMsgs)))
{
scope.Complete();
return OperationResult.Cancel(evtMsgs);
@@ -1791,7 +1760,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// just raise the event
if (content.Trashed == false && content.Published)
{
_eventAggregator.Publish(new UnpublishedNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new UnpublishedNotification<IContent>(content, evtMsgs));
}
DeleteLocked(scope, content, evtMsgs);
@@ -1810,7 +1779,7 @@ namespace Umbraco.Cms.Core.Services.Implement
void DoDelete(IContent c)
{
_documentRepository.Delete(c);
_eventAggregator.Publish(new DeletedNotification<IContent>(c, evtMsgs));
scope.Notifications.Publish(new DeletedNotification<IContent>(c, evtMsgs));
// media files deleted by QueuingEventDispatcher
}
@@ -1845,9 +1814,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new DeletingVersionsNotification<IContent>(id, evtMsgs, dateToRetain: versionDate);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingVersionsNotification<IContent>(id, evtMsgs, dateToRetain: versionDate)))
{
scope.Complete();
return;
@@ -1856,7 +1823,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.WriteLock(Cms.Core.Constants.Locks.ContentTree);
_documentRepository.DeleteVersions(id, versionDate);
_eventAggregator.Publish(new DeletedVersionsNotification<IContent>(id, evtMsgs, dateToRetain: versionDate));
scope.Notifications.Publish(new DeletedVersionsNotification<IContent>(id, evtMsgs, dateToRetain: versionDate));
Audit(AuditType.Delete, userId, Cms.Core.Constants.System.Root, "Delete (by version date)");
scope.Complete();
@@ -1877,9 +1844,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new DeletingVersionsNotification<IContent>(id, evtMsgs, specificVersion: versionId);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingVersionsNotification<IContent>(id, evtMsgs, specificVersion: versionId)))
{
scope.Complete();
return;
@@ -1896,7 +1861,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (c.VersionId != versionId && c.PublishedVersionId != versionId) // don't delete the current or published version
_documentRepository.DeleteVersion(versionId);
_eventAggregator.Publish(new DeletedVersionsNotification<IContent>(id, evtMsgs, specificVersion: versionId));
scope.Notifications.Publish(new DeletedVersionsNotification<IContent>(id, evtMsgs, specificVersion: versionId));
Audit(AuditType.Delete, userId, Cms.Core.Constants.System.Root, "Delete (by version)");
scope.Complete();
@@ -1920,9 +1885,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var originalPath = content.Path;
var moveEventInfo = new MoveEventInfo<IContent>(content, originalPath, Cms.Core.Constants.System.RecycleBinContent);
var notification = new MovingToRecycleBinNotification<IContent>(moveEventInfo, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new MovingToRecycleBinNotification<IContent>(moveEventInfo, evtMsgs)))
{
scope.Complete();
return OperationResult.Cancel(evtMsgs); // causes rollback
@@ -1941,7 +1904,7 @@ namespace Umbraco.Cms.Core.Services.Implement
.Select(x => new MoveEventInfo<IContent>(x.Item1, x.Item2, x.Item1.ParentId))
.ToArray();
_eventAggregator.Publish(new MovedToRecycleBinNotification<IContent>(moveInfo, evtMsgs));
scope.Notifications.Publish(new MovedToRecycleBinNotification<IContent>(moveInfo, evtMsgs));
Audit(AuditType.Move, userId, content.Id, "Moved to recycle bin");
scope.Complete();
@@ -1983,9 +1946,8 @@ namespace Umbraco.Cms.Core.Services.Implement
throw new InvalidOperationException("Parent does not exist or is trashed."); // causes rollback
var moveEventInfo = new MoveEventInfo<IContent>(content, content.Path, parentId);
var notification = new MovingNotification<IContent>(moveEventInfo, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new MovingNotification<IContent>(moveEventInfo, evtMsgs)))
{
scope.Complete();
return; // causes rollback
@@ -2014,7 +1976,7 @@ namespace Umbraco.Cms.Core.Services.Implement
.Select(x => new MoveEventInfo<IContent>(x.Item1, x.Item2, x.Item1.ParentId))
.ToArray();
_eventAggregator.Publish(new MovedNotification<IContent>(moveInfo, evtMsgs));
scope.Notifications.Publish(new MovedNotification<IContent>(moveInfo, evtMsgs));
Audit(AuditType.Move, userId, content.Id);
@@ -2099,9 +2061,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// are managed by Delete, and not here.
// no idea what those events are for, keep a simplified version
var notification = new EmptyingRecycleBinNotification<IContent>(evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new EmptyingRecycleBinNotification<IContent>(evtMsgs)))
{
scope.Complete();
return OperationResult.Cancel(evtMsgs);
@@ -2116,7 +2076,7 @@ namespace Umbraco.Cms.Core.Services.Implement
deleted.Add(content);
}
_eventAggregator.Publish(new EmptiedRecycleBinNotification<IContent>(evtMsgs));
scope.Notifications.Publish(new EmptiedRecycleBinNotification<IContent>(evtMsgs));
scope.Events.Dispatch(TreeChanged, this, deleted.Select(x => new TreeChange<IContent>(x, TreeChangeTypes.Remove)).ToEventArgs());
Audit(AuditType.Delete, userId, Cms.Core.Constants.System.RecycleBinContent, "Recycle bin emptied");
@@ -2163,9 +2123,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new CopyingNotification<IContent>(content, copy, parentId, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new CopyingNotification<IContent>(content, copy, parentId, evtMsgs)))
{
scope.Complete();
return null;
@@ -2220,9 +2178,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var descendantCopy = descendant.DeepCloneWithResetIdentities();
descendantCopy.ParentId = parentId;
notification = new CopyingNotification<IContent>(descendant, descendantCopy, parentId, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new CopyingNotification<IContent>(descendant, descendantCopy, parentId, evtMsgs)))
{
continue;
}
@@ -2250,7 +2206,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(copy, TreeChangeTypes.RefreshBranch).ToEventArgs());
foreach (var x in copies)
{
_eventAggregator.Publish(new CopiedNotification<IContent>(x.Item1, x.Item2, parentId, relateToOriginal, evtMsgs));
scope.Notifications.Publish(new CopiedNotification<IContent>(x.Item1, x.Item2, parentId, relateToOriginal, evtMsgs));
}
Audit(AuditType.Copy, userId, content.Id);
@@ -2272,9 +2228,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new SendingToPublishNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SendingToPublishNotification<IContent>(content, evtMsgs)))
{
scope.Complete();
return false;
@@ -2299,7 +2253,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (!saveResult.Success)
return saveResult.Success;
_eventAggregator.Publish(new SentToPublishNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new SentToPublishNotification<IContent>(content, evtMsgs));
if (culturesChanging != null)
Audit(AuditType.SendToPublishVariant, userId, content.Id, $"Send To Publish for cultures: {culturesChanging}", culturesChanging);
@@ -2374,17 +2328,13 @@ namespace Umbraco.Cms.Core.Services.Implement
if (raiseEvents)
{
// raise cancelable sorting event
var sortingNotification = new SortingNotification<IContent>(itemsA, evtMsgs);
_eventAggregator.Publish(sortingNotification);
if (sortingNotification.Cancel)
if (scope.Notifications.PublishCancelable(new SortingNotification<IContent>(itemsA, evtMsgs)))
{
return OperationResult.Cancel(evtMsgs);
}
// raise cancelable saving event
var savingNotification = new SavingNotification<IContent>(itemsA, evtMsgs);
_eventAggregator.Publish(savingNotification);
if (savingNotification.Cancel)
// raise cancelable saving event
if (scope.Notifications.PublishCancelable(new SavingNotification<IContent>(itemsA, evtMsgs)))
{
return OperationResult.Cancel(evtMsgs);
}
@@ -2421,15 +2371,15 @@ namespace Umbraco.Cms.Core.Services.Implement
if (raiseEvents)
{
//first saved, then sorted
_eventAggregator.Publish(new SavedNotification<IContent>(itemsA, evtMsgs));
_eventAggregator.Publish(new SortedNotification<IContent>(itemsA, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IContent>(itemsA, evtMsgs));
scope.Notifications.Publish(new SortedNotification<IContent>(itemsA, evtMsgs));
}
scope.Events.Dispatch(TreeChanged, this, saved.Select(x => new TreeChange<IContent>(x, TreeChangeTypes.RefreshNode)).ToEventArgs());
if (raiseEvents && published.Any())
{
_eventAggregator.Publish(new PublishedNotification<IContent>(published, evtMsgs));
scope.Notifications.Publish(new PublishedNotification<IContent>(published, evtMsgs));
}
Audit(AuditType.Sort, userId, 0, "Sorting content performed by user");
@@ -2534,9 +2484,7 @@ namespace Umbraco.Cms.Core.Services.Implement
IReadOnlyCollection<string> culturesUnpublishing, EventMessages evtMsgs, IReadOnlyCollection<ILanguage> allLangs)
{
// raise Publishing notification
var notification = new PublishingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new PublishingNotification<IContent>(content, evtMsgs)))
{
_logger.LogInformation("Document {ContentName} (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "publishing was cancelled");
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
@@ -2696,9 +2644,7 @@ namespace Umbraco.Cms.Core.Services.Implement
private PublishResult StrategyCanUnpublish(IScope scope, IContent content, EventMessages evtMsgs)
{
// raise Unpublishing notification
var notification = new UnpublishingNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new UnpublishingNotification<IContent>(content, evtMsgs)))
{
_logger.LogInformation("Document {ContentName} (id={ContentId}) cannot be unpublished: unpublishing was cancelled.", content.Name, content.Id);
return new PublishResult(PublishResultType.FailedUnpublishCancelledByEvent, evtMsgs, content);
@@ -2780,9 +2726,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var query = Query<IContent>().WhereIn(x => x.ContentTypeId, contentTypeIdsA);
var contents = _documentRepository.Get(query).ToArray();
var notification = new DeletingNotification<IContent>(contents, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingNotification<IContent>(contents, evtMsgs)))
{
scope.Complete();
return;
@@ -2797,7 +2741,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// just raise the event
if (content.Trashed == false && content.Published)
{
_eventAggregator.Publish(new UnpublishedNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new UnpublishedNotification<IContent>(content, evtMsgs));
}
// if current content has children, move them to trash
@@ -2822,7 +2766,7 @@ namespace Umbraco.Cms.Core.Services.Implement
.ToArray();
if (moveInfos.Length > 0)
{
_eventAggregator.Publish(new MovedToRecycleBinNotification<IContent>(moveInfos, evtMsgs));
scope.Notifications.Publish(new MovedToRecycleBinNotification<IContent>(moveInfos, evtMsgs));
}
scope.Events.Dispatch(TreeChanged, this, changes.ToEventArgs());
@@ -2922,7 +2866,7 @@ namespace Umbraco.Cms.Core.Services.Implement
Audit(AuditType.Save, Cms.Core.Constants.Security.SuperUserId, content.Id, $"Saved content template: {content.Name}");
_eventAggregator.Publish(new SavedBlueprintNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new SavedBlueprintNotification<IContent>(content, evtMsgs));
scope.Complete();
}
@@ -2936,7 +2880,7 @@ namespace Umbraco.Cms.Core.Services.Implement
{
scope.WriteLock(Cms.Core.Constants.Locks.ContentTree);
_documentBlueprintRepository.Delete(content);
_eventAggregator.Publish(new DeletedBlueprintNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new DeletedBlueprintNotification<IContent>(content, evtMsgs));
scope.Complete();
}
}
@@ -3028,7 +2972,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_documentBlueprintRepository.Delete(blueprint);
}
_eventAggregator.Publish(new DeletedBlueprintNotification<IContent>(blueprints, evtMsgs));
scope.Notifications.Publish(new DeletedBlueprintNotification<IContent>(blueprints, evtMsgs));
scope.Complete();
}
}
@@ -3063,9 +3007,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new RollingBackNotification<IContent>(content, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new RollingBackNotification<IContent>(content, evtMsgs)))
{
scope.Complete();
return OperationResult.Cancel(evtMsgs);
@@ -3085,7 +3027,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
else
{
_eventAggregator.Publish(new RolledBackNotification<IContent>(content, evtMsgs));
scope.Notifications.Publish(new RolledBackNotification<IContent>(content, evtMsgs));
//Logging & Audit message
_logger.LogInformation("User '{UserId}' rolled back content '{ContentId}' to version '{VersionId}'", userId, id, versionId);

View File

@@ -31,13 +31,11 @@ namespace Umbraco.Cms.Core.Services.Implement
private readonly IMediaFileSystem _mediaFileSystem;
private readonly IEventAggregator _eventAggregator;
#region Constructors
public MediaService(IScopeProvider provider, IMediaFileSystem mediaFileSystem, ILoggerFactory loggerFactory, IEventMessagesFactory eventMessagesFactory,
IMediaRepository mediaRepository, IAuditRepository auditRepository, IMediaTypeRepository mediaTypeRepository,
IEntityRepository entityRepository, IShortStringHelper shortStringHelper, IEventAggregator eventAggregator)
IEntityRepository entityRepository, IShortStringHelper shortStringHelper)
: base(provider, loggerFactory, eventMessagesFactory)
{
_mediaFileSystem = mediaFileSystem;
@@ -46,7 +44,6 @@ namespace Umbraco.Cms.Core.Services.Implement
_mediaTypeRepository = mediaTypeRepository;
_entityRepository = entityRepository;
_shortStringHelper = shortStringHelper;
_eventAggregator = eventAggregator;
}
#endregion
@@ -299,16 +296,14 @@ namespace Umbraco.Cms.Core.Services.Implement
if (withIdentity)
{
var notification = new SavingNotification<IMedia>(media, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new SavingNotification<IMedia>(media, evtMsgs)))
{
return;
}
_mediaRepository.Save(media);
_eventAggregator.Publish(new SavedNotification<IMedia>(media, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IMedia>(media, evtMsgs));
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IMedia>(media, TreeChangeTypes.RefreshNode).ToEventArgs());
}
@@ -666,15 +661,10 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
if (raiseEvents)
if (raiseEvents && scope.Notifications.PublishCancelable(new SavingNotification<IMedia>(media, evtMsgs)))
{
var notification = new SavingNotification<IMedia>(media, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
{
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
}
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
}
// poor man's validation?
@@ -693,7 +683,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_mediaRepository.Save(media);
if (raiseEvents)
{
_eventAggregator.Publish(new SavedNotification<IMedia>(media, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IMedia>(media, evtMsgs));
}
var changeType = TreeChangeTypes.RefreshNode;
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IMedia>(media, changeType).ToEventArgs());
@@ -718,15 +708,10 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
if (raiseEvents)
if (raiseEvents && scope.Notifications.PublishCancelable(new SavingNotification<IMedia>(mediasA, evtMsgs)))
{
var notification = new SavingNotification<IMedia>(mediasA, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
{
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
}
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
}
var treeChanges = mediasA.Select(x => new TreeChange<IMedia>(x, TreeChangeTypes.RefreshNode));
@@ -741,7 +726,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (raiseEvents)
{
_eventAggregator.Publish(new SavedNotification<IMedia>(mediasA, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IMedia>(mediasA, evtMsgs));
}
scope.Events.Dispatch(TreeChanged, this, treeChanges.ToEventArgs());
Audit(AuditType.Save, userId == -1 ? 0 : userId, Cms.Core.Constants.System.Root, "Bulk save media");
@@ -767,9 +752,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new DeletingNotification<IMedia>(media, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingNotification<IMedia>(media, evtMsgs)))
{
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
@@ -793,7 +776,7 @@ namespace Umbraco.Cms.Core.Services.Implement
void DoDelete(IMedia c)
{
_mediaRepository.Delete(c);
_eventAggregator.Publish(new DeletedNotification<IMedia>(c, evtMsgs));
scope.Notifications.Publish(new DeletedNotification<IMedia>(c, evtMsgs));
// media files deleted by QueuingEventDispatcher
}
@@ -836,9 +819,7 @@ namespace Umbraco.Cms.Core.Services.Implement
{
var evtMsgs = EventMessagesFactory.Get();
var notification = new DeletingVersionsNotification<IMedia>(id, evtMsgs, dateToRetain: versionDate);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingVersionsNotification<IMedia>(id, evtMsgs, dateToRetain: versionDate)))
{
return;
}
@@ -847,7 +828,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.WriteLock(Cms.Core.Constants.Locks.MediaTree);
_mediaRepository.DeleteVersions(id, versionDate);
_eventAggregator.Publish(new DeletedVersionsNotification<IMedia>(id, evtMsgs, dateToRetain: versionDate));
scope.Notifications.Publish(new DeletedVersionsNotification<IMedia>(id, evtMsgs, dateToRetain: versionDate));
Audit(AuditType.Delete, userId, Cms.Core.Constants.System.Root, "Delete Media by version date");
}
@@ -865,9 +846,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var notification = new DeletingVersionsNotification<IMedia>(id, evtMsgs, specificVersion: versionId);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingVersionsNotification<IMedia>(id, evtMsgs, specificVersion: versionId)))
{
scope.Complete();
return;
@@ -885,7 +864,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_mediaRepository.DeleteVersion(versionId);
_eventAggregator.Publish(new DeletedVersionsNotification<IMedia>(id, evtMsgs, specificVersion: versionId));
scope.Notifications.Publish(new DeletedVersionsNotification<IMedia>(id, evtMsgs, specificVersion: versionId));
Audit(AuditType.Delete, userId, Cms.Core.Constants.System.Root, "Delete Media by version");
scope.Complete();
@@ -917,9 +896,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var moveEventInfo = new MoveEventInfo<IMedia>(media, originalPath, Cms.Core.Constants.System.RecycleBinMedia);
var notification = new MovingToRecycleBinNotification<IMedia>(moveEventInfo, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new MovingToRecycleBinNotification<IMedia>(moveEventInfo, evtMsgs)))
{
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
@@ -928,9 +905,8 @@ namespace Umbraco.Cms.Core.Services.Implement
PerformMoveLocked(media, Cms.Core.Constants.System.RecycleBinMedia, null, userId, moves, true);
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IMedia>(media, TreeChangeTypes.RefreshBranch).ToEventArgs());
var moveInfo = moves.Select(x => new MoveEventInfo<IMedia>(x.Item1, x.Item2, x.Item1.ParentId))
.ToArray();
_eventAggregator.Publish(new MovedToRecycleBinNotification<IMedia>(moveInfo, evtMsgs));
var moveInfo = moves.Select(x => new MoveEventInfo<IMedia>(x.Item1, x.Item2, x.Item1.ParentId)).ToArray();
scope.Notifications.Publish(new MovedToRecycleBinNotification<IMedia>(moveInfo, evtMsgs));
Audit(AuditType.Move, userId, media.Id, "Move Media to recycle bin");
scope.Complete();
@@ -967,9 +943,7 @@ namespace Umbraco.Cms.Core.Services.Implement
throw new InvalidOperationException("Parent does not exist or is trashed."); // causes rollback
var moveEventInfo = new MoveEventInfo<IMedia>(media, media.Path, parentId);
var notification = new MovingNotification<IMedia>(moveEventInfo, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new MovingNotification<IMedia>(moveEventInfo, evtMsgs)))
{
scope.Complete();
return OperationResult.Attempt.Cancel(evtMsgs);
@@ -985,7 +959,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var moveInfo = moves //changes
.Select(x => new MoveEventInfo<IMedia>(x.Item1, x.Item2, x.Item1.ParentId))
.ToArray();
_eventAggregator.Publish(new MovedNotification<IMedia>(moveInfo, evtMsgs));
scope.Notifications.Publish(new MovedNotification<IMedia>(moveInfo, evtMsgs));
Audit(AuditType.Move, userId, media.Id);
scope.Complete();
}
@@ -1066,9 +1040,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// v7 EmptyingRecycleBin and EmptiedRecycleBin events are greatly simplified since
// each deleted items will have its own deleting/deleted events. so, files and such
// are managed by Delete, and not here.
var notification = new EmptyingRecycleBinNotification<IMedia>(evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new EmptyingRecycleBinNotification<IMedia>(evtMsgs)))
{
scope.Complete();
return OperationResult.Cancel(evtMsgs);
@@ -1082,7 +1054,7 @@ namespace Umbraco.Cms.Core.Services.Implement
DeleteLocked(scope, media, evtMsgs);
deleted.Add(media);
}
_eventAggregator.Publish(new EmptiedRecycleBinNotification<IMedia>(new EventMessages()));
scope.Notifications.Publish(new EmptiedRecycleBinNotification<IMedia>(new EventMessages()));
scope.Events.Dispatch(TreeChanged, this, deleted.Select(x => new TreeChange<IMedia>(x, TreeChangeTypes.Remove)).ToEventArgs());
Audit(AuditType.Delete, userId, Cms.Core.Constants.System.RecycleBinMedia, "Empty Media recycle bin");
scope.Complete();
@@ -1112,15 +1084,10 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
if (raiseEvents)
if (raiseEvents && scope.Notifications.PublishCancelable(new SavingNotification<IMedia>(itemsA, evtMsgs)))
{
var notification = new SavingNotification<IMedia>(itemsA, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
{
scope.Complete();
return false;
}
scope.Complete();
return false;
}
var saved = new List<IMedia>();
@@ -1146,7 +1113,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (raiseEvents)
{
_eventAggregator.Publish(new SavedNotification<IMedia>(itemsA, evtMsgs));
scope.Notifications.Publish(new SavedNotification<IMedia>(itemsA, evtMsgs));
}
scope.Events.Dispatch(TreeChanged, this, saved.Select(x => new TreeChange<IMedia>(x, TreeChangeTypes.RefreshNode)).ToEventArgs());
Audit(AuditType.Sort, userId, 0);
@@ -1264,9 +1231,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var query = Query<IMedia>().WhereIn(x => x.ContentTypeId, mediaTypeIdsA);
var medias = _mediaRepository.Get(query).ToArray();
var notification = new DeletingNotification<IMedia>(medias, evtMsgs);
_eventAggregator.Publish(notification);
if (notification.Cancel)
if (scope.Notifications.PublishCancelable(new DeletingNotification<IMedia>(medias, evtMsgs)))
{
scope.Complete();
return;
@@ -1297,7 +1262,7 @@ namespace Umbraco.Cms.Core.Services.Implement
.ToArray();
if (moveInfos.Length > 0)
{
_eventAggregator.Publish(new MovedToRecycleBinNotification<IMedia>(moveInfos, evtMsgs));
scope.Notifications.Publish(new MovedToRecycleBinNotification<IMedia>(moveInfos, evtMsgs));
}
scope.Events.Dispatch(TreeChanged, this, changes.ToEventArgs());

View File

@@ -17,6 +17,7 @@ using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Logging;
@@ -50,7 +51,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Components
var fs = new FileSystems(mock.Object, loggerFactory.CreateLogger<FileSystems>(), loggerFactory, IOHelper, Options.Create(globalSettings), Mock.Of<IHostingEnvironment>());
var coreDebug = new CoreDebugSettings();
IMediaFileSystem mediaFileSystem = Mock.Of<IMediaFileSystem>();
var p = new ScopeProvider(f, fs, Options.Create(coreDebug), mediaFileSystem, loggerFactory.CreateLogger<ScopeProvider>(), loggerFactory, NoAppCache.Instance);
IEventAggregator eventAggregator = Mock.Of<IEventAggregator>();
var p = new ScopeProvider(f, fs, Options.Create(coreDebug), mediaFileSystem, loggerFactory.CreateLogger<ScopeProvider>(), loggerFactory, NoAppCache.Instance, eventAggregator);
mock.Setup(x => x.GetService(typeof(ILogger))).Returns(logger);
mock.Setup(x => x.GetService(typeof(ILogger<ComponentCollection>))).Returns(loggerFactory.CreateLogger<ComponentCollection>);

View File

@@ -87,7 +87,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Scoping
Mock.Of<IMediaFileSystem>(),
Mock.Of<ILogger<ScopeProvider>>(),
instance,
Mock.Of<IRequestCache>()
Mock.Of<IRequestCache>(),
Mock.Of<IEventAggregator>()
);
}

View File

@@ -8,6 +8,7 @@ using NPoco;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Infrastructure.Migrations.Install;
@@ -86,7 +87,8 @@ namespace Umbraco.Tests.TestHelpers
fileSystems ??= new FileSystems(Current.Factory, loggerFactory.CreateLogger<FileSystems>(), loggerFactory, TestHelper.IOHelper, Options.Create(globalSettings), TestHelper.GetHostingEnvironment());
var coreDebug = TestHelper.CoreDebugSettings;
var mediaFileSystem = Mock.Of<IMediaFileSystem>();
return new ScopeProvider(databaseFactory, fileSystems, Options.Create(coreDebugSettings), mediaFileSystem, loggerFactory.CreateLogger<ScopeProvider>(), loggerFactory, NoAppCache.Instance);
var eventAggregator = Mock.Of<IEventAggregator>();
return new ScopeProvider(databaseFactory, fileSystems, Options.Create(coreDebugSettings), mediaFileSystem, loggerFactory.CreateLogger<ScopeProvider>(), loggerFactory, NoAppCache.Instance, eventAggregator);
}
}