Skip to content

Instantly share code, notes, and snippets.

@jraps20
Created January 12, 2023 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jraps20/bebffde5dcb713479f8e057413c4424f to your computer and use it in GitHub Desktop.
Save jraps20/bebffde5dcb713479f8e057413c4424f to your computer and use it in GitHub Desktop.
namespace Foundation.Search.Crawlers
{
using System;
using Microsoft.Extensions.DependencyInjection;
using Sitecore;
using Sitecore.Abstractions;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Events;
using Sitecore.Data.Items;
using Sitecore.Data.LanguageFallback;
using Sitecore.DependencyInjection;
using Sitecore.Diagnostics;
using Sitecore.ExperienceEdge.Connector.Abstraction.DirectPublishing;
/// <summary>
/// This crawler mimics the behavior of the familiar Content Editor Warning
///
/// e.g. "If you publish now, the selected version will not be visible on the Web site because it has been replaced by an older version."
///
/// This crawler only indexes item versions that are in a publishable state. The same logic is used when publishing content to Edge and thus
/// the index and Edge remain in sync.
/// </summary>
public class EdgeItemCrawler : Sitecore.ContentSearch.SitecoreItemCrawler
{
/// <summary>
/// This is confirmed to also be a singleton, thus this class is as well
/// </summary>
private readonly IItemPublishingManager itemPublishManager;
private const string EdgePublishingTargetId = "{3013BEED-71CA-4DE3-A1D2-17DD871597F1}";
public EdgeItemCrawler()
{
this.itemPublishManager = ServiceLocator.ServiceProvider.GetService<IItemPublishingManager>();
}
protected override void DoAdd(IProviderUpdateContext context, SitecoreIndexableItem indexable)
{
Assert.ArgumentNotNull(context, nameof(context));
Assert.ArgumentNotNull(indexable, nameof(indexable));
using (new LanguageFallbackItemSwitcher(context.Index.EnableItemLanguageFallback))
{
this.Index.Locator.GetInstance<BaseEventManager>().RaiseEvent(new AddingIndexingEvent().WithIndexName(context.Index.Name).WithUniqueId(indexable.UniqueId).WithPath(indexable.AbsolutePath));
if (!this.IsExcludedFromIndex(indexable))
{
foreach (var language in indexable.Item.Languages)
{
// delete by "groupId" to remove all versions of the item
base.Delete(context, indexable.UniqueId.GroupId);
if (indexable.Item?.Versions == null)
{
continue;
}
var latestVersion = this.itemPublishManager.GetPublishableVersion(indexable.Item, new Sitecore.Data.ID(EdgePublishingTargetId), false);
if (latestVersion == null)
{
continue;
}
indexable = latestVersion;
// add the single, publishable version
this.Operations.Add(indexable, context, this.index.Configuration);
}
}
this.Index.Locator.GetInstance<BaseEventManager>().RaiseEvent(new AddedIndexingEvent().WithIndexName(context.Index.Name).WithUniqueId(indexable.UniqueId).WithPath(indexable.AbsolutePath));
}
}
protected override void DoUpdate(IProviderUpdateContext context, SitecoreIndexableItem indexable, IndexEntryOperationContext operationContext)
{
Assert.ArgumentNotNull(context, "context");
Assert.ArgumentNotNull(indexable, "indexable");
if (indexable.Item?.Versions == null)
{
return;
}
var latestVersion = this.itemPublishManager.GetPublishableVersion(indexable.Item, new Sitecore.Data.ID(EdgePublishingTargetId), false);
if (latestVersion == null)
{
return;
}
base.Delete(context, indexable.UniqueId.GroupId);
if (operationContext != null)
{
operationContext.NeedUpdatePreviousVersion = false;
operationContext.NeedUpdateAllVersions = false;
}
base.DoUpdate(context, (SitecoreIndexableItem)latestVersion, operationContext);
}
public override void Update(IProviderUpdateContext context, IIndexableUniqueId indexableUniqueId, IndexEntryOperationContext operationContext, IndexingOptions indexingOptions = IndexingOptions.Default)
{
var item = this.GetItem(indexableUniqueId as SitecoreItemUniqueId);
if (item?.Versions == null)
{
return;
}
var latestVersion = this.itemPublishManager.GetPublishableVersion(item, new Sitecore.Data.ID(EdgePublishingTargetId), false);
if (latestVersion == null)
{
return;
}
base.Delete(context, indexableUniqueId.GroupId);
if (operationContext != null)
{
operationContext.NeedUpdatePreviousVersion = false;
operationContext.NeedUpdateAllVersions = false;
}
base.Update(context, ((SitecoreIndexableItem)latestVersion).UniqueId, operationContext, indexingOptions);
}
public override void Update(IProviderUpdateContext context, IIndexableUniqueId indexableUniqueId, IndexingOptions indexingOptions = IndexingOptions.Default)
{
var item = this.GetItem(indexableUniqueId as SitecoreItemUniqueId);
if (item?.Versions == null)
{
return;
}
var latestVersion = this.itemPublishManager.GetPublishableVersion(item, new Sitecore.Data.ID(EdgePublishingTargetId), false);
if (latestVersion == null)
{
return;
}
base.Delete(context, indexableUniqueId.GroupId);
base.Update(context, ((SitecoreIndexableItem)latestVersion).UniqueId, indexingOptions);
}
protected override void UpdateItemVersion(IProviderUpdateContext context, Item version, IndexEntryOperationContext operationContext)
{
// item has a workflow defined, but no value for workflow state, do not index
if (!String.IsNullOrEmpty(version[FieldIDs.DefaultWorkflow]) && String.IsNullOrEmpty(version[FieldIDs.WorkflowState]))
{
return;
}
if (version == null)
{
return;
}
var latestVersion = this.itemPublishManager.GetPublishableVersion(version, new Sitecore.Data.ID(EdgePublishingTargetId), false);
if (latestVersion == null)
{
return;
}
var indexable = (SitecoreIndexableItem)latestVersion;
// delete all versions of the item
base.Delete(context, indexable.UniqueId.GroupId);
// index only the publishable version
if (operationContext != null)
{
operationContext.NeedUpdatePreviousVersion = false;
operationContext.NeedUpdateAllVersions = false;
}
base.UpdateItemVersion(context, latestVersion, operationContext);
}
public override void Delete(
IProviderUpdateContext context,
IIndexableUniqueId indexableUniqueId,
IndexingOptions indexingOptions = IndexingOptions.Default)
{
if (!this.ShouldStartIndexing(indexingOptions))
{
return;
}
var item = this.GetItem(indexableUniqueId as SitecoreItemUniqueId);
if (item?.Versions == null)
{
return;
}
var latestVersion = this.itemPublishManager.GetPublishableVersion(item, new Sitecore.Data.ID(EdgePublishingTargetId), false);
base.Delete(context, indexableUniqueId.GroupId);
if (latestVersion == null)
{
return;
}
base.Update(context, ((SitecoreIndexableItem)latestVersion).UniqueId, indexingOptions);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment