wardey
wardey

Reputation: 169

Capturing duplicated item in Sitecore pipeline process

I'm writing a pipeline processor to blank two fields in a item after it's been duplicated to avoid duplicate auto-generated fields:

  1. Item a is duplicated into item b
  2. Item b has the values of one or more fields removed

I have a class in place for this but can only get access to the original item a through the ClientPipelineArgs parameter id.

Is there a way to capture the ID of newly duplicated item b?

Code below:

namespace XXXX.SC.Pipeline
{
    public class DuplicateItem
    {
        public void StripShortIDs(ClientPipelineArgs args)
        {
            Item item = Sitecore.Configuration.Factory.GetDatabase(args.Parameters["database"]).GetItem(args.Parameters["id"]);

            if (!String.IsNullOrWhiteSpace(item["Short ID"]))
                using (new EditContext(item))
                {
                    item["Short ID"] = String.Empty;
                }
        }

        public void StripStatus(ClientPipelineArgs args)
        {
            Item item = Sitecore.Configuration.Factory.GetDatabase(args.Parameters["database"]).GetItem(args.Parameters["id"]);

            if (item.TemplateID.ToString() == ConfigurationManager.AppSettings["config key redacted"])
                using (new EditContext(item))
                {
                    item["Status"] = "0";
                }
        }
    }
}

Upvotes: 1

Views: 840

Answers (1)

Marek Musielak
Marek Musielak

Reputation: 27142

Assuming that you're using uiDuplicateItem pipeline, which is defined by default as

<uiDuplicateItem>
  <processor mode="on" type="Sitecore.Shell.Framework.Pipelines.DuplicateItem,Sitecore.Kernel" method="CheckPermissions" />
  <processor mode="on" type="Sitecore.Shell.Framework.Pipelines.DuplicateItem,Sitecore.Kernel" method="GetName" />
  <processor mode="on" type="Sitecore.Shell.Framework.Pipelines.DuplicateItem,Sitecore.Kernel" method="Execute" />
</uiDuplicateItem>

you need to override Execute processor first with a single line change. Below is the code of the updated Execute method with the updated place commented:

public void Execute(ClientPipelineArgs args)
{
  Assert.ArgumentNotNull((object) args, "args");
  Database database = Factory.GetDatabase(args.Parameters["database"]);
  Assert.IsNotNull((object) database, args.Parameters["database"]);
  string str = args.Parameters["id"];
  Language result;
  if (!Language.TryParse(args.Parameters["language"], out result))
    result = Context.Language;
  Item obj = database.GetItem(ID.Parse(str), result);
  if (obj == null)
  {
    SheerResponse.Alert("Item not found.", new string[0]);
    args.AbortPipeline();
  }
  else
  {
    Item parent = obj.Parent;
    if (parent == null)
    {
      SheerResponse.Alert("Cannot duplicate the root item.", new string[0]);
      args.AbortPipeline();
    }
    else if (parent.Access.CanCreate())
    {
      Log.Audit((object) this, "Duplicate item: {0}", new string[1]
      {
        AuditFormatter.FormatItem(obj)
      });


      // this was the original code - duplicated item created but id not stored
      // Context.Workflow.DuplicateItem(obj, args.Parameters["name"]);

      // new code with the id stored in args.Parameters["duplicatedId"]
      Item duplicated = Context.Workflow.DuplicateItem(obj, args.Parameters["name"]);
      args.Parameters["duplicatedId"] = duplicated.ID.ToString();


    }
    else
    {
      SheerResponse.Alert(Translate.Text("You do not have permission to duplicate \"{0}\".", new object[1]
      {
        (object) obj.DisplayName
      }), new string[0]);
      args.AbortPipeline();
    }
  }
}

Then you can add your processors for clearing fields after the new Execute processor and obtain the duplicated item from the args.Parameters["duplicatedId"].

Upvotes: 4

Related Questions