Monday, December 15, 2014

Sitecore - Custom Workbox to Show the latest version of an Item

Current Environment: Sitecore 7.2 rev 140526

Requirement:
Show the latest version of an item when there is more than one version of that item.



This is the item listing in the Sitecore workbox with the default settings.

















Our requirement is to make it like this:      

Show only the latest version of a item.
Show the number of versions of that item.


















Step 1:
Get a copy of the Workbox.xml from the ~\Website\sitecore\shell\Applications\Workbox folder

Step 2:
Paste the copied Workbox.xml inside ~\Website\sitecore\shell\Override folder

Step 3:
Change the
<CodeBeside Type="Sitecore.Shell.Applications.Workbox.WorkboxForm,Sitecore.Client"/> to
<CodeBeside Type="(Namespace of your solution).(dll name)"/>

Ex: <CodeBeside Type="Custom_Workflow.CustomWrokbox"/>

Step 4:
Import the Sitecore.Client reference to the solution

Step 5:
Inherit the WorkboxForm to your class

Ex:  class CustomWrokbox : WorkboxForm

Step 6:
Override the DisplayStates() behaviour.

Code

namespace My_Workflow
{
    class CustomWrokbox : WorkboxForm
    {
        private NameValueCollection stateNames;

        protected override void DisplayStates(IWorkflow workflow, XmlControl placeholder)
        {
            Assert.ArgumentNotNull((object)workflow, "workflow");
            Assert.ArgumentNotNull((object)placeholder, "placeholder");
            this.stateNames = (NameValueCollection)null;
            foreach (WorkflowState state in workflow.GetStates())
            {
                if (WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(state.StateID)).Length > 0)
                {
                    List<DataUri> filteredUriList = new List<DataUri>();
                    DataUri[] items = this.GetItems(state, workflow);
                    Assert.IsNotNull((object)items, "items is null");
                 
                    List<DataUri> latestItemList = new List<DataUri>();
                 
                    for (int index = 0; index < items.Count(); index++)
                    {
                        bool currentItemAdded = false;
                        Item currentItem = Sitecore.Context.ContentDatabase.Items[items[index]];

                        if (latestItemList.Count > 0)
                        {
                         
                            for (int i = 0; i < latestItemList.Count; i++)
                            {
                                if ((currentItem.ID == latestItemList[i].ItemID) && (currentItem.Version.ToInt32() > latestItemList[i].Version.ToInt32()) && (currentItem.Language == latestItemList[i].Language))
                                {
                                    latestItemList.Remove(latestItemList[i]);
                                    latestItemList.Add(items[index]);
                                    currentItemAdded = true;
                                    break;
                                }
                            }

                            if (currentItemAdded == false)
                            {
                                latestItemList.Add(items[index]);
                            }
                        }
                        else
                        {
                            latestItemList.Add(items[index]);
                        }
                    }

                    items = latestItemList.ToArray();

                    string str1 = ShortID.Encode(workflow.WorkflowID) + "_" + ShortID.Encode(state.StateID);
                    Section section1 = new Section();
                    section1.ID = str1 + "_section";
                    Sitecore.Web.UI.HtmlControls.Section section2 = section1;
                    placeholder.AddControl((System.Web.UI.Control)section2);
                    int length = items.Length;
                    string str2 = string.Format("<span style=\"font-weight:normal\"> - ({0})</span>", length > 0 ? (length != 1 ? (object)string.Format("{0} {1}", (object)length, (object)Translate.Text("items")) : (object)string.Format("1 {0}", (object)Translate.Text("item"))) : (object)"none");
                    section2.Header = state.DisplayName + str2;
                    section2.Icon = state.Icon;
                    if (Settings.ClientFeeds.Enabled)
                    {
                        FeedUrlOptions feedUrlOptions = new FeedUrlOptions("/sitecore/shell/~/feed/workflowstate.aspx")
                        {
                            UseUrlAuthentication = true
                        };
                        feedUrlOptions.Parameters["wf"] = workflow.WorkflowID;
                        feedUrlOptions.Parameters["st"] = state.StateID;
                        section2.FeedLink = feedUrlOptions.ToString();
                    }
                    section2.Collapsed = length <= 0;
                    Border border = new Border();
                    section2.Controls.Add((System.Web.UI.Control)border);
                    border.ID = str1 + "_content";
                    this.DisplayState(workflow, state, items, (System.Web.UI.Control)border, 0, this.PageSize);
                    this.CreateNavigator(section2, str1 + "_navigator", length);
                }
            }
        }

        private DataUri[] GetItems(WorkflowState state, IWorkflow workflow)
        {
            Assert.ArgumentNotNull((object)state, "state");
            Assert.ArgumentNotNull((object)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((object)index);
                }
            }
            return arrayList.ToArray(typeof(DataUri)) as DataUri[];
        }

        private void CreateNavigator(Sitecore.Web.UI.HtmlControls.Section section, string id, int count)
        {
            Assert.ArgumentNotNull((object)section, "section");
            Assert.ArgumentNotNull((object)id, "id");
            Navigator navigator = new Navigator();
            section.Controls.Add((System.Web.UI.Control)navigator);
            navigator.ID = id;
            navigator.Offset = 0;
            navigator.Count = count;
            navigator.PageSize = this.PageSize;
        }
    }
}



NOTE: Code in red is the custom code. Other code is Sitecore default dll code.
Sitecore code can be change with the Sitecore version and the revision you are working with.

Friday, December 12, 2014

Sitecore - Set Reminder using Wrokflow Action

Current Environment: Sitecore 7.2 rev 140526

Requirement:
Need to set a reminder programmatically, from a custom workflow action.

Sitecore Step 1: Create a workflow action within the workflow which is set to that item template.

Create a workflow. (I used the default sample workflow).
You can find how to create the workflow action in sitecore cookbook: http://sdn.sitecore.net/upload/sitecore6/workflow_cookbook_a4.pdf.


Sitecore Step 2: Provide Type String

Select the created workflow action.
In the Type String field provide the following details.
namespace.class_name, dll_name
Ex: TestWorkflow.SetReminder, TestWorkflow

Coding

    public class SetReminder
    {
        public void Process(WorkflowPipelineArgs args)
        {
            var item = args.DataItem;
            if (item != null)
            {
                using (new Sitecore.SecurityModel.SecurityDisabler())
                {
                    item.Editing.BeginEdit();
                    try
                    {
                        item.Fields["__reminder text"].Value = "Review this item";
                        Sitecore.Data.Fields.DateField dateField = item.Fields["__reminder date"];
                        DateTime date = DateTime.Today.AddYears(1);

                        if (dateField != null)
                        {
                            dateField.Value = string.Format("{0}{1}{2}T{3}", date.Year, date.Month, date.Day,
                                date.ToString("hhmmss"));
                        }
                    }
                    finally
                    {
                        item.Editing.EndEdit();
                    }
                }
            }

        }