diff --git a/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs b/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs
index 7df9167ce6..58fdafc341 100644
--- a/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs
+++ b/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs
@@ -1,6 +1,7 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
+using System;
using System.Threading.Tasks;
using Umbraco.Cms.Core.Notifications;
@@ -8,6 +9,12 @@ namespace Umbraco.Cms.Core.Events
{
public interface IScopedNotificationPublisher
{
+ ///
+ /// Suppresses all notifications from being added/created until the result object is disposed.
+ ///
+ ///
+ IDisposable Suppress();
+
///
/// Publishes a cancelable notification to the notification subscribers
///
diff --git a/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs b/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs
index c9b0080218..7261b514bf 100644
--- a/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs
+++ b/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using System.Threading.Tasks;
using Umbraco.Cms.Core.Notifications;
@@ -12,6 +13,8 @@ namespace Umbraco.Cms.Core.Events
{
private readonly IEventAggregator _eventAggregator;
private readonly List _notificationOnScopeCompleted;
+ private readonly object _locker = new object();
+ private bool _isSuppressed = false;
public ScopedNotificationPublisher(IEventAggregator eventAggregator)
{
@@ -26,6 +29,11 @@ namespace Umbraco.Cms.Core.Events
throw new ArgumentNullException(nameof(notification));
}
+ if (_isSuppressed)
+ {
+ return false;
+ }
+
_eventAggregator.Publish(notification);
return notification.Cancel;
}
@@ -37,6 +45,11 @@ namespace Umbraco.Cms.Core.Events
throw new ArgumentNullException(nameof(notification));
}
+ if (_isSuppressed)
+ {
+ return false;
+ }
+
await _eventAggregator.PublishAsync(notification);
return notification.Cancel;
}
@@ -48,6 +61,11 @@ namespace Umbraco.Cms.Core.Events
throw new ArgumentNullException(nameof(notification));
}
+ if (_isSuppressed)
+ {
+ return;
+ }
+
_notificationOnScopeCompleted.Add(notification);
}
@@ -57,7 +75,7 @@ namespace Umbraco.Cms.Core.Events
{
if (completed)
{
- foreach (var notification in _notificationOnScopeCompleted)
+ foreach (INotification notification in _notificationOnScopeCompleted)
{
_eventAggregator.Publish(notification);
}
@@ -68,5 +86,45 @@ namespace Umbraco.Cms.Core.Events
_notificationOnScopeCompleted.Clear();
}
}
+
+ public IDisposable Suppress()
+ {
+ lock(_locker)
+ {
+ if (_isSuppressed)
+ {
+ throw new InvalidOperationException("Notifications are already suppressed");
+ }
+ return new Suppressor(this);
+ }
+ }
+
+ private class Suppressor : IDisposable
+ {
+ private bool _disposedValue;
+ private readonly ScopedNotificationPublisher _scopedNotificationPublisher;
+
+ public Suppressor(ScopedNotificationPublisher scopedNotificationPublisher)
+ {
+ _scopedNotificationPublisher = scopedNotificationPublisher;
+ _scopedNotificationPublisher._isSuppressed = true;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ lock (_scopedNotificationPublisher._locker)
+ {
+ _scopedNotificationPublisher._isSuppressed = false;
+ }
+ }
+ _disposedValue = true;
+ }
+ }
+ public void Dispose() => Dispose(disposing: true);
+ }
}
}
diff --git a/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs b/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs
index 6957da7f70..b9cda7722c 100644
--- a/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs
+++ b/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs
@@ -5,6 +5,7 @@ using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Core.Notifications
{
+
[Obsolete("This is only used for the internal cache and will change, use saved notifications instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class ContentRefreshNotification : EntityRefreshNotification
diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs
index cef8a8c6d6..e58664fef8 100644
--- a/src/Umbraco.Core/Services/IContentService.cs
+++ b/src/Umbraco.Core/Services/IContentService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
@@ -236,13 +236,13 @@ namespace Umbraco.Cms.Core.Services
///
/// Saves a document.
///
- OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId);
///
/// Saves documents.
///
// TODO: why only 1 result not 1 per content?!
- OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId);
///
/// Deletes a document.
@@ -325,12 +325,12 @@ namespace Umbraco.Cms.Core.Services
///
/// Sorts documents.
///
- OperationResult Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ OperationResult Sort(IEnumerable items, int userId = Constants.Security.SuperUserId);
///
/// Sorts documents.
///
- OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId);
#endregion
@@ -349,8 +349,7 @@ namespace Umbraco.Cms.Core.Services
/// The document to publish.
/// The culture to publish.
/// The identifier of the user performing the action.
- /// A value indicating whether to raise events.
- PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId);
///
/// Saves and publishes a document.
@@ -363,8 +362,7 @@ namespace Umbraco.Cms.Core.Services
/// The document to publish.
/// The cultures to publish.
/// The identifier of the user performing the action.
- /// A value indicating whether to raise events.
- PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = Constants.Security.SuperUserId);
///
/// Saves and publishes a document branch.
diff --git a/src/Umbraco.Core/Services/IContentServiceBase.cs b/src/Umbraco.Core/Services/IContentServiceBase.cs
index 9ab7fc7acc..a62d039abb 100644
--- a/src/Umbraco.Core/Services/IContentServiceBase.cs
+++ b/src/Umbraco.Core/Services/IContentServiceBase.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Umbraco.Cms.Core.Models;
@@ -8,7 +8,7 @@ namespace Umbraco.Cms.Core.Services
where TItem: class, IContentBase
{
TItem GetById(Guid key);
- Attempt Save(IEnumerable contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ Attempt Save(IEnumerable contents, int userId = Constants.Security.SuperUserId);
}
///
diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs
index f8e91d07d8..c7b13c04e1 100644
--- a/src/Umbraco.Core/Services/IDataTypeService.cs
+++ b/src/Umbraco.Core/Services/IDataTypeService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Umbraco.Cms.Core.Models;
@@ -68,15 +68,7 @@ namespace Umbraco.Cms.Core.Services
/// to save
/// Id of the user issuing the save
void Save(IEnumerable dataTypeDefinitions, int userId = Constants.Security.SuperUserId);
-
- ///
- /// Saves a collection of
- ///
- /// to save
- /// Id of the user issuing the save
- /// Boolean indicating whether or not to raise events
- void Save(IEnumerable dataTypeDefinitions, int userId, bool raiseEvents);
-
+
///
/// Deletes an
///
diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs
index fc4d4fd612..19b509134e 100644
--- a/src/Umbraco.Core/Services/IMediaService.cs
+++ b/src/Umbraco.Core/Services/IMediaService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using Umbraco.Cms.Core.Models;
@@ -198,16 +198,14 @@ namespace Umbraco.Cms.Core.Services
///
/// The to save
/// Id of the User saving the Media
- /// Optional boolean indicating whether or not to raise events.
- Attempt Save(IMedia media, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ Attempt Save(IMedia media, int userId = Constants.Security.SuperUserId);
///
/// Saves a collection of objects
///
/// Collection of to save
/// Id of the User saving the Media
- /// Optional boolean indicating whether or not to raise events.
- Attempt Save(IEnumerable medias, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ Attempt Save(IEnumerable medias, int userId = Constants.Security.SuperUserId);
///
/// Gets an object by its 'UniqueId'
@@ -302,9 +300,8 @@ namespace Umbraco.Cms.Core.Services
///
///
///
- ///
/// True if sorting succeeded, otherwise False
- bool Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
+ bool Sort(IEnumerable items, int userId = Constants.Security.SuperUserId);
///
/// Creates an object using the alias of the
diff --git a/src/Umbraco.Core/Services/IMemberGroupService.cs b/src/Umbraco.Core/Services/IMemberGroupService.cs
index 16028ded3f..0b72906c2f 100644
--- a/src/Umbraco.Core/Services/IMemberGroupService.cs
+++ b/src/Umbraco.Core/Services/IMemberGroupService.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Services
IMemberGroup GetById(Guid id);
IEnumerable GetByIds(IEnumerable ids);
IMemberGroup GetByName(string name);
- void Save(IMemberGroup memberGroup, bool raiseEvents = true);
+ void Save(IMemberGroup memberGroup);
void Delete(IMemberGroup memberGroup);
}
}
diff --git a/src/Umbraco.Core/Services/IMembershipMemberService.cs b/src/Umbraco.Core/Services/IMembershipMemberService.cs
index c91eba5250..6093c0a4fe 100644
--- a/src/Umbraco.Core/Services/IMembershipMemberService.cs
+++ b/src/Umbraco.Core/Services/IMembershipMemberService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
@@ -125,18 +125,14 @@ namespace Umbraco.Cms.Core.Services
///
/// An can be of type or
/// or to Save
- /// Optional parameter to raise events.
- /// Default is True otherwise set to False to not raise events
- void Save(T entity, bool raiseEvents = true);
+ void Save(T entity);
///
/// Saves a list of objects
///
/// An can be of type or
/// to save
- /// Optional parameter to raise events.
- /// Default is True otherwise set to False to not raise events
- void Save(IEnumerable entities, bool raiseEvents = true);
+ void Save(IEnumerable entities);
///
/// Finds a list of objects by a partial email string
diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs
index a4af73e084..25ce49b65d 100644
--- a/src/Umbraco.Core/Services/IUserService.cs
+++ b/src/Umbraco.Core/Services/IUserService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Persistence.Querying;
@@ -243,9 +243,7 @@ namespace Umbraco.Cms.Core.Services
/// If null than no changes are made to the users who are assigned to this group, however if a value is passed in
/// than all users will be removed from this group and only these users will be added
///
- /// Optional parameter to raise events.
- /// Default is True otherwise set to False to not raise events
- void Save(IUserGroup userGroup, int[] userIds = null, bool raiseEvents = true);
+ void Save(IUserGroup userGroup, int[] userIds = null);
///
/// Deletes a UserGroup
diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs
index 32ce247c2b..fcf4ada7c0 100644
--- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs
+++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs
@@ -1044,7 +1044,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
if (dataTypes.Count > 0)
{
- _dataTypeService.Save(dataTypes, userId, true);
+ _dataTypeService.Save(dataTypes, userId);
}
return dataTypes;
diff --git a/src/Umbraco.Infrastructure/Services/Implement/ContentService.cs b/src/Umbraco.Infrastructure/Services/Implement/ContentService.cs
index 3d4c6dfbbe..609a6bd426 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/ContentService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/ContentService.cs
@@ -379,10 +379,8 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- ///
///
- Attempt IContentServiceBase.Save(IEnumerable contents, int userId,
- bool raiseEvents) => Attempt.Succeed(Save(contents, userId, raiseEvents));
+ Attempt IContentServiceBase.Save(IEnumerable contents, int userId) => Attempt.Succeed(Save(contents, userId));
///
/// Gets objects by Ids
@@ -756,7 +754,7 @@ namespace Umbraco.Cms.Core.Services.Implement
#region Save, Publish, Unpublish
///
- public OperationResult Save(IContent content, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public OperationResult Save(IContent content, int userId = Cms.Core.Constants.Security.SuperUserId)
{
PublishedState publishedState = content.PublishedState;
if (publishedState != PublishedState.Published && publishedState != PublishedState.Unpublished)
@@ -774,7 +772,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (IScope scope = ScopeProvider.CreateScope())
{
var savingNotification = new ContentSavingNotification(content, eventMessages);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return OperationResult.Cancel(eventMessages);
@@ -800,10 +798,12 @@ namespace Umbraco.Cms.Core.Services.Implement
_documentRepository.Save(content);
- if (raiseEvents)
- {
- scope.Notifications.Publish(new ContentSavedNotification(content, eventMessages).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new ContentSavedNotification(content, eventMessages).WithStateFrom(savingNotification));
+
+ // TODO: we had code here to FORCE that this event can never be suppressed. But that just doesn't make a ton of sense?!
+ // I understand that if its suppressed that the caches aren't updated, but that would be expected. If someone
+ // is supressing events then I think it's expected that nothing will happen. They are probably doing it for perf
+ // reasons like bulk import and in those cases we don't want this occuring.
scope.Notifications.Publish(new ContentTreeChangeNotification(content, TreeChangeTypes.RefreshNode, eventMessages));
if (culturesChanging != null)
@@ -823,7 +823,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
///
- public OperationResult Save(IEnumerable contents, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public OperationResult Save(IEnumerable contents, int userId = Cms.Core.Constants.Security.SuperUserId)
{
EventMessages eventMessages = EventMessagesFactory.Get();
IContent[] contentsA = contents.ToArray();
@@ -831,7 +831,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (IScope scope = ScopeProvider.CreateScope())
{
var savingNotification = new ContentSavingNotification(contentsA, eventMessages);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return OperationResult.Cancel(eventMessages);
@@ -850,11 +850,10 @@ namespace Umbraco.Cms.Core.Services.Implement
_documentRepository.Save(content);
}
- if (raiseEvents)
- {
- scope.Notifications.Publish(new ContentSavedNotification(contentsA, eventMessages).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new ContentSavedNotification(contentsA, eventMessages).WithStateFrom(savingNotification));
+ // TODO: See note above about supressing events
scope.Notifications.Publish(new ContentTreeChangeNotification(contentsA, TreeChangeTypes.RefreshNode, eventMessages));
+
Audit(AuditType.Save, userId == -1 ? 0 : userId, Cms.Core.Constants.System.Root, "Saved multiple content");
scope.Complete();
@@ -864,7 +863,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
///
- public PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Cms.Core.Constants.Security.SuperUserId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -912,14 +911,14 @@ namespace Umbraco.Cms.Core.Services.Implement
// we don't care about the response here, this response will be rechecked below but we need to set the culture info values now.
content.PublishCulture(impact);
- var result = CommitDocumentChangesInternal(scope, content, evtMsgs, allLangs, savingNotification.State, userId, raiseEvents);
+ var result = CommitDocumentChangesInternal(scope, content, evtMsgs, allLangs, savingNotification.State, userId);
scope.Complete();
return result;
}
}
///
- public PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = 0, bool raiseEvents = true)
+ public PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = 0)
{
if (content == null) throw new ArgumentNullException(nameof(content));
if (cultures == null) throw new ArgumentNullException(nameof(cultures));
@@ -938,7 +937,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var evtMsgs = EventMessagesFactory.Get();
var savingNotification = new ContentSavingNotification(content, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
return new PublishResult(PublishResultType.FailedPublishCancelledByEvent, evtMsgs, content);
}
@@ -948,7 +947,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (cultures.Length == 0 && !varies)
{
//no cultures specified and doesn't vary, so publish it, else nothing to publish
- return SaveAndPublish(content, userId: userId, raiseEvents: raiseEvents);
+ return SaveAndPublish(content, userId: userId);
}
if (cultures.Any(x => x == null || x == "*"))
@@ -959,9 +958,11 @@ namespace Umbraco.Cms.Core.Services.Implement
// publish the culture(s)
// we don't care about the response here, this response will be rechecked below but we need to set the culture info values now.
foreach (var impact in impacts)
+ {
content.PublishCulture(impact);
+ }
- var result = CommitDocumentChangesInternal(scope, content, evtMsgs, allLangs, savingNotification.State, userId, raiseEvents);
+ var result = CommitDocumentChangesInternal(scope, content, evtMsgs, allLangs, savingNotification.State, userId);
scope.Complete();
return result;
}
@@ -1067,7 +1068,7 @@ namespace Umbraco.Cms.Core.Services.Implement
/// The document is *always* saved, even when publishing fails.
///
internal PublishResult CommitDocumentChanges(IContent content,
- int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ int userId = Cms.Core.Constants.Security.SuperUserId)
{
using (var scope = ScopeProvider.CreateScope())
{
@@ -1083,7 +1084,7 @@ namespace Umbraco.Cms.Core.Services.Implement
var allLangs = _languageRepository.GetMany().ToList();
- var result = CommitDocumentChangesInternal(scope, content, evtMsgs, allLangs, savingNotification.State, userId, raiseEvents);
+ var result = CommitDocumentChangesInternal(scope, content, evtMsgs, allLangs, savingNotification.State, userId);
scope.Complete();
return result;
}
@@ -1097,7 +1098,6 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- ///
///
///
///
@@ -1111,8 +1111,8 @@ namespace Umbraco.Cms.Core.Services.Implement
private PublishResult CommitDocumentChangesInternal(IScope scope, IContent content,
EventMessages eventMessages, IReadOnlyCollection allLangs,
IDictionary notificationState,
- int userId = Cms.Core.Constants.Security.SuperUserId,
- bool raiseEvents = true, bool branchOne = false, bool branchRoot = false)
+ int userId = Constants.Security.SuperUserId,
+ bool branchOne = false, bool branchRoot = false)
{
if (scope == null)
{
@@ -1269,10 +1269,7 @@ namespace Umbraco.Cms.Core.Services.Implement
SaveDocument(content);
// raise the Saved event, always
- if (raiseEvents)
- {
- scope.Notifications.Publish(new ContentSavedNotification(content, eventMessages).WithState(notificationState));
- }
+ scope.Notifications.Publish(new ContentSavedNotification(content, eventMessages).WithState(notificationState));
if (unpublishing) // we have tried to unpublish - won't happen in a branch
{
@@ -2381,9 +2378,8 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- ///
/// Result indicating what action was taken when handling the command.
- public OperationResult Sort(IEnumerable items, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public OperationResult Sort(IEnumerable items, int userId = Cms.Core.Constants.Security.SuperUserId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -2394,7 +2390,7 @@ namespace Umbraco.Cms.Core.Services.Implement
{
scope.WriteLock(Cms.Core.Constants.Locks.ContentTree);
- var ret = Sort(scope, itemsA, userId, evtMsgs, raiseEvents);
+ var ret = Sort(scope, itemsA, userId, evtMsgs);
scope.Complete();
return ret;
}
@@ -2410,9 +2406,8 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- ///
/// Result indicating what action was taken when handling the command.
- public OperationResult Sort(IEnumerable ids, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public OperationResult Sort(IEnumerable ids, int userId = Cms.Core.Constants.Security.SuperUserId)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -2424,29 +2419,27 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.WriteLock(Cms.Core.Constants.Locks.ContentTree);
var itemsA = GetByIds(idsA).ToArray();
- var ret = Sort(scope, itemsA, userId, evtMsgs, raiseEvents);
+ var ret = Sort(scope, itemsA, userId, evtMsgs);
scope.Complete();
return ret;
}
}
- private OperationResult Sort(IScope scope, IContent[] itemsA, int userId, EventMessages eventMessages, bool raiseEvents)
+ private OperationResult Sort(IScope scope, IContent[] itemsA, int userId, EventMessages eventMessages)
{
var sortingNotification = new ContentSortingNotification(itemsA, eventMessages);
var savingNotification = new ContentSavingNotification(itemsA, eventMessages);
- if (raiseEvents)
- {
- // raise cancelable sorting event
- if (scope.Notifications.PublishCancelable(sortingNotification))
- {
- return OperationResult.Cancel(eventMessages);
- }
- // raise cancelable saving event
- if (scope.Notifications.PublishCancelable(savingNotification))
- {
- return OperationResult.Cancel(eventMessages);
- }
+ // raise cancelable sorting event
+ if (scope.Notifications.PublishCancelable(sortingNotification))
+ {
+ return OperationResult.Cancel(eventMessages);
+ }
+
+ // raise cancelable saving event
+ if (scope.Notifications.PublishCancelable(savingNotification))
+ {
+ return OperationResult.Cancel(eventMessages);
}
var published = new List();
@@ -2479,16 +2472,13 @@ namespace Umbraco.Cms.Core.Services.Implement
_documentRepository.Save(content);
}
- if (raiseEvents)
- {
- //first saved, then sorted
- scope.Notifications.Publish(new ContentSavedNotification(itemsA, eventMessages).WithStateFrom(savingNotification));
- scope.Notifications.Publish(new ContentSortedNotification(itemsA, eventMessages).WithStateFrom(sortingNotification));
- }
+ //first saved, then sorted
+ scope.Notifications.Publish(new ContentSavedNotification(itemsA, eventMessages).WithStateFrom(savingNotification));
+ scope.Notifications.Publish(new ContentSortedNotification(itemsA, eventMessages).WithStateFrom(sortingNotification));
scope.Notifications.Publish(new ContentTreeChangeNotification(saved, TreeChangeTypes.RefreshNode, eventMessages));
- if (raiseEvents && published.Any())
+ if (published.Any())
{
scope.Notifications.Publish(new ContentPublishedNotification(published, eventMessages));
}
diff --git a/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs b/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs
index b20be692df..50caca0ec8 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs
@@ -434,18 +434,7 @@ namespace Umbraco.Cms.Core.Services.Implement
///
/// to save
/// Id of the user issuing the save
- public void Save(IEnumerable dataTypeDefinitions, int userId = Cms.Core.Constants.Security.SuperUserId)
- {
- Save(dataTypeDefinitions, userId, true);
- }
-
- ///
- /// Saves a collection of
- ///
- /// to save
- /// Id of the user issuing the save
- /// Boolean indicating whether or not to raise events
- public void Save(IEnumerable dataTypeDefinitions, int userId, bool raiseEvents)
+ public void Save(IEnumerable dataTypeDefinitions, int userId)
{
var evtMsgs = EventMessagesFactory.Get();
var dataTypeDefinitionsA = dataTypeDefinitions.ToArray();
@@ -453,7 +442,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var savingDataTypeNotification = new DataTypeSavingNotification(dataTypeDefinitions, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingDataTypeNotification))
+ if (scope.Notifications.PublishCancelable(savingDataTypeNotification))
{
scope.Complete();
return;
@@ -465,10 +454,8 @@ namespace Umbraco.Cms.Core.Services.Implement
_dataTypeRepository.Save(dataTypeDefinition);
}
- if (raiseEvents)
- {
- scope.Notifications.Publish(new DataTypeSavedNotification(dataTypeDefinitions, evtMsgs).WithStateFrom(savingDataTypeNotification));
- }
+ scope.Notifications.Publish(new DataTypeSavedNotification(dataTypeDefinitions, evtMsgs).WithStateFrom(savingDataTypeNotification));
+
Audit(AuditType.Save, userId, -1);
scope.Complete();
diff --git a/src/Umbraco.Infrastructure/Services/Implement/MediaService.cs b/src/Umbraco.Infrastructure/Services/Implement/MediaService.cs
index 34d1c2a5ce..0239ad8e60 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/MediaService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/MediaService.cs
@@ -653,15 +653,14 @@ namespace Umbraco.Cms.Core.Services.Implement
///
/// The to save
/// Id of the User saving the Media
- /// Optional boolean indicating whether or not to raise events.
- public Attempt Save(IMedia media, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public Attempt Save(IMedia media, int userId = Cms.Core.Constants.Security.SuperUserId)
{
EventMessages eventMessages = EventMessagesFactory.Get();
using (IScope scope = ScopeProvider.CreateScope())
{
var savingNotification = new MediaSavingNotification(media, eventMessages);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return OperationResult.Attempt.Cancel(eventMessages);
@@ -685,10 +684,8 @@ namespace Umbraco.Cms.Core.Services.Implement
}
_mediaRepository.Save(media);
- if (raiseEvents)
- {
- scope.Notifications.Publish(new MediaSavedNotification(media, eventMessages).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new MediaSavedNotification(media, eventMessages).WithStateFrom(savingNotification));
+ // TODO: See note about suppressing events in content service
scope.Notifications.Publish(new MediaTreeChangeNotification(media, TreeChangeTypes.RefreshNode, eventMessages));
Audit(AuditType.Save, userId, media.Id);
@@ -703,8 +700,7 @@ namespace Umbraco.Cms.Core.Services.Implement
///
/// Collection of to save
/// Id of the User saving the Media
- /// Optional boolean indicating whether or not to raise events.
- public Attempt Save(IEnumerable medias, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public Attempt Save(IEnumerable medias, int userId = Cms.Core.Constants.Security.SuperUserId)
{
EventMessages messages = EventMessagesFactory.Get();
IMedia[] mediasA = medias.ToArray();
@@ -712,7 +708,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (IScope scope = ScopeProvider.CreateScope())
{
var savingNotification = new MediaSavingNotification(mediasA, messages);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return OperationResult.Attempt.Cancel(messages);
@@ -731,10 +727,8 @@ namespace Umbraco.Cms.Core.Services.Implement
_mediaRepository.Save(media);
}
- if (raiseEvents)
- {
- scope.Notifications.Publish(new MediaSavedNotification(mediasA, messages).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new MediaSavedNotification(mediasA, messages).WithStateFrom(savingNotification));
+ // TODO: See note about suppressing events in content service
scope.Notifications.Publish(new MediaTreeChangeNotification(treeChanges, messages));
Audit(AuditType.Save, userId == -1 ? 0 : userId, Cms.Core.Constants.System.Root, "Bulk save media");
@@ -1093,9 +1087,8 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- ///
/// True if sorting succeeded, otherwise False
- public bool Sort(IEnumerable items, int userId = Cms.Core.Constants.Security.SuperUserId, bool raiseEvents = true)
+ public bool Sort(IEnumerable items, int userId = Cms.Core.Constants.Security.SuperUserId)
{
IMedia[] itemsA = items.ToArray();
if (itemsA.Length == 0)
@@ -1108,7 +1101,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (IScope scope = ScopeProvider.CreateScope())
{
var savingNotification = new MediaSavingNotification(itemsA, messages);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return false;
@@ -1135,10 +1128,8 @@ namespace Umbraco.Cms.Core.Services.Implement
_mediaRepository.Save(media);
}
- if (raiseEvents)
- {
- scope.Notifications.Publish(new MediaSavedNotification(itemsA, messages).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new MediaSavedNotification(itemsA, messages).WithStateFrom(savingNotification));
+ // TODO: See note about suppressing events in content service
scope.Notifications.Publish(new MediaTreeChangeNotification(saved, TreeChangeTypes.RefreshNode, messages));
Audit(AuditType.Sort, userId, 0);
diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs
index 096ff164a0..9d68415ad5 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs
@@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
}
- public void Save(IMemberGroup memberGroup, bool raiseEvents = true)
+ public void Save(IMemberGroup memberGroup)
{
if (string.IsNullOrWhiteSpace(memberGroup.Name))
{
@@ -76,7 +76,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var savingNotification = new MemberGroupSavingNotification(memberGroup, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -85,10 +85,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_memberGroupRepository.Save(memberGroup);
scope.Complete();
- if (raiseEvents)
- {
- scope.Notifications.Publish(new MemberGroupSavedNotification(memberGroup, evtMsgs).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new MemberGroupSavedNotification(memberGroup, evtMsgs).WithStateFrom(savingNotification));
}
}
diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs
index 94476ff1e1..f6aac98682 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs
@@ -767,7 +767,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
///
- public void Save(IMember member, bool raiseEvents = true)
+ public void Save(IMember member)
{
// trimming username and email to make sure we have no trailing space
member.Username = member.Username.Trim();
@@ -778,7 +778,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (IScope scope = ScopeProvider.CreateScope())
{
var savingNotification = new MemberSavingNotification(member, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -793,10 +793,7 @@ namespace Umbraco.Cms.Core.Services.Implement
_memberRepository.Save(member);
- if (raiseEvents)
- {
- scope.Notifications.Publish(new MemberSavedNotification(member, evtMsgs).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new MemberSavedNotification(member, evtMsgs).WithStateFrom(savingNotification));
Audit(AuditType.Save, 0, member.Id);
@@ -805,7 +802,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
///
- public void Save(IEnumerable members, bool raiseEvents = true)
+ public void Save(IEnumerable members)
{
var membersA = members.ToArray();
@@ -814,7 +811,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var savingNotification = new MemberSavingNotification(membersA, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -831,10 +828,8 @@ namespace Umbraco.Cms.Core.Services.Implement
_memberRepository.Save(member);
}
- if (raiseEvents)
- {
- scope.Notifications.Publish(new MemberSavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new MemberSavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification));
+
Audit(AuditType.Save, 0, -1, "Save multiple Members");
scope.Complete();
diff --git a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs
index 743b4816da..0500c18bdd 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Globalization;
@@ -273,16 +273,14 @@ namespace Umbraco.Cms.Core.Services.Implement
/// Saves an
///
/// to Save
- /// Optional parameter to raise events.
- /// Default is True otherwise set to False to not raise events
- public void Save(IUser entity, bool raiseEvents = true)
+ public void Save(IUser entity)
{
var evtMsgs = EventMessagesFactory.Get();
using (var scope = ScopeProvider.CreateScope())
{
var savingNotification = new UserSavingNotification(entity, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -297,10 +295,7 @@ namespace Umbraco.Cms.Core.Services.Implement
try
{
_userRepository.Save(entity);
- if (raiseEvents)
- {
- scope.Notifications.Publish(new UserSavedNotification(entity, evtMsgs).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new UserSavedNotification(entity, evtMsgs).WithStateFrom(savingNotification));
scope.Complete();
}
@@ -321,9 +316,7 @@ namespace Umbraco.Cms.Core.Services.Implement
/// Saves a list of objects
///
/// to save
- /// Optional parameter to raise events.
- /// Default is True otherwise set to False to not raise events
- public void Save(IEnumerable entities, bool raiseEvents = true)
+ public void Save(IEnumerable entities)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -332,7 +325,7 @@ namespace Umbraco.Cms.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var savingNotification = new UserSavingNotification(entitiesA, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -350,10 +343,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
- if (raiseEvents)
- {
- scope.Notifications.Publish(new UserSavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification));
- }
+ scope.Notifications.Publish(new UserSavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification));
//commit the whole lot in one go
scope.Complete();
@@ -816,9 +806,8 @@ namespace Umbraco.Cms.Core.Services.Implement
/// If null than no changes are made to the users who are assigned to this group, however if a value is passed in
/// than all users will be removed from this group and only these users will be added
///
- /// Optional parameter to raise events.
/// Default is True otherwise set to False to not raise events
- public void Save(IUserGroup userGroup, int[] userIds = null, bool raiseEvents = true)
+ public void Save(IUserGroup userGroup, int[] userIds = null)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -843,7 +832,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// this is the default/expected notification for the IUserGroup entity being saved
var savingNotification = new UserGroupSavingNotification(userGroup, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification))
+ if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
@@ -851,7 +840,7 @@ namespace Umbraco.Cms.Core.Services.Implement
// this is an additional notification for special auditing
var savingUserGroupWithUsersNotification = new UserGroupWithUsersSavingNotification(userGroupWithUsers, evtMsgs);
- if (raiseEvents && scope.Notifications.PublishCancelable(savingUserGroupWithUsersNotification))
+ if (scope.Notifications.PublishCancelable(savingUserGroupWithUsersNotification))
{
scope.Complete();
return;
@@ -859,11 +848,8 @@ namespace Umbraco.Cms.Core.Services.Implement
_userGroupRepository.AddOrUpdateGroupWithUsers(userGroup, userIds);
- if (raiseEvents)
- {
- scope.Notifications.Publish(new UserGroupSavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification));
- scope.Notifications.Publish(new UserGroupWithUsersSavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification));
- }
+ scope.Notifications.Publish(new UserGroupSavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification));
+ scope.Notifications.Publish(new UserGroupWithUsersSavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification));
scope.Complete();
}
diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
index d759c8da9b..712323656d 100644
--- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
+++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
@@ -111,10 +111,6 @@
-
-
-
-
diff --git a/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs
index b9b3d0569e..d1f25a8f82 100644
--- a/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs
+++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs
@@ -1,11 +1,13 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
+using System;
using System.Linq;
using System.Threading;
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Models.Membership;
+using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
@@ -39,6 +41,9 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services
private IUser CreateTestUser()
{
+ using IScope scope = ScopeProvider.CreateScope(autoComplete: true);
+ using IDisposable _ = scope.Notifications.Suppress();
+
var globalSettings = new GlobalSettings();
var user = new User(globalSettings)
{
@@ -46,7 +51,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services
Username = "testUser",
Email = "testuser@test.com",
};
- UserService.Save(user, false);
+ UserService.Save(user);
var userGroupA = new UserGroup(ShortStringHelper)
{
@@ -57,7 +62,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services
userGroupA.AddAllowedSection("settings");
// TODO: This is failing the test
- UserService.Save(userGroupA, new[] { user.Id }, false);
+ UserService.Save(userGroupA, new[] { user.Id });
var userGroupB = new UserGroup(ShortStringHelper)
{
@@ -66,7 +71,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services
};
userGroupB.AddAllowedSection("settings");
userGroupB.AddAllowedSection("member");
- UserService.Save(userGroupB, new[] { user.Id }, false);
+ UserService.Save(userGroupB, new[] { user.Id });
return UserService.GetUserById(user.Id);
}
diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs
new file mode 100644
index 0000000000..c5cff66d0a
--- /dev/null
+++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Umbraco.
+// See LICENSE for more details.
+
+using System;
+using NUnit.Framework;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Notifications;
+using Umbraco.Cms.Core.Scoping;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Tests.Common.Builders;
+using Umbraco.Cms.Tests.Common.Testing;
+using Umbraco.Cms.Tests.Integration.Testing;
+
+namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping
+{
+ [TestFixture]
+ [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
+ public class SuppressNotificationsTests : UmbracoIntegrationTest
+ {
+ private IContentService ContentService => GetRequiredService();
+ private IContentTypeService ContentTypeService => GetRequiredService();
+ private IMediaTypeService MediaTypeService => GetRequiredService();
+ private IMediaService MediaService => GetRequiredService();
+
+ protected override void CustomTestSetup(IUmbracoBuilder builder)
+ {
+ base.CustomTestSetup(builder);
+
+ builder.AddNotificationHandler();
+ builder.AddNotificationHandler();
+ builder.AddNotificationHandler();
+ }
+
+ [Test]
+ public void GivenScope_WhenNotificationsSuppressed_ThenNotificationsDoNotExecute()
+ {
+ using IScope scope = ScopeProvider.CreateScope(autoComplete: true);
+ using IDisposable _ = scope.Notifications.Suppress();
+
+ ContentType contentType = ContentTypeBuilder.CreateBasicContentType();
+ ContentTypeService.Save(contentType);
+ Content content = ContentBuilder.CreateBasicContent(contentType);
+ ContentService.Save(content);
+ }
+
+ [Test]
+ public void GivenNestedScope_WhenOuterNotificationsSuppressed_ThenNotificationsDoNotExecute()
+ {
+ using (IScope parentScope = ScopeProvider.CreateScope(autoComplete: true))
+ {
+ using IDisposable _ = parentScope.Notifications.Suppress();
+
+ using (IScope childScope = ScopeProvider.CreateScope(autoComplete: true))
+ {
+ ContentType contentType = ContentTypeBuilder.CreateBasicContentType();
+ ContentTypeService.Save(contentType);
+ Content content = ContentBuilder.CreateBasicContent(contentType);
+ ContentService.Save(content);
+ }
+ }
+ }
+
+ [Test]
+ public void GivenSuppressedNotifications_WhenDisposed_ThenNotificationsExecute()
+ {
+ int asserted = 0;
+ using (IScope scope = ScopeProvider.CreateScope(autoComplete: true))
+ {
+ using IDisposable suppressed = scope.Notifications.Suppress();
+
+ MediaType mediaType = MediaTypeBuilder.CreateImageMediaType("test");
+ MediaTypeService.Save(mediaType);
+
+ suppressed.Dispose();
+
+ asserted = TestContext.CurrentContext.AssertCount;
+ Media media = MediaBuilder.CreateMediaImage(mediaType, -1);
+ MediaService.Save(media);
+ }
+
+ Assert.AreEqual(asserted + 1, TestContext.CurrentContext.AssertCount);
+ }
+
+ [Test]
+ public void GivenSuppressedNotificationsOnParent_WhenChildSuppresses_ThenExceptionIsThrown()
+ {
+ using (IScope parentScope = ScopeProvider.CreateScope(autoComplete: true))
+ using (IDisposable parentSuppressed = parentScope.Notifications.Suppress())
+ {
+ using (IScope childScope = ScopeProvider.CreateScope(autoComplete: true))
+ {
+ Assert.Throws(() => childScope.Notifications.Suppress());
+ }
+ }
+ }
+
+ private class TestContentNotificationHandler : INotificationHandler
+ {
+ public void Handle(ContentSavingNotification notification)
+ => Assert.Fail("Notification was sent");
+ }
+
+ private class TestMediaNotificationHandler : INotificationHandler
+ {
+ public void Handle(MediaSavedNotification notification)
+ => Assert.IsNotNull(notification);
+ }
+
+ private class TestContentTypeNotificationHandler : INotificationHandler
+ {
+ public void Handle(ContentTypeSavingNotification notification)
+ => Assert.Fail("Notification was sent");
+ }
+ }
+}
diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs
index f1d1af20c0..62b8456fc7 100644
--- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs
+++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/UserServiceTests.cs
@@ -23,6 +23,7 @@ using Umbraco.Extensions;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
{
+
///
/// Tests covering the UserService
///
diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberManagerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberManagerTests.cs
index fabe1f3a0c..05afd547e1 100644
--- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberManagerTests.cs
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberManagerTests.cs
@@ -246,7 +246,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
private void MockMemberServiceForCreateMember(IMember fakeMember)
{
_mockMemberService.Setup(x => x.CreateMember(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(fakeMember);
- _mockMemberService.Setup(x => x.Save(fakeMember, false));
+ _mockMemberService.Setup(x => x.Save(fakeMember));
}
}
}
diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs
index 412de11a9e..a82534c940 100644
--- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs
@@ -62,9 +62,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
IMemberGroup mockMemberGroup = Mock.Of(m =>
m.Name == "fakeGroupName" && m.CreatorId == 77);
- bool raiseEvents = false;
-
- _mockMemberGroupService.Setup(x => x.Save(mockMemberGroup, raiseEvents));
+ _mockMemberGroupService.Setup(x => x.Save(mockMemberGroup));
// act
IdentityResult identityResult = await sut.CreateAsync(fakeRole, fakeCancellationToken);
@@ -72,7 +70,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
// assert
Assert.IsTrue(identityResult.Succeeded);
Assert.IsTrue(!identityResult.Errors.Any());
- _mockMemberGroupService.Verify(x => x.Save(It.IsAny(), It.IsAny()));
+ _mockMemberGroupService.Verify(x => x.Save(It.IsAny()));
}
[Test]
@@ -86,10 +84,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
IMemberGroup mockMemberGroup = Mock.Of(m =>
m.Name == "fakeGroupName" && m.CreatorId == 777);
- bool raiseEvents = false;
-
_mockMemberGroupService.Setup(x => x.GetById(777)).Returns(mockMemberGroup);
- _mockMemberGroupService.Setup(x => x.Save(mockMemberGroup, raiseEvents));
+ _mockMemberGroupService.Setup(x => x.Save(mockMemberGroup));
// act
IdentityResult identityResult = await sut.UpdateAsync(fakeRole, fakeCancellationToken);
@@ -111,10 +107,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
IMemberGroup mockMemberGroup = Mock.Of(m =>
m.Name == "fakeGroupName" && m.CreatorId == 777);
- bool raiseEvents = false;
-
_mockMemberGroupService.Setup(x => x.GetById(777)).Returns(mockMemberGroup);
- _mockMemberGroupService.Setup(x => x.Save(mockMemberGroup, raiseEvents));
+ _mockMemberGroupService.Setup(x => x.Save(mockMemberGroup));
// act
IdentityResult identityResult = await sut.UpdateAsync(fakeRole, fakeCancellationToken);
@@ -122,7 +116,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
// assert
Assert.IsTrue(identityResult.Succeeded);
Assert.IsTrue(!identityResult.Errors.Any());
- _mockMemberGroupService.Verify(x => x.Save(It.IsAny(), It.IsAny()));
+ _mockMemberGroupService.Verify(x => x.Save(It.IsAny()));
_mockMemberGroupService.Verify(x => x.GetById(777));
}
diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberUserStoreTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberUserStoreTests.cs
index 96d25d4d04..db58239e5f 100644
--- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberUserStoreTests.cs
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberUserStoreTests.cs
@@ -90,7 +90,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
m.HasIdentity == false);
_mockMemberService.Setup(x => x.CreateMember(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockMember);
- _mockMemberService.Setup(x => x.Save(mockMember, It.IsAny()));
+ _mockMemberService.Setup(x => x.Save(mockMember));
// act
IdentityResult actual = await sut.CreateAsync(null);
@@ -118,10 +118,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
m.ContentTypeAlias == fakeMemberType.Alias &&
m.HasIdentity == true);
- bool raiseEvents = false;
-
_mockMemberService.Setup(x => x.CreateMember(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockMember);
- _mockMemberService.Setup(x => x.Save(mockMember, raiseEvents));
+ _mockMemberService.Setup(x => x.Save(mockMember));
// act
IdentityResult identityResult = await sut.CreateAsync(fakeUser, CancellationToken.None);
@@ -130,7 +128,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
Assert.IsTrue(identityResult.Succeeded);
Assert.IsTrue(!identityResult.Errors.Any());
_mockMemberService.Verify(x => x.CreateMember(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()));
- _mockMemberService.Verify(x => x.Save(mockMember, It.IsAny()));
+ _mockMemberService.Verify(x => x.Save(mockMember));
}
[Test]
@@ -175,9 +173,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
m.RawPasswordValue == "xyz" &&
m.SecurityStamp == "xyz");
- bool raiseEvents = false;
-
- _mockMemberService.Setup(x => x.Save(mockMember, raiseEvents));
+ _mockMemberService.Setup(x => x.Save(mockMember));
_mockMemberService.Setup(x => x.GetById(123)).Returns(mockMember);
// act
@@ -200,7 +196,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
Assert.AreEqual(fakeUser.SecurityStamp, mockMember.SecurityStamp);
Assert.AreNotEqual(DateTime.MinValue, mockMember.EmailConfirmedDate.Value);
- _mockMemberService.Verify(x => x.Save(mockMember, It.IsAny()));
+ _mockMemberService.Verify(x => x.Save(mockMember));
_mockMemberService.Verify(x => x.GetById(123));
_mockMemberService.Verify(x => x.ReplaceRoles(new[] { 123 }, new[] { "role1", "role2" }));
}
diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MemberControllerUnitTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MemberControllerUnitTests.cs
index cde267d7dc..2da13a4bed 100644
--- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MemberControllerUnitTests.cs
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/MemberControllerUnitTests.cs
@@ -417,7 +417,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.BackOffice.Controllers
Mock.Get(umbracoMembersUserManager)
.Verify(u => u.AddToRolesAsync(membersIdentityUser, new[] { roleName }));
Mock.Get(memberService)
- .Verify(m => m.Save(It.IsAny(), true));
+ .Verify(m => m.Save(It.IsAny()));
AssertMemberDisplayPropertiesAreEqual(memberDisplay, result.Value);
}