4

As the title mentions, I am looking for a way to unpublish an active item from all publishing targets, including web, when an item is archived from Master. I am aware the Archive item now button and the Set archive date are processed differently within Sitecore. To that effect, I have developed two different overrides. Both overrides will archive the item however the issue is, neither of these function 100% of the time for removing the item from the other publishing targets when the unpublish date has occurred. Is there an agent I am missing for the items to be unpublished from the other targets?

Here is the code I have for the Archive item now.

public class ArchivePublish : ArchiveItems
    {
        public const string workflowPubTargets = "{D9E44555-02A6-407A-B4FC-96B9026CAADD}";
        public const string stateTargetDatabase = "{39ECFD90-55D2-49D8-B513-99D15573DE41}";
        public override void Execute(ClientPipelineArgs args)
        {
            Assert.ArgumentNotNull((object)args, nameof(args));
            Database database = Factory.GetDatabase(args.Parameters["database"]);
            ListString listString = new ListString(args.Parameters["items"], '|');
            Archive archive = ArchiveManager.GetArchive("archive", database);
            if (database != null && archive != null)
                using (new TaskContext("ArchiveItems pipeline"))
                {
                    //Context.ClientPage.Modified = false;
                    foreach (string path in listString)
                    {
                        Item obj = database.GetItem(path);
                        if (obj != null)
                        {
                            obj.Editing.BeginEdit();
                            /// set unpublish date and publish change
                            obj[FieldIDs.UnpublishDate] = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ");
                            obj.Publishing.UnpublishDate = DateTime.UtcNow;
                            obj.Editing.EndEdit();
                            List<Database> publishingTargets = GetPubTargets(database);
                            /// Loop through each target, determine the database, and publish
                            Log.Audit($"Archive publishing: {string.Join(",", publishingTargets.Select(x => x.Name))} -" +
                                $" {database.Languages.Length} - {obj.Publishing.UnpublishDate}", this);
                            try
                            {
                                PublishManager.PublishItem(obj, publishingTargets.ToArray(),
                                    database.Languages, false, false);
                            }
                            catch (Exception ex)
                            {
                                Log.Error($"Issue unpublishing - {string.Join(",", publishingTargets.Select(x => x.Name))} - {ex.Message}",
                                    ex, this);
                            }
                            System.Threading.Thread.Sleep(2000);
                            Log.Audit((object)this, "Archive item: {0}", AuditFormatter.FormatItem(obj));
                            archive.ArchiveItem(obj);
                        }
                    }
                    string parameter = args.Parameters["message"];
                    if (string.IsNullOrEmpty(parameter))
                        return;
                    Context.ClientPage.SendMessage((object)this, parameter);
                }
        }
        private List<Database> GetPubTargets(Database database)
        {
            List<Database> tdbs = new List<Database>();
            try
            {
                Item targetParent = database.GetItem(ID.Parse(workflowPubTargets));
                ChildList pubTargets = targetParent.GetChildren(ChildListOptions.IgnoreSecurity);
                if (pubTargets != null && pubTargets.Count > 0)
                {
                    foreach (Item target in pubTargets)
                    {
                        try
                        {
                            if (target.Fields[stateTargetDatabase].HasValue)
                            {
                                tdbs.Add(Factory.GetDatabase(target.Fields[stateTargetDatabase].Value));
                            }
                        }
                        catch
                        {
                            Log.Error($"Error recognising publishing database: {target.Name}", "archive");
                        }
                    }
                }
            }
            catch
            {
                Log.Error($"Error with updating folder state", "archive");
            }
            return tdbs;
        }
    }

Here is the code I have for the Set archive date

public class ArchivePublishDateForm : ArchiveDateForm
    {
        public const string workflowPubTargets = "{D9E44555-02A6-407A-B4FC-96B9026CAADD}";
        public const string stateTargetDatabase = "{39ECFD90-55D2-49D8-B513-99D15573DE41}";
        protected override void OnOK(object sender, EventArgs args)
        {
            base.OnOK(sender, args);
            if (this.CurrentItem.Empty)
                return;
            using (new TaskContext("Archive Date pipeline"))
            {
                try
                {
                    DateTime? dtStruct = null;
                    if (!string.IsNullOrEmpty(this.ItemArchiveDate.Value))
                    {
                        dtStruct = DateUtil.ToUniversalTime(DateUtil.IsoDateToDateTime(this.ItemArchiveDate.Value));
                    }
                    Item directItem = Factory.GetDatabase("master").GetItem(this.CurrentItem.ID);
                    directItem.Editing.BeginEdit();
                    directItem[FieldIDs.UnpublishDate] = dtStruct.HasValue ?
                                    dtStruct.Value.ToString("yyyyMMddTHHmmssZ") : string.Empty;
                    directItem.Editing.EndEdit();
                    List<Database> publishingTargets = GetPubTargets(Factory.GetDatabase("master"));
                    try
                    {
                        try
                        {
                            PublishManager.PublishItem(directItem, publishingTargets.ToArray(),
                                directItem.Languages, false, false);
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Issue unpublishing - {string.Join(",", publishingTargets.Select(x => x.Name))} - {ex.Message}",
                                ex, this);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error($"Issue setting unpublish - {string.Join(",", publishingTargets.Select(x => x.Name))} - {ex.Message}",
                            ex, this);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error($"Issue setting unpublish date - {ex.Message}", ex, this);
                }
            }
        }
        private List<Database> GetPubTargets(Database database)
        {
            List<Database> tdbs = new List<Database>();
            try
            {
                Item targetParent = database.GetItem(ID.Parse(workflowPubTargets));
                ChildList pubTargets = targetParent.GetChildren(ChildListOptions.IgnoreSecurity);
                if (pubTargets != null && pubTargets.Count > 0)
                {
                    foreach (Item target in pubTargets)
                    {
                        try
                        {
                            if (target.Fields[stateTargetDatabase].HasValue)
                            {
                                tdbs.Add(Factory.GetDatabase(target.Fields[stateTargetDatabase].Value));
                            }
                        }
                        catch
                        {
                            Log.Error($"Error recognising publishing database: {target.Name}", "archive");
                        }
                    }
                }
            }
            catch
            {
                Log.Error($"Error with updating folder state", "archive");
            }
            return tdbs;
        }
    }

1 Answer 1

1

You shouldn't use any Thread.Sleep(2000) after calling PublishManager.PublishItem method.

Instead, get the handle var handle = PublishManager.PublishItem(...) and use PublishManager.WaitFor(handle) method.

This is the code which works for me:

using (new SecurityDisabler())
{
    var targets = PublishManager.GetPublishingTargets(item.Database)
        .Select(i => Database.GetDatabase(i[FieldIDs.PublishingTargetDatabase]))
        .ToArray();

    var languages = LanguageManager.GetLanguages(item.Database).ToArray();

    item.Editing.BeginEdit();
    item.Publishing.NeverPublish = true;
    item.Editing.EndEdit();

    var handle = PublishManager.PublishItem(item, targets, languages, false, false);
    PublishManager.WaitFor(handle);
}
2
  • I just tried this out and works very well for the Execute override of the Publish item now button however the Set archive date is still not having the item removed from the web database once the unpublish date has passed.
    – Nathan S
    Jul 8, 2020 at 12:29
  • I think there are 2 different things and 2 completely separate places in Sitecore, am I right? I guess it would be best if you just create another question and describe all the steps to reproduce the issue there.
    – Marek Musielak
    Jul 8, 2020 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.