Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sitecore workbox does not prompt for comment when approving multiple items

Tags:

sitecore

I have a sitecore workflow. When I approve an item with the Approve button right next to the item it asks for comment. When I approve multiple items using the Approve (selected) or Approve (all) buttons it does not ask for comment. Why is that? Can I make it ask for comment and associate that comment with all the items that being approved? Thanks

like image 731
Z.D. Avatar asked Apr 08 '14 20:04

Z.D.


1 Answers

In order to enable comments for Selected or All items you need to:

  1. Copy Website\sitecore\shell\Applications\Workbox\Workbox.xml to Website\sitecore\shell\Override\ directory and change <CodeBeside Type="..." /> to <CodeBeside Type="My.Assembly.Namespace.WorkboxForm,My.Assembly" /> where My.Assembly and My.Assembly.Namespace matches your project.
  2. Create your own class WorkboxForm that will override Sitecore WorkboxForm and match Type from point 1. and use the edited code of WorkBox form:
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Exceptions;
using Sitecore.Globalization;
using Sitecore.Resources;
using Sitecore.Shell.Framework.CommandBuilders;
using Sitecore.Text;
using Sitecore.Web;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.Sheer;
using Sitecore.Web.UI.XmlControls;
using Sitecore.Workflows;
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;

namespace My.Assembly.Namespace
{
    public class WorkboxForm : Sitecore.Shell.Applications.Workbox.WorkboxForm
    {
        private NameValueCollection stateNames;

        public void CommentMultiple(ClientPipelineArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if (!args.IsPostBack)
            {
                Context.ClientPage.ClientResponse.Input("Enter a comment:", string.Empty);
                args.WaitForPostBack();
            }
            else if (args.Result.Length > 2000)
            {
                Context.ClientPage.ClientResponse.ShowError(new Exception(string.Format("The comment is too long.\n\nYou have entered {0} characters.\nA comment cannot contain more than 2000 characters.", args.Result.Length)));
                Context.ClientPage.ClientResponse.Input("Enter a comment:", string.Empty);
                args.WaitForPostBack();
            }
            else
            {
                if (args.Result == null || args.Result == "null" || args.Result == "undefined")
                    return;

                IWorkflowProvider workflowProvider = Context.ContentDatabase.WorkflowProvider;
                if (workflowProvider == null)
                    return;
                IWorkflow workflow = workflowProvider.GetWorkflow(Context.ClientPage.ServerProperties["workflowid"] as string);
                if (workflow == null)
                    return;

                string stateId = (string)Context.ClientPage.ServerProperties["ws"];
                string command = (string)Context.ClientPage.ServerProperties["command"];

                string[] itemRefs = ((string)Context.ClientPage.ServerProperties["ids"] ?? string.Empty).Split(new[] { "::" }, StringSplitOptions.RemoveEmptyEntries);

                bool flag = false;

                int num = 0;

                foreach (string itemRef in itemRefs)
                {
                    string[] strArray = itemRef.Split(new[] { ',' });
                    Item items = Context.ContentDatabase.Items[strArray[0], Language.Parse(strArray[1]), Sitecore.Data.Version.Parse(strArray[2])];
                    if (items != null)
                    {
                        WorkflowState state = workflow.GetState(items);
                        if (state.StateID == stateId)
                        {
                            try
                            {
                                workflow.Execute(command, items, args.Result, true, new object[0]);
                            }
                            catch (WorkflowStateMissingException)
                            {
                                flag = true;
                            }
                            ++num;
                        }
                    }
                }

                if (flag)
                    SheerResponse.Alert("One or more items could not be processed because their workflow state does not specify the next step.", new string[0]);

                if (num == 0)
                {
                    Context.ClientPage.ClientResponse.Alert("There are no selected items.");
                }
                else
                {
                    UrlString urlString = new UrlString(WebUtil.GetRawUrl());
                    urlString["reload"] = "1";
                    Context.ClientPage.ClientResponse.SetLocation(urlString.ToString());
                }
            }
        }

        public override void HandleMessage(Message message)
        {
            Assert.ArgumentNotNull(message, "message");
            switch (message.Name)
            {
                case "workflow:sendselectednew":
                    SendSelectedNew(message);
                    return;
                case "workflow:sendallnew":
                    SendAllNew(message);
                    return;
            }
            base.HandleMessage(message);
        }

        protected override void DisplayState(IWorkflow workflow, WorkflowState state, DataUri[] items, System.Web.UI.Control control, int offset, int pageSize)
        {
            Assert.ArgumentNotNull(workflow, "workflow");
            Assert.ArgumentNotNull(state, "state");
            Assert.ArgumentNotNull(items, "items");
            Assert.ArgumentNotNull(control, "control");
            if (items.Length <= 0)
                return;
            int num = offset + pageSize;
            if (num > items.Length)
                num = items.Length;
            for (int index = offset; index < num; ++index)
            {
                Item obj = Context.ContentDatabase.Items[items[index]];
                if (obj != null)
                    CreateItem(workflow, obj, control);
            }
            Border border1 = new Border();
            border1.Background = "#e9e9e9";
            Border border2 = border1;
            control.Controls.Add(border2);
            border2.Margin = "0px 4px 0px 16px";
            border2.Padding = "2px 8px 2px 8px";
            border2.Border = "1px solid #999999";
            foreach (WorkflowCommand workflowCommand in WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(state.StateID)))
            {
                XmlControl xmlControl1 = (XmlControl) Resource.GetWebControl("WorkboxCommand");
                Assert.IsNotNull(xmlControl1, "workboxCommand is null");
                xmlControl1["Header"] = (workflowCommand.DisplayName + " " + Translate.Text("(selected)"));
                xmlControl1["Icon"] = workflowCommand.Icon;
                xmlControl1["Command"] = ("workflow:sendselectednew(command=" + workflowCommand.CommandID + ",ws=" + state.StateID + ",wf=" + workflow.WorkflowID + ")");
                border2.Controls.Add(xmlControl1);
                XmlControl xmlControl2 = (XmlControl) Resource.GetWebControl("WorkboxCommand");
                Assert.IsNotNull(xmlControl2, "workboxCommand is null");
                xmlControl2["Header"] = (workflowCommand.DisplayName + " " + Translate.Text("(all)"));
                xmlControl2["Icon"] = workflowCommand.Icon;
                xmlControl2["Command"] = ("workflow:sendallnew(command=" + workflowCommand.CommandID + ",ws=" + state.StateID + ",wf=" + workflow.WorkflowID + ")");
                border2.Controls.Add(xmlControl2);
            }
        }

        private static void CreateCommand(IWorkflow workflow, WorkflowCommand command, Item item, XmlControl workboxItem)
        {
            Assert.ArgumentNotNull(workflow, "workflow");
            Assert.ArgumentNotNull(command, "command");
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNull(workboxItem, "workboxItem");
            XmlControl xmlControl = (XmlControl) Resource.GetWebControl("WorkboxCommand");
            Assert.IsNotNull(xmlControl, "workboxCommand is null");
            xmlControl["Header"] = command.DisplayName;
            xmlControl["Icon"] = command.Icon;
            CommandBuilder commandBuilder = new CommandBuilder("workflow:send");
            commandBuilder.Add("id", item.ID.ToString());
            commandBuilder.Add("la", item.Language.Name);
            commandBuilder.Add("vs", item.Version.ToString());
            commandBuilder.Add("command", command.CommandID);
            commandBuilder.Add("wf", workflow.WorkflowID);
            commandBuilder.Add("ui", command.HasUI);
            commandBuilder.Add("suppresscomment", command.SuppressComment);
            xmlControl["Command"] = commandBuilder.ToString();
            workboxItem.AddControl(xmlControl);
        }

        private void CreateItem(IWorkflow workflow, Item item, System.Web.UI.Control control)
        {
            Assert.ArgumentNotNull(workflow, "workflow");
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNull(control, "control");
            XmlControl workboxItem = (XmlControl) Resource.GetWebControl("WorkboxItem");
            Assert.IsNotNull(workboxItem, "workboxItem is null");
            control.Controls.Add(workboxItem);
            StringBuilder stringBuilder = new StringBuilder(" - (");
            Language language = item.Language;
            stringBuilder.Append(language.CultureInfo.DisplayName);
            stringBuilder.Append(", ");
            stringBuilder.Append(Translate.Text("version"));
            stringBuilder.Append(' ');
            stringBuilder.Append(item.Version);
            stringBuilder.Append(")");
            Assert.IsNotNull(workboxItem, "workboxItem");
            workboxItem["Header"] = item.DisplayName;
            workboxItem["Details"] = (stringBuilder).ToString();
            workboxItem["Icon"] = item.Appearance.Icon;
            workboxItem["ShortDescription"] = item.Help.ToolTip;
            workboxItem["History"] = GetHistory(workflow, item);
            workboxItem["HistoryMoreID"] = Control.GetUniqueID("ctl");
            workboxItem["HistoryClick"] = ("workflow:showhistory(id=" + item.ID + ",la=" + item.Language.Name + ",vs=" + item.Version + ",wf=" + workflow.WorkflowID + ")");
            workboxItem["PreviewClick"] = ("Preview(\"" + item.ID + "\", \"" + item.Language + "\", \"" + item.Version + "\")");
            workboxItem["Click"] = ("Open(\"" + item.ID + "\", \"" + item.Language + "\", \"" + item.Version + "\")");
            workboxItem["DiffClick"] = ("Diff(\"" + item.ID + "\", \"" + item.Language + "\", \"" + item.Version + "\")");
            workboxItem["Display"] = "none";
            string uniqueId = Control.GetUniqueID(string.Empty);
            workboxItem["CheckID"] = ("check_" + uniqueId);
            workboxItem["HiddenID"] = ("hidden_" + uniqueId);
            workboxItem["CheckValue"] = (item.ID + "," + item.Language + "," + item.Version);
            foreach (WorkflowCommand command in WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(item)))
                CreateCommand(workflow, command, item, workboxItem);
        }

        private string GetHistory(IWorkflow workflow, Item item)
        {
            Assert.ArgumentNotNull(workflow, "workflow");
            Assert.ArgumentNotNull(item, "item");
            WorkflowEvent[] history = workflow.GetHistory(item);
            string str;
            if (history.Length > 0)
            {
                WorkflowEvent workflowEvent = history[history.Length - 1];
                string text = workflowEvent.User;
                string name = Context.Domain.Name;
                if (text.StartsWith(name + "\\", StringComparison.OrdinalIgnoreCase))
                    text = StringUtil.Mid(text, name.Length + 1);
                str = string.Format(Translate.Text("{0} changed from <b>{1}</b> to <b>{2}</b> on {3}."),
                                    StringUtil.GetString(new[]
                                        {
                                            text,
                                            Translate.Text("Unknown")
                                        }), GetStateName(workflow, workflowEvent.OldState),
                                    GetStateName(workflow, workflowEvent.NewState),
                                    DateUtil.FormatDateTime(workflowEvent.Date, "D", Context.User.Profile.Culture));
            }
            else
                str = Translate.Text("No changes have been made.");
            return str;
        }

        private static DataUri[] GetItems(WorkflowState state, IWorkflow workflow)
        {
            Assert.ArgumentNotNull(state, "state");
            Assert.ArgumentNotNull(workflow, "workflow");
            ArrayList arrayList = new ArrayList();
            DataUri[] items = workflow.GetItems(state.StateID);
            if (items != null)
            {
                foreach (DataUri index in items)
                {
                    Item obj = Context.ContentDatabase.Items[index];
                    if (obj != null && obj.Access.CanRead() && (obj.Access.CanReadLanguage() && obj.Access.CanWriteLanguage()) && (Context.IsAdministrator || obj.Locking.CanLock() || obj.Locking.HasLock()))
                        arrayList.Add(index);
                }
            }
            return arrayList.ToArray(typeof(DataUri)) as DataUri[];
        }

        private string GetStateName(IWorkflow workflow, string stateID)
        {
            Assert.ArgumentNotNull(workflow, "workflow");
            Assert.ArgumentNotNull(stateID, "stateID");
            if (stateNames == null)
            {
                stateNames = new NameValueCollection();
                foreach (WorkflowState workflowState in workflow.GetStates())
                    stateNames.Add(workflowState.StateID, workflowState.DisplayName);
            }
            return StringUtil.GetString(new[] {stateNames[stateID], "?"});
        }

        private void SendAll(Message message)
        {
            Assert.ArgumentNotNull(message, "message");
            IWorkflowProvider workflowProvider = Context.ContentDatabase.WorkflowProvider;
            if (workflowProvider == null)
                return;
            string workflowID = message["wf"];
            string stateID = message["ws"];
            IWorkflow workflow = workflowProvider.GetWorkflow(workflowID);
            if (workflow == null)
                return;
            WorkflowState state = workflow.GetState(stateID);
            DataUri[] items = GetItems(state, workflow);
            Assert.IsNotNull(items, "uris is null");
            string comments = state != null ? state.DisplayName : string.Empty;
            bool flag = false;
            foreach (DataUri index in items)
            {
                Item obj = Context.ContentDatabase.Items[index];
                if (obj != null)
                {
                    try
                    {
                        workflow.Execute(message["command"], obj, comments, true, new object[0]);
                    }
                    catch (WorkflowStateMissingException)
                    {
                        flag = true;
                    }
                }
            }
            if (flag)
                SheerResponse.Alert("One or more items could not be processed because their workflow state does not specify the next step.", new string[0]);
            UrlString urlString = new UrlString(WebUtil.GetRawUrl());
            urlString["reload"] = "1";
            Context.ClientPage.ClientResponse.SetLocation(urlString.ToString());
        }

        private void SendAllNew(Message message)
        {
            Assert.ArgumentNotNull(message, "message");
            IWorkflowProvider workflowProvider = Context.ContentDatabase.WorkflowProvider;
            if (workflowProvider == null)
                return;
            string workflowID = message["wf"];
            string stateID = message["ws"];
            IWorkflow workflow = workflowProvider.GetWorkflow(workflowID);
            if (workflow == null)
                return;

            if (message["ui"] != "1")
            {
                if (message["suppresscomment"] != "1")
                {
                    string ids = String.Empty;

                    WorkflowState state = workflow.GetState(stateID);
                    DataUri[] items = GetItems(state, workflow);

                    foreach (DataUri dataUri in items)
                    {
                        ids += dataUri.ItemID + "," + dataUri.Language + "," + dataUri.Version.Number + "," + "::";
                    }

                    if (String.IsNullOrEmpty(ids))
                    {
                        Context.ClientPage.ClientResponse.Alert("There are no selected items.");
                        return;
                    }

                    Context.ClientPage.ServerProperties["ids"] = ids;
                    Context.ClientPage.ServerProperties["language"] = message["la"];
                    Context.ClientPage.ServerProperties["version"] = message["vs"];
                    Context.ClientPage.ServerProperties["command"] = message["command"];
                    Context.ClientPage.ServerProperties["ws"] = message["ws"];
                    Context.ClientPage.ServerProperties["workflowid"] = workflowID;
                    Context.ClientPage.Start(this, "CommentMultiple");
                    return;
                }
            }

            // no comment - use the old SendAll
            SendAll(message);
        }

        private void SendSelectedNew(Message message)
        {
            Assert.ArgumentNotNull(message, "message");
            IWorkflowProvider workflowProvider = Context.ContentDatabase.WorkflowProvider;
            if (workflowProvider == null)
                return;
            string workflowID = message["wf"];

            IWorkflow workflow = workflowProvider.GetWorkflow(workflowID);
            if (workflow == null)
                return;

            if (message["ui"] != "1")
            {
                if (message["suppresscomment"] != "1")
                {
                    string ids = String.Empty;
                    foreach (string str2 in Context.ClientPage.ClientRequest.Form.Keys)
                    {
                        if (str2 != null && str2.StartsWith("check_", StringComparison.InvariantCulture))
                        {
                            ids += Context.ClientPage.ClientRequest.Form["hidden_" + str2.Substring(6)] + "::";
                        }
                    }

                    if (String.IsNullOrEmpty(ids))
                    {
                        Context.ClientPage.ClientResponse.Alert("There are no selected items.");
                        return;
                    }

                    Context.ClientPage.ServerProperties["ids"] = ids;
                    Context.ClientPage.ServerProperties["language"] = message["la"];
                    Context.ClientPage.ServerProperties["version"] = message["vs"];
                    Context.ClientPage.ServerProperties["command"] = message["command"];
                    Context.ClientPage.ServerProperties["ws"] = message["ws"];
                    Context.ClientPage.ServerProperties["workflowid"] = workflowID;
                    Context.ClientPage.Start(this, "CommentMultiple");
                    return;
                }
            }

            // no comment - use the old SendSelected
            SendSelected(message);
        }

        private void SendSelected(Message message, string comment = null)
        {
            Assert.ArgumentNotNull(message, "message");
            IWorkflowProvider workflowProvider = Context.ContentDatabase.WorkflowProvider;
            if (workflowProvider == null)
                return;
            string workflowID = message["wf"];
            string str1 = message["ws"];
            IWorkflow workflow = workflowProvider.GetWorkflow(workflowID);
            if (workflow == null)
                return;
            int num = 0;
            bool flag = false;
            foreach (string str2 in Context.ClientPage.ClientRequest.Form.Keys)
            {
                if (str2 != null && str2.StartsWith("check_", StringComparison.InvariantCulture))
                {
                    string[] strArray = Context.ClientPage.ClientRequest.Form["hidden_" + str2.Substring(6)].Split(new [] { ',' });
                    Item obj = Context.ContentDatabase.Items[strArray[0], Language.Parse(strArray[1]), Sitecore.Data.Version.Parse(strArray[2])];
                    if (obj != null)
                    {
                        WorkflowState state = workflow.GetState(obj);
                        if (state.StateID == str1)
                        {
                            try
                            {
                                workflow.Execute(message["command"], obj, comment ?? state.DisplayName, true, new object[0]);
                            }
                            catch (WorkflowStateMissingException)
                            {
                                flag = true;
                            }
                            ++num;
                        }
                    }
                }
            }
            if (flag)
                SheerResponse.Alert("One or more items could not be processed because their workflow state does not specify the next step.", new string[0]);
            if (num == 0)
            {
                Context.ClientPage.ClientResponse.Alert("There are no selected items.");
            }
            else
            {
                UrlString urlString = new UrlString(WebUtil.GetRawUrl());
                urlString["reload"] = "1";
                Context.ClientPage.ClientResponse.SetLocation(urlString.ToString());
            }
        }
    }
}
like image 62
Marek Musielak Avatar answered Oct 14 '22 11:10

Marek Musielak