Skip to content

Instantly share code, notes, and snippets.

@jraps20
Last active May 2, 2022 17:40
Show Gist options
  • Save jraps20/638312ea825f9a5ca5ee8da2c6ff92c1 to your computer and use it in GitHub Desktop.
Save jraps20/638312ea825f9a5ca5ee8da2c6ff92c1 to your computer and use it in GitHub Desktop.
Sitecore publishing Utils to quickly queue up a batch of items to a publish queue and publish the queue, as opposed to individual publishes which cause the publish:end event to fire multiple times (read: individual index updates, cache clearing, etc.)
public static class PublishUtils
{
public static void CreateAndPublishQueue(Database sourceDatabase, Database[] targetDatabases, Language[] targetLanguages, IEnumerable<ID> itemIds, bool skipEvents = false, bool useSecurityDisabler = true)
{
Assert.IsNotNull(sourceDatabase, "sourceDatabase");
Assert.IsNotNull(targetDatabases, "targetDatabases");
Assert.IsNotNull(targetLanguages, "targetLanguages");
var publishingCandidates = SetPublishingCandidates(sourceDatabase, targetDatabases, targetLanguages, itemIds);
ProcessCandidates(sourceDatabase, targetDatabases, targetLanguages, publishingCandidates, skipEvents, useSecurityDisabler);
}
private static List<PublishingCandidate> SetPublishingCandidates(Database sourceDatabase, Database[] targetDatabases, Language[] targetLanguages, IEnumerable<ID> itemIds)
{
var publishingCandidates = new List<PublishingCandidate>();
foreach (var itemId in itemIds)
{
publishingCandidates.AddRange(CreatePublishingCandidatesFromItemId(sourceDatabase, targetDatabases, targetLanguages, itemId));
}
return publishingCandidates;
}
public static List<PublishingCandidate> CreatePublishingCandidatesFromItemId(Database sourceDatabase, Database[] targetDatabases, Language[] targetLanguages, ID itemId)
{
if (sourceDatabase == null)
{
Log.Info("sourceDatabase == null", new object());
return Enumerable.Empty<PublishingCandidate>().ToList();
}
if (targetDatabases == null)
{
Log.Info("targetDatabases == null", new object());
return Enumerable.Empty<PublishingCandidate>().ToList();
}
if (targetLanguages == null)
{
Log.Info("targetLanguages == null", new object());
return Enumerable.Empty<PublishingCandidate>().ToList();
}
var publishingCandidates = new List<PublishingCandidate>();
var item = sourceDatabase.GetItem(itemId);
if (item == null)
{
Log.Info("item == null", new object());
return Enumerable.Empty<PublishingCandidate>().ToList();
}
foreach (var publishingTargetDatabase in targetDatabases.Where(tDb => tDb != null))
{
foreach (var publishingTargetLanguage in targetLanguages.Where(lang => lang != null))
{
var publishOptions = new PublishOptions(
Database.GetDatabase("master"),
publishingTargetDatabase,
PublishMode.Full,
publishingTargetLanguage,
DateTime.Now)
{
CompareRevisions = false
};
publishingCandidates.Add(new PublishingCandidate(itemId, publishOptions));
Log.Info($"Added item {item.Paths.FullPath} to the publish queue, target language: {publishingTargetLanguage}, targetDatabase: {publishingTargetDatabase}", new object());
}
}
return publishingCandidates;
}
public static void ProcessCandidates(Database sourceDatabase, Database[] targetDatabases, Language[] targetLanguages, List<PublishingCandidate> publishingCandidates, bool skipEvents = false, bool useSecurityDisabler = true)
{
Assert.IsNotNull(sourceDatabase, "sourceDatabase");
Assert.IsNotNull(targetDatabases, "targetDatabases");
Assert.IsNotNull(targetLanguages, "targetLanguages");
Log.Info($"{publishingCandidates.Count} items added to publish queue", new object());
var triggerDatabase = targetDatabases.First();
var triggerLanguage = targetLanguages.First();
var defaultPublishOptions = new PublishOptions(
sourceDatabase,
triggerDatabase, // need to pass database to satisfy contructor
PublishMode.Full,
triggerLanguage, // need to pass language to satisfy contructor
DateTime.Now)
{
CompareRevisions = false
};
var publishContext = PublishManager.CreatePublishContext(defaultPublishOptions);
// required or null exception thrown
publishContext.Languages = targetLanguages;
publishContext.Queue.Add(publishingCandidates);
if (skipEvents)
{
var queue = new ProcessQueue();
Log.Info("Processing Publish Queue, skipEvents = true", new object());
if (useSecurityDisabler)
{
Log.Info("Processing Publish Queue, security disabled", new object());
using (new SecurityDisabler())
queue.Process(publishContext);
}
else
{
Log.Info("Processing Publish Queue, security enabled", new object());
queue.Process(publishContext);
}
}
else
{
Log.Info("Processing Publish Queue, skipEvents = false", new object());
if (useSecurityDisabler)
{
Log.Info("Processing Publish Queue, security disabled", new object());
using (new SecurityDisabler())
CorePipeline.Run("publish", publishContext);
}
else
{
Log.Info("Processing Publish Queue, security enabled", new object());
CorePipeline.Run("publish", publishContext);
}
Log.Info("Raising publish:end event", new object());
global::Sitecore.Events.Event.RaiseEvent("publish:end", new Publisher(defaultPublishOptions));
Log.Info("Raising publish:end:remote event", new object());
global::Sitecore.Events.Event.RaiseEvent("publish:end:remote", new Publisher(defaultPublishOptions));
}
Log.Info("Finished processing Publish Queue", new object());
}
}
@marcelgruber
Copy link

Note: this will also publish the top level sitecore item.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment