【问题标题】:CQ5 / AEM5.6 Workflow: Access workflow instance properties from inside OR SplitCQ5 / AEM5.6 工作流:从内部或拆分访问工作流实例属性
【发布时间】:2014-04-16 00:58:25
【问题描述】:

TL;DR 版本:

  • 在 CQ 工作流程中,OR 拆分流程步骤 可用的内容之间是否存在差异?
  • 是否可以从 OR 拆分中访问工作流实例的 /history/ 节点?
  • 怎么样?!

整个故事:

我正在处理 CQ5 / AEM5.6 中的工作流。

在这个工作流中,我有一个自定义对话框,它在工作流实例上存储了几个属性。

我遇到问题的属性的路径是:/workflow/instances/[this instance]/history/[workItem id]/workItem/metaData,我将该属性称为“reject-or-approve”。

该对话框将属性设置为正常(通过一个下拉菜单,您可以将其设置为“拒绝”或“批准”),我可以通过以下流程步骤(在 ecma 脚本中)访问此节点上的其他属性:

var actionReason;
var history = workflowSession.getHistory(workItem.getWorkflow());

// loop backwards through workItems
// and as soon as we find a Action Reason that is not empty
// store that as 'actionReason' and break.
for (var index = history.size() - 1; index >= 0; index--) {
  var previous = history.get(index);

    var tempActionReason = previous.getWorkItem().getMetaDataMap().get('action-message');

    if ((tempActionReason != '')&&(tempActionReason != null)) {
        actionReason = tempActionReason;
        break;
    }
}

虽然过程步骤不是问题。我遇到麻烦的地方是当我尝试从 OR Split 内部做同样的事情时。

当我在 OR 拆分中尝试相同的 workflowSession.getHistory(workItem.getWorkflow()) 时,它会引发错误,提示未定义 workItem。

我尝试将此属性存储在有效负载上(即,将其存储在页面的 jcr:content 下),在这种情况下,该属性似乎可用于 OR 拆分,但我的问题是:

  • reject-or-approve 属性仅与当前工作流实例相关,因此将其存储在页面的 jcr:content 中没有任何意义。 jcr:content 属性将在工作流关闭后持续存在,并且可供未来的工作流实例访问。我可以解决这个问题(即不要让工作流基于该属性做任何事情,除非我确定该实例已经写入该属性),但这感觉不对,而且可能容易出错。
  • 由于某种原因,在我的工作流程中运行自定义对话框时,似乎只有 Admin 用户组能够写入 jcr:content 属性。当我将对话框用作任何其他用户组(我需要为此工作流设计执行此操作)时,对话框看起来好像在工作,但实际上从未写入 jcr:content 属性。

因此,出于几个不同的原因,我宁愿将此属性保留在工作流实例的本地,而不是将其存储在页面的 jcr:content 中——但是,如果有人能想到我的对话框未设置的原因jcr:content 上的属性,当我使用除 admin 之外的任何组时,即使它不是我正在寻找的解决方案,它也会给我一个解决方法。

如果有人可以提供帮助,请提前致谢!我知道这有点晦涩难懂,但我已经坚持了很久。

【问题讨论】:

  • 嗨,本,非常好的描述!我还有一个问题,只是为了确定你想要实现什么。您对此工作流程的用例是什么?在哪些情况下以及应该由谁启动?关于在 jcr:content 下存储属性的问题 - 可能是启动工作流或使用对话框的用户没有在此 jcr:content 下存储的权限。请检查该用户属于哪个组并检查其权限。它可能由 XHR POST 完成 - 检查浏览器中的响应。
  • 感谢米哈尔的建议。当我正要研究 XHR POST 时,我的同事告诉我他已经解决了这个问题。我会单独发布答案。
  • 更新:我们已经解决了部分问题,但还没有完全解决。我们发现 Approver 无法更新批准或拒绝属性(在有效负载的 jcr:content 上),因为我们的工作流在对话步骤期间锁定了有效负载。管理员可以更新属性,因为负载被锁定作为管理员。不幸的是,这实际上并没有解决我们的问题,因为我们仍然需要锁定有效载荷。如果我们能找到一种解锁方法,更新 jcr:content 然后再次锁定,这将让我们摆脱麻烦。
  • 如果没有后端开发,这将很难。你能告诉我这个工作流程的用例是什么吗?另一个提示是查看 JCR 中 OR 拆分的外观。这不是一个正常的步骤。据我所知,它由几个节点组成。
  • 是的,我查看了 OR 拆分结构,它看起来相当复杂。我正在考虑开发一个自定义工作流程步骤,但在这个阶段,这将是一个陡峭的学习曲线,我没有时间!我找到了一种解决方法(与昨天的不同),我认为它相当简洁。我会将我的发现作为答案发布。

标签: workflow aem


【解决方案1】:

几天前我遇到了同样的问题。这里的问题是您没有 workItem 对象,因为您实际上没有现有的 workItem。想象一下:您正在经历工作流程,您有几个工作项,其中一个是流程步骤,一个是收件箱项。当您在一个或拆分中时,您没有现有的工作项,您可以通过访问工作流实例的 /workItems 节点来确保。您的解决方法似乎是解决此“问题”的唯一方法。

【讨论】:

    【解决方案2】:

    我已经解决了。它看起来并不那么优雅,但它似乎是一个非常可靠的解决方案。

    这里有一些背景:

    对话框似乎可以让您可靠地将属性存储在:

    • payload 的jcr:content 节点(这对我来说不实用,因为payload 在工作流程中被锁定,并且不允许非管理员写入其 jcr:content)
    • 当前工作流程步骤的workItem/metaData

    但是,拆分步骤无权访问 workItem。我在这里找到了一个相当无用的确认:http://blogs.adobe.com/dmcmahon/2013/03/26/cq5-failure-running-script-etcworkflowscriptscaworkitem-ecma-referenceerror-workitem-is-not-defined/

    所以基本上问题是,Dialog 步骤可以存储属性,但 OR Split 无法访问它。

    我的解决方法是在我的工作流程中的对话框之后直接添加一个流程步骤。流程步骤确实可以访问workItem,因此它们可以读取对话框设置的属性。我从来没有特别想将这些数据存储在有效载荷的jcr:content 上,所以我寻找了另一个位置。事实证明,Process 步骤和 OR Split 都可以访问工作流 metaData(位于工作流实例节点的顶层,而不是 workItem/metaData,它位于 /history 子节点内)。因此,我的 Process 步骤现在读取 workItem 的 approveReject 属性(由对话框设置),然后将其写入工作流的 metaData 节点。然后,OR 拆分从其新位置读取属性,并施展魔法。

    您从“流程”步骤和 OR 拆分访问工作流 metaData 的方式并不一致,但您可以从两者中实现。

    这里有一些代码:(包含 cmets。不客气)

    在您选择批准或拒绝的对话框中,该字段的name 设置为rejectApprove。没有./ 或之前的任何内容。这告诉它将属性存储在workItem/metaData 节点上,用于/history/ 下的当前工作流步骤。

    在对话框之后,一个 Process 步骤运行:

    var rejectApprove;
    var history = workflowSession.getHistory(workItem.getWorkflow());
    
    // loop backwards through workItems
    // and as soon as we find a rejectApprove that is not empty
    // store that as 'rejectApprove' and break.
    for (var index = history.size() - 1; index >= 0; index--) {
      var previous = history.get(index);
        var tempRejectApprove = previous.getWorkItem().getMetaDataMap().get('rejectApprove');
        if ((tempRejectApprove != '')&&(tempRejectApprove != null)) {
            rejectApprove = tempRejectApprove;
            break;
        }
    }
    // steps up from the workflow step into the workflow metaData, 
    // and stores the rejectApprove property there
    // (where it can be accessed by an OR Split)
    workItem.getWorkflowData().getMetaData().put('rejectApprove', rejectApprove);
    

    然后在处理步骤之后,OR 拆分在其选项卡中具有以下内容:

    function check() {
        var match = 'approve';
        if (workflowData.getMetaData().get('rejectApprove') == match) {
            return true;
        } else {
            return false;
        }
    }
    

    注意:将此用于“批准”路径的选项卡,然后将其复制并将var match = 'approve' 替换为var match = 'reject'

    所以这里的关键是来自流程步骤:

    workItem.getWorkflowData().getMetaData().put('rejectApprove', rejectApprove);

    写入相同的属性:

    workflowData.getMetaData().get('rejectApprove') 在 OR 拆分中执行时读取。

    为了满足我们的业务需求,我实现的工作流程不止于此,但上述方法似乎是一种非常可靠的方式来获取在对话框中输入的值,并从 OR 中访问它们拆分。

    OR Split 无法直接访问 workItem 似乎很愚蠢,我很想知道是否有一种不那么迂回的方法,但现在这已经解决了我的问题。

    我真的希望其他人也有同样的问题,并且觉得这很有用,因为我花了很长时间才弄清楚,只应用一次!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      相关资源
      最近更新 更多