Coveo IsPublishableInboundFilter

UPDATE 1: added return to inner call to AllAncestorsArePublishable and removed patch:before from processor to allow processor to go to the bottom of the pipeline.  Thanks for helping with this, Jeff L’Heureux!

While working with Coveo on a Sitecore project recently, I ran into an interesting situation – items that were not publishable were showing up in Coveo search results in Preview mode.  Upon further investigation, I realized this is expected behavior with Coveo given that it does not take into account the fact that an item is not publishable when indexing items and returning results in Preview mode, i.e., results from the Master database.

In some cases, you might want to see these items in your search results in Preview mode.  In my case, my client did not.  My client wanted the results to match the state of their items in Sitecore.  Not only were items showing up that shouldn’t be but also, when we would click on a Coveo search result, Sitecore would return a 404, which, was expected because that’s Sitecore’s default behavior in Preview mode.

So, as you can see, this was a problem for Content Authors.

To meet my client’s requirement of not displaying unpublishable results in Coveo search results, I implemented a Coveo inbound filter that I called IsPublishableInboundFilter.

using Coveo.Framework.Items;
using Coveo.SearchProvider.InboundFilters;
using Coveo.SearchProvider.Pipelines;

namespace MySolution.Coveo.Custom.InboundFilters
{
    public class IsPublishableInboundFilter : AbstractCoveoInboundFilterProcessor
    {
        public override void Process(CoveoInboundFilterPipelineArgs args)
        {
            if (args.IndexableToIndex != null && !args.IsExcluded && ShouldExecute(args))
            {
                var item = args.IndexableToIndex.Item;

                if (item.Publishing.NeverPublish)
                {
                    args.IsExcluded = true;
                    return;
                }

                args.IsExcluded = !AllAncestorsArePublishable(item);
            }
        }

        private bool AllAncestorsArePublishable(IItem item)
        {
            if (item.Parent != null && item.Parent.Publishing.NeverPublish)
            {
                return false;
            }
            else if (item.Parent != null)
            {
                return AllAncestorsArePublishable(item.Parent);
            }

            return true;
        }
    }
}

And here’s the config to patch in this inbound filter:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <coveoInboundFilterPipeline>
        <processor type="MySolution.Coveo.Custom.InboundFilters.IsPublishableInboundFilter, MySolution.Coveo.Custom" />
      </coveoInboundFilterPipeline>
    </pipelines>
  </sitecore>
</configuration>

Note, I left out any patch:before or patch:after references.  This was on purpose so that the inbound filter gets added to the bottom of the pipeline and is the final processor to set the args.isExcluded property.

You can also find this code and config as a Gist on Github – https://gist.github.com/dcouto/00d78af1ea5befc361b8cfc614f2d585.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s