Merge branch 'U4-8675' of https://github.com/benjaminketron/Umbraco-CMS into temp-u4-8675

This commit is contained in:
Stephan
2016-07-05 10:30:53 +02:00
5 changed files with 181 additions and 12 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 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>
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

@@ -96,6 +96,80 @@ namespace Umbraco.Core.Services
}
}
/// <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();
}
//we'll lazily get these if we need to send notifications
Dictionary<int, IEnumerable<IContent>> allVersionsDictionary = new Dictionary<int, IEnumerable<IContent>>();
int totalUsers;
var allUsers = _userService.GetAll(0, int.MaxValue, out totalUsers);
foreach (var u in allUsers)
{
if (u.IsApproved == false) continue;
var userNotifications = GetUserNotifications(u).ToArray();
foreach (var entity in entities)
{
var content = (IContent) entity;
var userNotificationsByPath = FilterUserNotificationsByPath(userNotifications, content.Path);
var notificationForAction = userNotificationsByPath
.FirstOrDefault(x => x.Action == action);
if (notificationForAction != null)
{
IEnumerable<IContent> allVersions = null;
if (allVersionsDictionary.ContainsKey(entity.Id))
{
allVersions = allVersionsDictionary[entity.Id];
}
//lazy load versions if notifications are required
if (allVersions == null)
{
allVersions = _contentService.GetVersions(entity.Id);
allVersionsDictionary[entity.Id] = allVersions;
}
try
{
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>
/// Gets the notifications for the user
/// </summary>
@@ -120,11 +194,22 @@ namespace Umbraco.Core.Services
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();
var result = FilterUserNotificationsByPath(userNotifications, path);
return result;
}
/// <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);
var result = userNotifications.Where(r => pathParts.InvariantContains(r.EntityId.ToString(CultureInfo.InvariantCulture))).ToList();
return result;
}
/// <summary>
/// Deletes notifications by entity
/// </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

@@ -177,13 +177,15 @@ namespace umbraco.presentation.webservices
var sortedContent = new List<IContent>();
try
{
for (var i = 0; i < ids.Length; i++)
{
var id = int.Parse(ids[i]);
var c = contentService.GetById(id);
sortedContent.Add(c);
}
int [] intIds = ids.Select(id => int.Parse(id)).ToArray();
sortedContent = contentService.GetByIds(intIds).ToList();
sortedContent = (from id in intIds
join content in sortedContent
on id equals content.Id
select content).ToList();
// Save content with new sort order and update db+cache accordingly
var sorted = contentService.Sort(sortedContent);