2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core.Events;
|
|
|
|
|
using Umbraco.Cms.Core.Models;
|
2021-05-11 14:33:49 +02:00
|
|
|
using Umbraco.Cms.Core.Notifications;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core.PublishedCache;
|
2022-04-28 11:55:22 +01:00
|
|
|
using Umbraco.Cms.Core.Services;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core.Services.Changes;
|
2021-02-10 10:46:52 +01:00
|
|
|
using Umbraco.Cms.Infrastructure.PublishedCache.Persistence;
|
2021-02-09 13:32:34 +01:00
|
|
|
using Umbraco.Extensions;
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
namespace Umbraco.Cms.Infrastructure.PublishedCache;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Subscribes to Umbraco events to ensure nucache remains consistent with the source data
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PublishedSnapshotServiceEventHandler :
|
|
|
|
|
INotificationHandler<LanguageSavedNotification>,
|
|
|
|
|
INotificationHandler<MemberDeletingNotification>,
|
|
|
|
|
INotificationHandler<ContentRefreshNotification>,
|
|
|
|
|
INotificationHandler<MediaRefreshNotification>,
|
|
|
|
|
INotificationHandler<MemberRefreshNotification>,
|
|
|
|
|
INotificationHandler<ContentTypeRefreshedNotification>,
|
|
|
|
|
INotificationHandler<MediaTypeRefreshedNotification>,
|
|
|
|
|
INotificationHandler<MemberTypeRefreshedNotification>,
|
|
|
|
|
INotificationHandler<ScopedEntityRemoveNotification>
|
2020-12-09 22:43:49 +11:00
|
|
|
{
|
2022-06-20 09:21:08 +02:00
|
|
|
private readonly INuCacheContentService _publishedContentService;
|
|
|
|
|
private readonly IPublishedSnapshotService _publishedSnapshotService;
|
|
|
|
|
|
2020-12-21 16:44:50 +11:00
|
|
|
/// <summary>
|
2022-06-20 09:21:08 +02:00
|
|
|
/// Initializes a new instance of the <see cref="PublishedSnapshotServiceEventHandler" /> class.
|
2020-12-21 16:44:50 +11:00
|
|
|
/// </summary>
|
2022-06-20 09:21:08 +02:00
|
|
|
public PublishedSnapshotServiceEventHandler(
|
|
|
|
|
IPublishedSnapshotService publishedSnapshotService,
|
|
|
|
|
INuCacheContentService publishedContentService)
|
2020-12-09 22:43:49 +11:00
|
|
|
{
|
2022-06-20 09:21:08 +02:00
|
|
|
_publishedSnapshotService = publishedSnapshotService;
|
|
|
|
|
_publishedContentService = publishedContentService;
|
|
|
|
|
}
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
[Obsolete("Please use alternative constructor.")]
|
|
|
|
|
public PublishedSnapshotServiceEventHandler(
|
|
|
|
|
IRuntimeState runtime,
|
|
|
|
|
IPublishedSnapshotService publishedSnapshotService,
|
|
|
|
|
INuCacheContentService publishedContentService,
|
|
|
|
|
IContentService contentService,
|
|
|
|
|
IMediaService mediaService)
|
|
|
|
|
: this(publishedSnapshotService, publishedContentService)
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
public void Handle(ContentRefreshNotification notification) =>
|
|
|
|
|
_publishedContentService.RefreshContent(notification.Entity);
|
|
|
|
|
|
|
|
|
|
public void Handle(ContentTypeRefreshedNotification notification)
|
|
|
|
|
{
|
|
|
|
|
const ContentTypeChangeTypes types // only for those that have been refreshed
|
|
|
|
|
= ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther;
|
|
|
|
|
var contentTypeIds = notification.Changes.Where(x => x.ChangeTypes.HasTypesAny(types)).Select(x => x.Item.Id)
|
|
|
|
|
.ToArray();
|
|
|
|
|
if (contentTypeIds.Any())
|
2022-04-28 11:55:22 +01:00
|
|
|
{
|
2022-06-20 09:21:08 +02:00
|
|
|
_publishedSnapshotService.Rebuild(contentTypeIds);
|
2022-04-28 11:55:22 +01:00
|
|
|
}
|
2022-06-20 09:21:08 +02:00
|
|
|
}
|
2022-04-28 11:55:22 +01:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
// TODO: This should be a cache refresher call!
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// If a <see cref="ILanguage" /> is ever saved with a different culture, we need to rebuild all of the content nucache
|
|
|
|
|
/// database table
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Handle(LanguageSavedNotification notification)
|
|
|
|
|
{
|
|
|
|
|
// culture changed on an existing language
|
|
|
|
|
var cultureChanged = notification.SavedEntities.Any(x =>
|
|
|
|
|
!x.WasPropertyDirty(nameof(ILanguage.Id)) && x.WasPropertyDirty(nameof(ILanguage.IsoCode)));
|
|
|
|
|
if (cultureChanged)
|
2020-12-09 22:43:49 +11:00
|
|
|
{
|
2022-06-20 09:21:08 +02:00
|
|
|
// Rebuild all content for all content types
|
|
|
|
|
_publishedSnapshotService.Rebuild(Array.Empty<int>());
|
2020-12-09 22:43:49 +11:00
|
|
|
}
|
2022-06-20 09:21:08 +02:00
|
|
|
}
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
public void Handle(MediaRefreshNotification notification) =>
|
|
|
|
|
_publishedContentService.RefreshMedia(notification.Entity);
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
public void Handle(MediaTypeRefreshedNotification notification)
|
|
|
|
|
{
|
|
|
|
|
const ContentTypeChangeTypes types // only for those that have been refreshed
|
|
|
|
|
= ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther;
|
|
|
|
|
var mediaTypeIds = notification.Changes.Where(x => x.ChangeTypes.HasTypesAny(types)).Select(x => x.Item.Id)
|
|
|
|
|
.ToArray();
|
|
|
|
|
if (mediaTypeIds.Any())
|
2020-12-09 22:43:49 +11:00
|
|
|
{
|
2022-06-20 09:21:08 +02:00
|
|
|
_publishedSnapshotService.Rebuild(mediaTypeIds: mediaTypeIds);
|
2020-12-09 22:43:49 +11:00
|
|
|
}
|
2022-06-20 09:21:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Handle(MemberDeletingNotification notification) =>
|
|
|
|
|
_publishedContentService.DeleteContentItems(notification.DeletedEntities);
|
|
|
|
|
|
|
|
|
|
public void Handle(MemberRefreshNotification notification) =>
|
|
|
|
|
_publishedContentService.RefreshMember(notification.Entity);
|
2020-12-09 22:43:49 +11:00
|
|
|
|
2022-06-20 09:21:08 +02:00
|
|
|
public void Handle(MemberTypeRefreshedNotification notification)
|
|
|
|
|
{
|
|
|
|
|
const ContentTypeChangeTypes types // only for those that have been refreshed
|
|
|
|
|
= ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther;
|
|
|
|
|
var memberTypeIds = notification.Changes.Where(x => x.ChangeTypes.HasTypesAny(types)).Select(x => x.Item.Id)
|
|
|
|
|
.ToArray();
|
|
|
|
|
if (memberTypeIds.Any())
|
2020-12-09 22:43:49 +11:00
|
|
|
{
|
2022-06-20 09:21:08 +02:00
|
|
|
_publishedSnapshotService.Rebuild(memberTypeIds: memberTypeIds);
|
2020-12-09 22:43:49 +11:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-20 09:21:08 +02:00
|
|
|
|
|
|
|
|
// note: if the service is not ready, ie _isReady is false, then we still handle repository events,
|
|
|
|
|
// because we can, we do not need a working published snapshot to do it - the only reason why it could cause an
|
|
|
|
|
// issue is if the database table is not ready, but that should be prevented by migrations.
|
|
|
|
|
|
|
|
|
|
// we need them to be "repository" events ie to trigger from within the repository transaction,
|
|
|
|
|
// because they need to be consistent with the content that is being refreshed/removed - and that
|
|
|
|
|
// should be guaranteed by a DB transaction
|
|
|
|
|
public void Handle(ScopedEntityRemoveNotification notification) =>
|
|
|
|
|
_publishedContentService.DeleteContentItem(notification.Entity);
|
2020-12-09 22:43:49 +11:00
|
|
|
}
|