Merge pull request #1371 from umbraco/temp-u4-8675

u4-8675
This commit is contained in:
Warren Buckley
2016-07-06 11:42:16 +01:00
committed by GitHub
5 changed files with 175 additions and 35 deletions

View File

@@ -29,6 +29,20 @@ namespace Umbraco.Core.Services
Func<IUser, string[], string> createSubject,
Func<IUser, string[], string> createBody);
/// <summary>
/// Sends the notifications for the specified user regarding the specified nodes and action.
/// </summary>
/// <param name="entities"></param>
/// <param name="operatingUser"></param>
/// <param name="action"></param>
/// <param name="actionName"></param>
/// <param name="http"></param>
/// <param name="createSubject"></param>
/// <param name="createBody"></param>
void SendNotifications(IUser operatingUser, IEnumerable<IUmbracoEntity> entities, string action, string actionName, HttpContextBase http,
Func<IUser, string[], string> createSubject,
Func<IUser, string[], string> createBody);
/// <summary>
/// Gets the notifications for the user
/// </summary>

View File

@@ -56,37 +56,88 @@ namespace Umbraco.Core.Services
Func<IUser, string[], string> createBody)
{
if ((entity is IContent) == false)
{
throw new NotSupportedException();
}
var content = (IContent) entity;
//we'll lazily get these if we need to send notifications
IEnumerable<IContent> allVersions = null;
var content = (IContent) entity;
// lazily get versions - into a list to ensure we can enumerate multiple times
List<IContent> allVersions = null;
int totalUsers;
var allUsers = _userService.GetAll(0, int.MaxValue, out totalUsers);
foreach (var u in allUsers)
foreach (var u in allUsers.Where(x => x.IsApproved))
{
if (u.IsApproved == false) continue;
var userNotifications = GetUserNotifications(u, content.Path).ToArray();
var userNotifications = GetUserNotifications(u, content.Path);
var notificationForAction = userNotifications.FirstOrDefault(x => x.Action == action);
if (notificationForAction != null)
if (notificationForAction == null) continue;
if (allVersions == null) // lazy load
allVersions = _contentService.GetVersions(entity.Id).ToList();
try
{
//lazy load versions if notifications are required
if (allVersions == null)
{
allVersions = _contentService.GetVersions(entity.Id);
}
SendNotification(operatingUser, u, content, allVersions,
actionName, http, createSubject, createBody);
_logger.Debug<NotificationService>(string.Format("Notification type: {0} sent to {1} ({2})",
action, u.Name, u.Email));
}
catch (Exception ex)
{
_logger.Error<NotificationService>("An error occurred sending notification", ex);
}
}
}
/// <summary>
/// Sends the notifications for the specified user regarding the specified node and action.
/// </summary>
/// <param name="entities"></param>
/// <param name="operatingUser"></param>
/// <param name="action"></param>
/// <param name="actionName"></param>
/// <param name="http"></param>
/// <param name="createSubject"></param>
/// <param name="createBody"></param>
/// <remarks>
/// Currently this will only work for Content entities!
/// </remarks>
public void SendNotifications(IUser operatingUser, IEnumerable<IUmbracoEntity> entities, string action, string actionName, HttpContextBase http,
Func<IUser, string[], string> createSubject,
Func<IUser, string[], string> createBody)
{
if ((entities is IEnumerable<IContent>) == false)
throw new NotSupportedException();
// ensure we can enumerate multiple times
var entitiesL = entities as List<IContent> ?? entities.Cast<IContent>().ToList();
// lazily get versions - into lists to ensure we can enumerate multiple times
var allVersionsDictionary = new Dictionary<int, List<IContent>>();
int totalUsers;
var allUsers = _userService.GetAll(0, int.MaxValue, out totalUsers);
foreach (var u in allUsers.Where(x => x.IsApproved))
{
var userNotifications = GetUserNotifications(u).ToArray();
foreach (var content in entitiesL)
{
var userNotificationsByPath = FilterUserNotificationsByPath(userNotifications, content.Path);
var notificationForAction = userNotificationsByPath.FirstOrDefault(x => x.Action == action);
if (notificationForAction == null) continue;
var allVersions = allVersionsDictionary.ContainsKey(content.Id) // lazy load
? allVersionsDictionary[content.Id]
: allVersionsDictionary[content.Id] = _contentService.GetVersions(content.Id).ToList();
try
{
SendNotification(
operatingUser, u, content,
allVersions,
SendNotification(operatingUser, u, content, allVersions,
actionName, http, createSubject, createBody);
_logger.Debug<NotificationService>(string.Format("Notification type: {0} sent to {1} ({2})", action, u.Name, u.Email));
_logger.Debug<NotificationService>(string.Format("Notification type: {0} sent to {1} ({2})",
action, u.Name, u.Email));
}
catch (Exception ex)
{
@@ -96,6 +147,7 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Gets the notifications for the user
/// </summary>
@@ -119,10 +171,20 @@ namespace Umbraco.Core.Services
/// </remarks>
public IEnumerable<Notification> GetUserNotifications(IUser user, string path)
{
var userNotifications = GetUserNotifications(user).ToArray();
var pathParts = path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
var result = userNotifications.Where(r => pathParts.InvariantContains(r.EntityId.ToString(CultureInfo.InvariantCulture))).ToList();
return result;
var userNotifications = GetUserNotifications(user);
return FilterUserNotificationsByPath(userNotifications, path);
}
/// <summary>
/// Filters a userNotifications collection by a path
/// </summary>
/// <param name="userNotifications"></param>
/// <param name="path"></param>
/// <returns></returns>
public IEnumerable<Notification> FilterUserNotificationsByPath(IEnumerable<Notification> userNotifications, string path)
{
var pathParts = path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
return userNotifications.Where(r => pathParts.InvariantContains(r.EntityId.ToString(CultureInfo.InvariantCulture))).ToList();
}
/// <summary>

View File

@@ -9,6 +9,7 @@ using Umbraco.Core.Services;
using umbraco;
using umbraco.BusinessLogic.Actions;
using umbraco.interfaces;
using System.Collections.Generic;
namespace Umbraco.Web
{
@@ -27,6 +28,16 @@ namespace Umbraco.Web
service.SendNotification(entity, action, UmbracoContext.Current);
}
internal static void SendNotification(this INotificationService service, IEnumerable<IUmbracoEntity> entities, IAction action, ApplicationContext applicationContext)
{
if (UmbracoContext.Current == null)
{
LogHelper.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext");
return;
}
service.SendNotification(entities, action, UmbracoContext.Current);
}
internal static void SendNotification(this INotificationService service, IUmbracoEntity entity, IAction action, UmbracoContext umbracoContext)
{
if (umbracoContext == null)
@@ -37,6 +48,16 @@ namespace Umbraco.Web
service.SendNotification(entity, action, umbracoContext, umbracoContext.Application);
}
internal static void SendNotification(this INotificationService service, IEnumerable<IUmbracoEntity> entities, IAction action, UmbracoContext umbracoContext)
{
if (umbracoContext == null)
{
LogHelper.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext");
return;
}
service.SendNotification(entities, action, umbracoContext, umbracoContext.Application);
}
internal static void SendNotification(this INotificationService service, IUmbracoEntity entity, IAction action, UmbracoContext umbracoContext, ApplicationContext applicationContext)
{
if (umbracoContext == null)
@@ -61,6 +82,30 @@ namespace Umbraco.Web
service.SendNotification(user, entity, action, umbracoContext, applicationContext);
}
internal static void SendNotification(this INotificationService service, IEnumerable<IUmbracoEntity> entities, IAction action, UmbracoContext umbracoContext, ApplicationContext applicationContext)
{
if (umbracoContext == null)
{
LogHelper.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext");
return;
}
var user = umbracoContext.Security.CurrentUser;
//if there is no current user, then use the admin
if (user == null)
{
LogHelper.Debug(typeof(NotificationServiceExtensions), "There is no current Umbraco user logged in, the notifications will be sent from the administrator");
user = applicationContext.Services.UserService.GetUserById(0);
if (user == null)
{
LogHelper.Warn(typeof(NotificationServiceExtensions), "Noticiations can not be sent, no admin user with id 0 could be resolved");
return;
}
}
service.SendNotification(user, entities, action, umbracoContext, applicationContext);
}
internal static void SendNotification(this INotificationService service, IUser sender, IUmbracoEntity entity, IAction action, UmbracoContext umbracoContext, ApplicationContext applicationContext)
{
if (sender == null) throw new ArgumentNullException("sender");
@@ -79,5 +124,24 @@ namespace Umbraco.Web
? ui.Text("notifications", "mailBody", strings, mailingUser)
: ui.Text("notifications", "mailBodyHtml", strings, mailingUser));
}
internal static void SendNotification(this INotificationService service, IUser sender, IEnumerable<IUmbracoEntity> entities, IAction action, UmbracoContext umbracoContext, ApplicationContext applicationContext)
{
if (sender == null) throw new ArgumentNullException("sender");
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
if (applicationContext == null) throw new ArgumentNullException("applicationContext");
applicationContext.Services.NotificationService.SendNotifications(
sender,
entities,
action.Letter.ToString(CultureInfo.InvariantCulture),
ui.Text("actions", action.Alias),
umbracoContext.HttpContext,
(mailingUser, strings) => ui.Text("notifications", "mailSubject", strings, mailingUser),
(mailingUser, strings) => UmbracoConfig.For.UmbracoSettings().Content.DisableHtmlEmail
? ui.Text("notifications", "mailBody", strings, mailingUser)
: ui.Text("notifications", "mailBodyHtml", strings, mailingUser));
}
}
}

View File

@@ -9,6 +9,7 @@ using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Services;
using umbraco;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core.Models;
namespace Umbraco.Web.Strategies
{
@@ -36,6 +37,9 @@ namespace Umbraco.Web.Strategies
//Send notifications for the update and created actions
ContentService.Saved += (sender, args) =>
{
var newEntities = new List<IContent>();
var updatedEntities = new List<IContent>();
//need to determine if this is updating or if it is new
foreach (var entity in args.SavedEntities)
{
@@ -43,16 +47,16 @@ namespace Umbraco.Web.Strategies
if (dirty.WasPropertyDirty("Id"))
{
//it's new
applicationContext.Services.NotificationService.SendNotification(
entity, ActionNew.Instance, applicationContext);
newEntities.Add(entity);
}
else
{
//it's updating
applicationContext.Services.NotificationService.SendNotification(
entity, ActionUpdate.Instance, applicationContext);
updatedEntities.Add(entity);
}
}
applicationContext.Services.NotificationService.SendNotification(newEntities, ActionNew.Instance, applicationContext);
applicationContext.Services.NotificationService.SendNotification(updatedEntities, ActionUpdate.Instance, applicationContext);
};
//Send notifications for the delete action

View File

@@ -173,16 +173,12 @@ namespace umbraco.presentation.webservices
private void SortContent(string[] ids, int parentId)
{
var contentService = base.ApplicationContext.Services.ContentService;
var sortedContent = new List<IContent>();
var contentService = ApplicationContext.Services.ContentService;
try
{
for (var i = 0; i < ids.Length; i++)
{
var id = int.Parse(ids[i]);
var c = contentService.GetById(id);
sortedContent.Add(c);
}
var intIds = ids.Select(int.Parse).ToArray();
var allContent = contentService.GetByIds(intIds).ToDictionary(x => x.Id, x => x);
var sortedContent = intIds.Select(x => allContent[x]);
// Save content with new sort order and update db+cache accordingly
var sorted = contentService.Sort(sortedContent);