2015년 4월 28일 화요일

Workflow Related Item 업데이트 하기

#HowTo #Workflow #FYI

 이번에 회사에서 사이트코어 workflow세팅을 재수정하기로 하였다. 사이트코어의 유저권한에 따라, 에디터는 컨테츠를 수정하고 제출할수 있으며, 검증자는 승인을 하고, 마지막 관리자 또는 등록자는 해당 업데이트된 페이지를 Publish 할 수있도록 하는것이다.

여기서 하나의 문제점은, 아래의 사진처럼 content item에 페이지를 구성하는 많은 sublayout들이 존재할수가 있다. 각각 다른 템플릿이 적용된 관계로 페이지를 등록하고, 승인한다고 하더래도 해당 선택되어진 content item만 workflow에 적용될뿐이다. 다른 child Related Item은 그대로 initial state에 존재할수가 있다.



이런 경우를 보완하기 위하여, content item의 Workflow state이 업데이트 되면, 페이지에 등록되어진 sublayout역시 모두 똑같은 workflow state 으로 바뀌게 된다.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class UpdateWorkflowState
{
    // List all controls in page item
    public RenderingReference[] GetListOfSublayouts(string itemId, Item targetItem)
    {
        RenderingReference[] renderings = null;

        if (Sitecore.Data.ID.IsID(itemId))
        {
            renderings = targetItem.Visualization.GetRenderings(Sitecore.Context.Device, true);
        }

        return renderings;
    }

    // Return all datasource defined on one item
    public IEnumerable<string> GetDatasourceValue(WorkflowPipelineArgs args, Item targetItem)
    {
        List<string> uniqueDatasourceValues = new List<string>();
        Sitecore.Layouts.RenderingReference[] renderings = GetListOfSublayouts(targetItem.ID.ToString(), targetItem);
        foreach (var rendering in renderings)
        {
            if (!uniqueDatasourceValues.Contains(rendering.Settings.DataSource))
                uniqueDatasourceValues.Add(rendering.Settings.DataSource);
        }

        return uniqueDatasourceValues;
    }

    // Check workflow state and update state
    public WorkflowResult ChangeWorkflowState(Item item, ID workflowStateId)
    {
        using (new EditContext(item))
        {
            item[FieldIDs.WorkflowState] = workflowStateId.ToString();
        }
        return new WorkflowResult(true, "OK", workflowStateId);
    }

    // Verify workflow state
    public WorkflowResult ChangeWorkflowState(Item item, string workflowStateName)
    {
        IWorkflow workflow = item.Database.WorkflowProvider.GetWorkflow(item);

        if (workflow == null)
        {
            return new WorkflowResult(false, "No workflow assigned to item");
        }

        WorkflowState newState = workflow.GetStates().FirstOrDefault(state => state.DisplayName == workflowStateName);

        if (newState == null)
        {
            return new WorkflowResult(false, "Cannot find workflow state " + workflowStateName);
        }

        return ChangeWorkflowState(item, ID.Parse(newState.StateID));
    }
}



여기는 해당 모든 sublayout을 불러오고, 현재 workflow state의 그 다은 state로 적용시키는 것이다.


1
2
3
4
5
6
7
8
9
// Find all controls on item
foreach (string controls in GetDatasourceValue(args, args.DataItem))
{
    if (!String.IsNullOrEmpty(controls))
    {
        Item listControls = args.DataItem.Database.GetItem(controls);
        ChangeWorkflowState(listControls, "Awaiting Approval");
    }
}