We recently migrated from legacy publishing to publishing service. In Publishing service, "getItemReferences" pipeline decommissioned. So we have to seek the ways to publish related items. Hence, we have written a customized processor under "publishEndResultBatch" pipeline. Thanks for great article written by Vincent Lui. https://vincent-lui.medium.com/sitecore-publishing-service-the-good-the-bad-and-the-ugly-74a9c17c9e16
We are take the article as reference and built our logic under "publishEndResultBatch" pipeline. Related items are published.
But the problem is that every related item is publising in separate job that led to performance dip. For ex: If i have 50 related items for an item, 50 dedicated jobs scheduled in publishing service.
Can anybody came across these use cases. Please suggest the better way to publish all related items at one go along with context item.
Here is my code:
public class ProcessRelatedItems
{
private readonly IDatabaseFactory _databaseFactory;
private readonly IPublishingLog _publishingLog;
private readonly IServiceItem _publishedItem;
public ProcessRelatedItems() : this(new PublishingLogWrapper(), new DatabaseFactoryWrapper(new PublishingLogWrapper()), new PublishedItem()) { }
public ProcessRelatedItems(IPublishingLog publishingLog,IDatabaseFactory databaseFactory,IServiceItem publishedItem)
{
Condition.Requires(publishingLog, nameof(publishingLog)).IsNotNull();
Condition.Requires(databaseFactory, nameof(databaseFactory)).IsNotNull();
Condition.Requires(publishedItem, nameof(publishedItem)).IsNotNull();
_databaseFactory = databaseFactory;
_publishingLog = publishingLog;
_publishedItem = publishedItem;
}
public void Process(PublishEndResultBatchArgs args)
{
if (args.JobData.Metadata.Where(x => x.Key == "Publish.Options.IncludeRelatedItems").Select(i => i.Value).FirstOrDefault() == "True")
{
Assert.ArgumentNotNull((object)args, nameof(args));
_publishingLog.Debug("Processing Published Items and Transforming into a list of Published item");
ProcessPublishedItems(args);
}
}
public void ProcessPublishedItems(PublishEndResultBatchArgs args)
{
IEnumerable<SC.Data.Items.Item> itemReferences = null;
Database master = SC.Configuration.Factory.GetDatabase("master");
Database web = SC.Configuration.Factory.GetDatabase("web");
List<SC.Data.Items.Item> modifiedRelatedItems = new List<SC.Data.Items.Item>();
List<SC.Publishing.PublishOptions> publishingOptionsList = new List<SC.Publishing.PublishOptions>();
SC.Publishing.PublishOptions publishOptions = new SC.Publishing.PublishOptions(master, web, SC.Publishing.PublishMode.SingleItem, Context.Language, System.DateTime.Now);
bool parseItemId = ID.TryParse(args.JobData.ItemId, out ID itemId);
PublishItemContext publishitemcontext = new PublishItemContext(itemId, publishOptions);
SC.Data.Items.Item sourceItem = publishitemcontext.PublishHelper.GetSourceItem(itemId);
if (sourceItem == null)
return;
itemReferences = this.GetReferences(sourceItem, true);
var datasourceItems = itemReferences.Where(item => item.TemplateName == "Folder").ToList();
foreach (SC.Data.Items.Item relatedItem in datasourceItems)
{
SC.Publishing.PublishOptions publishRelatedItemsOptions = new SC.Publishing.PublishOptions(master, web, SC.Publishing.PublishMode.Smart, Context.Language, System.DateTime.Now)
{
Deep = true,
RootItem = relatedItem,
PublishRelatedItems = true
};
publishingOptionsList.Add(publishRelatedItemsOptions);
}
SC.Publishing.PublishOptions[] publishingOptionsArray = publishingOptionsList.ToArray();
if (publishingOptionsArray.Length > 0)
{
var publisher = SC.Publishing.PublishManager.Publish(publishingOptionsArray);
_publishedItem.PublishedStatus = true;
}
else
{
_publishedItem.PublishedStatus = false;
}
}
private IEnumerable<SC.Data.Items.Item> GetReferences(SC.Data.Items.Item item, bool sharedOnly)
{
Assert.ArgumentNotNull((object)item, nameof(item));
List<SC.Data.Items.Item> source = new List<SC.Data.Items.Item>();
ItemLink[] array = ((IEnumerable<ItemLink>)item.Links.GetValidLinks()).Where<ItemLink>((Func<ItemLink, bool>)(link => item.Database.Name.Equals(link.TargetDatabaseName, StringComparison.OrdinalIgnoreCase))).ToArray<ItemLink>();
if (sharedOnly)
{
array = ((IEnumerable<ItemLink>)array).Where<ItemLink>((Func<ItemLink, bool>)(link =>
{
SC.Data.Items.Item sourceItem = link.GetSourceItem();
if (sourceItem == null)
{
return false;
}
if (!ID.IsNullOrEmpty(link.SourceFieldID))
{
return sourceItem.Fields[link.SourceFieldID].Shared;
}
return true;
})).ToArray<ItemLink>();
}
foreach (SC.Data.Items.Item obj in ((IEnumerable<ItemLink>)array).Select<ItemLink, SC.Data.Items.Item>((Func<ItemLink, SC.Data.Items.Item>)(link => link.GetTargetItem())).Where<SC.Data.Items.Item>((Func<SC.Data.Items.Item, bool>)(relatedItem => relatedItem != null)).ToList<SC.Data.Items.Item>())
{
source.AddRange(PublishQueue.GetParents(obj));
source.Add(obj);
if (obj.HasChildren)
{
source.AddRange(obj.GetChildren());
}
}
return source.Distinct<SC.Data.Items.Item>((IEqualityComparer<SC.Data.Items.Item>)new ItemIdComparer());
}