Support notifications for multiple root nodes (#13805)
This commit is contained in:
@@ -76,7 +76,8 @@ public class NotificationService : INotificationService
|
|||||||
Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject,
|
Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject,
|
||||||
Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody)
|
Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody)
|
||||||
{
|
{
|
||||||
var entitiesL = entities.ToList();
|
// sort the entities explicitly by path to handle notification inheritance (see comment below)
|
||||||
|
var entitiesL = entities.OrderBy(entity => entity.Path).ToList();
|
||||||
|
|
||||||
// exit if there are no entities
|
// exit if there are no entities
|
||||||
if (entitiesL.Count == 0)
|
if (entitiesL.Count == 0)
|
||||||
@@ -84,11 +85,11 @@ public class NotificationService : INotificationService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// put all entity's paths into a list with the same indices
|
// create a dictionary of entity paths by entity ID
|
||||||
var paths = entitiesL.Select(x =>
|
var pathsByEntityId = entitiesL.ToDictionary(
|
||||||
x.Path.Split(Constants.CharArrays.Comma).Select(s => int.Parse(s, CultureInfo.InvariantCulture))
|
entity => entity.Id,
|
||||||
.ToArray())
|
entity => entity.Path.Split(Constants.CharArrays.Comma)
|
||||||
.ToArray();
|
.Select(s => int.Parse(s, CultureInfo.InvariantCulture)).ToArray());
|
||||||
|
|
||||||
// lazily get versions
|
// lazily get versions
|
||||||
var prevVersionDictionary = new Dictionary<int, IContentBase?>();
|
var prevVersionDictionary = new Dictionary<int, IContentBase?>();
|
||||||
@@ -106,47 +107,32 @@ public class NotificationService : INotificationService
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
foreach (IUser user in users)
|
foreach (IUser user in users)
|
||||||
{
|
{
|
||||||
// continue if there's no notification for this user
|
Notification[] userNotifications = notifications.Where(n => n.UserId == user.Id).ToArray();
|
||||||
if (notifications[i].UserId != user.Id)
|
foreach (Notification notification in userNotifications)
|
||||||
{
|
{
|
||||||
continue; // next user
|
// notifications are inherited down the tree - find the topmost entity
|
||||||
}
|
// relevant to this notification (entity list is sorted by path)
|
||||||
|
IContent? entityForNotification = entitiesL
|
||||||
|
.FirstOrDefault(entity =>
|
||||||
|
pathsByEntityId.TryGetValue(entity.Id, out var path) &&
|
||||||
|
path.Contains(notification.EntityId));
|
||||||
|
|
||||||
for (var j = 0; j < entitiesL.Count; j++)
|
if (entityForNotification == null)
|
||||||
{
|
|
||||||
IContent content = entitiesL[j];
|
|
||||||
var path = paths[j];
|
|
||||||
|
|
||||||
// test if the notification applies to the path ie to this entity
|
|
||||||
if (path.Contains(notifications[i].EntityId) == false)
|
|
||||||
{
|
{
|
||||||
continue; // next entity
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevVersionDictionary.ContainsKey(content.Id) == false)
|
if (prevVersionDictionary.ContainsKey(entityForNotification.Id) == false)
|
||||||
{
|
{
|
||||||
prevVersionDictionary[content.Id] = GetPreviousVersion(content.Id);
|
prevVersionDictionary[entityForNotification.Id] = GetPreviousVersion(entityForNotification.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue notification
|
// queue notification
|
||||||
NotificationRequest req = CreateNotificationRequest(operatingUser, user, content, prevVersionDictionary[content.Id], actionName, siteUri, createSubject, createBody);
|
NotificationRequest req = CreateNotificationRequest(operatingUser, user, entityForNotification, prevVersionDictionary[entityForNotification.Id], actionName, siteUri, createSubject, createBody);
|
||||||
Enqueue(req);
|
Enqueue(req);
|
||||||
}
|
break;
|
||||||
|
|
||||||
// skip other notifications for this user, essentially this means moving i to the next index of notifications
|
|
||||||
// for the next user.
|
|
||||||
do
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (i < notifications.Count && notifications[i].UserId == user.Id);
|
|
||||||
|
|
||||||
if (i >= notifications.Count)
|
|
||||||
{
|
|
||||||
break; // break if no more notifications
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user