8

We're on Sitecore 8.2.
We have recently moved from Sitecore 6.6 to 8.2.

In Sitecore 6.6, if the parent item is marked as "Never publish" I get a warning in Content Editor on that item saying "This item will never be published because its "Publishable" option is disabled.".
I also get a warning on all of its descendants, saying "If you publish now, the selected version will not be visible on the Web site. No other version will be published.". Descendant item does not have "Never publish" marked, but I'm still getting a warning because one of its ascendants up the tree has "Never publish" marked. And that's fine, I really like that feature.

However, in Sitecore 8.2 I'm getting the warning only on the parent item. There is no warning on its descendants.

In Sitecore 6.6 I found that Sitecore.Pipelines.GetContentEditorWarnings.VersionPublishingRestricted is responsible for generating that message and I can see that at one point it calls obj.Publishing.IsPublishable(now, true);. The second parameter "true" causes that function to check if ancestors are publishable too, which is a desired functionality.

But when I look at VersionPublishingRestricted pipeline in Sitecore 8.2 I see it's very different and can't really be compared directly to 6.6 code.

Sitecore 8.2 processor looks like this:

namespace Sitecore.Pipelines.GetContentEditorWarnings
{
  public class VersionPublishingRestricted
  {
    public void Process(GetContentEditorWarningsArgs args)
    {
      Assert.ArgumentNotNull((object) args, "args");
      Item obj = args.Item;
      if (obj == null || PublishingInformationBuilder.GetPublishingInformation(obj, PublishingInformationLevel.Item).OfType<Sitecore.Publishing.Explanations.Error>().Any<Sitecore.Publishing.Explanations.Error>() || obj.Versions.GetVersions(false).Length == 0)
        return;
      Sitecore.Publishing.Explanations.Error[] array = PublishingInformationBuilder.GetPublishingInformation(obj, PublishingInformationLevel.Version).OfType<Sitecore.Publishing.Explanations.Error>().ToArray<Sitecore.Publishing.Explanations.Error>();
      Sitecore.Publishing.Explanations.Error error1 = ((IEnumerable<Sitecore.Publishing.Explanations.Error>) array).FirstOrDefault<Sitecore.Publishing.Explanations.Error>();
      if (error1 == null)
        return;
      GetContentEditorWarningsArgs.ContentEditorWarning warning = args.Add();
      warning.Title = error1.Message;
      warning.Text = error1.Remarks;
      VersionNotInFinalWorkflowStepError error2 = error1 as VersionNotInFinalWorkflowStepError;
      bool flag = false;
      if (error2 == null)
      {
        flag = true;
        error2 = array.OfType<VersionNotInFinalWorkflowStepError>().FirstOrDefault<VersionNotInFinalWorkflowStepError>();
      }
      if (error2 == null)
        return;
      if (flag && error2.Remarks != null && (warning.Text != null && warning.Text.IndexOf(error2.Remarks, StringComparison.InvariantCultureIgnoreCase) < 0))
      {
        GetContentEditorWarningsArgs.ContentEditorWarning contentEditorWarning = warning;
        string str = contentEditorWarning.Text + " " + error2.Remarks;
        contentEditorWarning.Text = str;
      }
      this.AddOptions(warning, error2);
    }

    private void AddOptions(GetContentEditorWarningsArgs.ContentEditorWarning warning, VersionNotInFinalWorkflowStepError error)
    {
      foreach (string header in (IEnumerable<string>) error.TargetsList.OrderBy<string, string>((Func<string, string>) (x => x), (IComparer<string>) StringComparer.InvariantCultureIgnoreCase))
        warning.AddOption(header);
    }
  }
}

I can see it's calling PublishingInformationBuilder.GetPublishingInformation two times. First it calls it inside IF, to see if there are any errors at all, and the second time it calls it to fetch the array of errors.
The difference is that the first time it's sending PublishingInformationLevel.Item as parameter value, and the second time it's sending PublishingInformationLevel.Version.
When I go to the source of PublishingInformationBuilder.GetPublishingInformation I can see that if it's called for the Version then it actually has a code for checking ancestors (it calls version.Publishing.IsPublishable(utcNow, true);), and if it's called for the Item then it doesn't do that.

So, I suspect that this might be a bug, that PublishingInformationBuilder.GetPublishingInformation should be called with PublishingInformationLevel.Version both times in this pipeline processor.

My next step will be to copy that standard processor into my own processor and try to fix the bug, but I just wanted to first see if anyone here has encountered this and perhaps already has a fix for it.

  • Could you please clarify what your question is? – Dmytro Shevchenko Dec 1 '16 at 16:32
  • I want to get a warning in content editor that the item is not publishable because one of its ancestors (parent or higher up the tree) is marked as not publishable. This feature was available in Sitecore 6.6 out of the box, and I suspect that Sitecore 8.2 has a bug in that feature. I'm trying to find out if anyone else has encountered this problem. – Dalibor Kovač Dec 1 '16 at 16:35
  • This sounds like a bug. If I were you, I'd reach out to Sitecore support. – sestocker Dec 1 '16 at 19:13
1

Upon further research I found that the problem is not in the value of parameter (Item vs Version). The code in VersionPublishingRestricted class is perfectly okay. It first checks if there are warnings on item level, and if there aren't any then it goes on to check the version level.

In my opinion, one other pipeline (Sitecore.Pipelines.GetContentEditorWarnings.ItemPublishingRestricted) should be displaying warnings on items whose ancestors are not publishable. But, that pipeline looks only at that particular item and doesn't look up the tree, so it looks like in Sitecore 8.2 they have given up on those warnings.

My answer to this problem is creating a custom pipeline processor that handles the situation where item itself is publishable but one of its ancestors is not.

Here's the code:

using System;
using Sitecore.Data.Items;
using Sitecore.Publishing.Explanations;
using Sitecore.Publishing.PublishingInformation;
using System.Linq;
using Sitecore.Pipelines.GetContentEditorWarnings;

namespace ABC.Sitecore.Website.Pipelines.GetContentEditorWarnings
{
    public class ItemPublishingRestrictedOnAncestor
    {
        public void Process(GetContentEditorWarningsArgs args)
        {
            Item obj = args.Item;
            if (obj == null || PublishingInformationBuilder.GetPublishingInformation(obj, PublishingInformationLevel.Item).OfType<Error>().Any<Error>())
            {
                // A call to PublishingInformationBuilder.GetPublishingInformation is needed because that is the area covered by standard ItemPublishingRestricted processor.
                // So, if that processor will display a warning that the item is not publishable then we don't have to go on and do our processing.
                return;
            }
            DateTime utcNow = DateTime.UtcNow;
            // IsPublishable with second parameter "true" will go up the tree and check if all ancestors of this item are publishable.
            if (!obj.Publishing.IsPublishable(utcNow, true))
                args.Add("This item will not be published because \"Publishable\" option is disabled on one of parent items.", string.Empty);
        }
    }
}

And the config file (e.g. App_Config\Include\ItemPublishingRestrictedOnAncestorPipeline.config):

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <getContentEditorWarnings>
        <processor type="ABC.Sitecore.Website.Pipelines.GetContentEditorWarnings.ItemPublishingRestrictedOnAncestor, ABC.Sitecore.Website" />
      </getContentEditorWarnings>
    </pipelines>
  </sitecore>
</configuration>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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