更改Sitecore

时间:2016-05-04 20:53:05

标签: sitecore sitecore7 sitecore7.2 sitecore-workflow

我遇到了以编程方式更改项目的工作流程状态的问题。无论我对田地做什么,国家都不会改变。我已尝试using (new SecurityDisabler()){}并将项目置于编辑模式,然后手动更改字段。我注意到该项目本身的锁定设置为<r />,这是否会导致问题?

以下是我尝试过的一些示例代码:

        [HttpPost]
        [MultipleButton(Name = "action", Argument = "Submit")]
        public ActionResult Submit(LoI model)
        {
            if (model.Submitted || !model.Signed)
            {
                return Redirect("/Profile/LoI");
            }

            ModifyCandidateInfo(model, true);

            Session["message"] = Translate.Text("loi-submitted-message");
            Session["messageClass"] = "success";

            return Redirect("/Profile/LoI");
        }
    private static void ModifyCandidateInfo(LoI model, bool isSubmission)
    {
        using (new SecurityDisabler())
        {
            var candidateFolder = CBUtility.GetCandidateFolder();

            var loi= candidateFolder.GetChildren().SingleOrDefault(loi => loi.TemplateID == LoITemplateId);

            if (loi == null) return;

            loi.Editing.BeginEdit();

            EditFields(loi, model);

            EditChildren(loi, model);

            //Send emails upon submission
            if (isSubmission)
            {
                loi.ExecuteCommand("Submit",
                    loi.Name + " submitted for " + model.CandidateName);

                using (new SecurityDisabler())
                {
                    loi.Editing.BeginEdit();

                    loi.Fields["__Workflow state"].Value = "{F352B651-341B-4CCF-89FE-BD77F5E4D540}";
                    loi.Editing.EndEdit();
                }
            }

            loi.Editing.EndEdit();


        }

    }

我使用以下功能初始化了项目的工作流程:

public static void InitializeWorkflow(Item item, ID workflowId)
        {
            item.Editing.BeginEdit();
            var workflow =
                item.Database.WorkflowProvider.GetWorkflow(workflowId.ToString());
            workflow.Start(item);
            item.Editing.EndEdit();
        }

该项目以默认的起草状态开始,并执行“提交”命令以触发电子邮件。通过Sitecore UI,如果我点击提交,它将进入下一个工作流状态,但不会以编程方式触发ExecuteCommand函数。您可以在下面找到ExecuteCommand函数。

public static WorkflowResult ExecuteCommand(this Item item, string commandName, string comment)
        {
            using (new SecurityDisabler())
            {
                var workflow = item.Database.WorkflowProvider.GetWorkflow(item);
                if (workflow == null)
                {
                    return new WorkflowResult(false, "No workflow assigned to item");
                }

                var command = workflow.GetCommands(item[FieldIDs.WorkflowState])
                    .FirstOrDefault(c => c.DisplayName == commandName);
                return command == null
                    ? new WorkflowResult(false, "Workflow command not found")
                    : workflow.Execute(command.CommandID, item, comment, false);
            }
        }

该命令发出罚款并发送电子邮件,但我无法弄清楚为什么状态不会改变。有人可以提供其他建议或解决方案吗?

我是否正确阅读了工作流程状态ID?我正在使用项目ID作为工作流状态。

1 个答案:

答案 0 :(得分:2)

我认为您的代码与我的实现非常相似。这是我的代码背景。

所有项目都具有名为“WF”的相同工作流程,并且它具有三种工作流程状态(工作,等待批准和已批准)。具有“WF”的一个页面项具有一些渲染项和那些数据源项。假设内容编辑器已准备好提交和批准项目及其相关项目。通过点击页面中的“提交”和“批准”按钮,所有页面项目的相关项目都与页面项目的工作流程状态相同。

大多数代码都来自Marek Musielak,这段代码非常适合我。

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);

        LayoutField layoutField = new LayoutField(targetItem.Fields[Sitecore.FieldIDs.FinalLayoutField]);
        LayoutDefinition layoutDefinition = LayoutDefinition.Parse(layoutField.Value);
        DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(Sitecore.Context.Device.ID.ToString());

        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();
        }

        Sitecore.Layouts.RenderingReference[] renderings = GetListOfSublayouts(item.ID.ToString(), item);
        return new WorkflowResult(true, "OK", workflowStateId);
    }

    // Verify workflow state and update 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);
        }

        unlockItem(newState, item);

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

    // Unlock the item when it is on FinalState
    public void unlockItem(WorkflowState newState, Item item)
    {
        if (newState.FinalState && item.Locking.IsLocked())
        {
            using (new EditContext(item, false, false))
            {
                item["__lock"] = "<r />";
            }
        }
    }
}