BPMN 2.0 - ProcessMaker Nayra 扩展包接口实现

基于 ProcessMaker\Nayra 引擎的工作流工作原理

在谈工作流开发之前,请先了解下BPMN规范,BPMN规范定义了用图元如何定义一个业务流程图。BPMN的主要目标就是要提供被所有业务用户理解的一套标记语言,包括业务分析者、软件开发者以及业务管理者与监察者。

下面是一个请假流程的基于BPMN的业务流程图

BPMN 2.0 - ProcessMaker Nayra 扩展包执行流程

一个最简单的流程也要至少包括 启动事件 ,任务,结束事件顺序流网关(可以没有)。转化为BPMN标记语言如下

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:pm="http://processmaker.com/BPMN/2.0/Schema.xsd" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1530553328908" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://bpmn.io/schema/bpmn" exporter="ProcessMaker Modeler" exporterVersion="1.0" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd">
  <bpmn:process id="ProcessId" name="ProcessName" isExecutable="true">
    <bpmn:startEvent id="node_1" name="提交申请">
      <bpmn:outgoing>node_9</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:endEvent id="node_2" name="结束">
      <bpmn:incoming>node_18</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:task id="node_3" name="人事审批" pm:assignment="requester">
      <bpmn:incoming>node_14</bpmn:incoming>
      <bpmn:outgoing>node_19</bpmn:outgoing>
    </bpmn:task>
    <bpmn:task id="node_4" name="部门领导审批" pm:assignment="requester">
      <bpmn:incoming>node_16</bpmn:incoming>
      <bpmn:outgoing>node_21</bpmn:outgoing>
    </bpmn:task>
    <bpmn:parallelGateway id="node_5" name="" gatewayDirection="Diverging">
      <bpmn:incoming>node_12</bpmn:incoming>
      <bpmn:outgoing>node_14</bpmn:outgoing>
      <bpmn:outgoing>node_16</bpmn:outgoing>
    </bpmn:parallelGateway>
    <bpmn:task id="node_6" name="直属领导审批" pm:assignment="requester">
      <bpmn:incoming>node_9</bpmn:incoming>
      <bpmn:outgoing>node_12</bpmn:outgoing>
    </bpmn:task>
    <bpmn:sequenceFlow id="node_9" name="New Sequence Flow" sourceRef="node_1" targetRef="node_6" pm:startEvent="" />
    <bpmn:sequenceFlow id="node_12" name="New Sequence Flow" sourceRef="node_6" targetRef="node_5" pm:startEvent="" />
    <bpmn:sequenceFlow id="node_14" name="New Sequence Flow" sourceRef="node_5" targetRef="node_3" pm:startEvent="" />
    <bpmn:sequenceFlow id="node_16" name="New Sequence Flow" sourceRef="node_5" targetRef="node_4" pm:startEvent="" />
    <bpmn:task id="node_17" name="行政归档" pm:assignment="requester">
      <bpmn:incoming>node_19</bpmn:incoming>
      <bpmn:incoming>node_21</bpmn:incoming>
      <bpmn:outgoing>node_18</bpmn:outgoing>
    </bpmn:task>
    <bpmn:sequenceFlow id="node_18" name="New Sequence Flow" sourceRef="node_17" targetRef="node_2" pm:startEvent="" />
    <bpmn:sequenceFlow id="node_19" name="New Sequence Flow" sourceRef="node_3" targetRef="node_17" pm:startEvent="" />
    <bpmn:sequenceFlow id="node_21" name="New Sequence Flow" sourceRef="node_4" targetRef="node_17" pm:startEvent="" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagramId">
    <bpmndi:BPMNPlane id="BPMNPlaneId" bpmnElement="ProcessId">
      <bpmndi:BPMNShape id="node_1_di" bpmnElement="node_1">
        <dc:Bounds x="0" y="250" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="node_2_di" bpmnElement="node_2">
        <dc:Bounds x="840" y="250" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="node_3_di" bpmnElement="node_3">
        <dc:Bounds x="430" y="140" width="116" height="76" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="node_4_di" bpmnElement="node_4">
        <dc:Bounds x="430" y="310" width="116" height="76" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="node_5_di" bpmnElement="node_5">
        <dc:Bounds x="330" y="250" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="node_6_di" bpmnElement="node_6">
        <dc:Bounds x="110" y="230" width="116" height="76" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="node_9_di" bpmnElement="node_9">
        <di:waypoint x="18" y="268" />
        <di:waypoint x="168.5" y="268" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="node_12_di" bpmnElement="node_12">
        <di:waypoint x="168" y="268" />
        <di:waypoint x="348" y="268" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="node_14_di" bpmnElement="node_14">
        <di:waypoint x="348" y="268" />
        <di:waypoint x="400" y="178.5" />
        <di:waypoint x="488.5" y="178.5" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="node_16_di" bpmnElement="node_16">
        <di:waypoint x="348" y="268" />
        <di:waypoint x="348" y="348.5" />
        <di:waypoint x="488.5" y="348.5" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="node_17_di" bpmnElement="node_17">
        <dc:Bounds x="630" y="230" width="116" height="76" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="node_18_di" bpmnElement="node_18">
        <di:waypoint x="688" y="268" />
        <di:waypoint x="858" y="268" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="node_19_di" bpmnElement="node_19">
        <di:waypoint x="488" y="178" />
        <di:waypoint x="688.5" y="268.5" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="node_21_di" bpmnElement="node_21">
        <di:waypoint x="488" y="348" />
        <di:waypoint x="688.5" y="268.5" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

在我们要调用 ProcessMaker Nayra 引擎的方法,我们首先需要实现引擎指定的几个 Interface,这些 Interface 有各自不同的作用,我们可以根据自己的需求在实现Interface时的指定方法时自定义

实现 ProcessMaker\Nayra\Contracts\Engine\EngineInterface 接口

ProcessMaker\Nayra\Contracts\Engine\EngineInterface 这是核心接口,在 ProcessMaker\Nayra\Engine\EngineTrait 中给出了核心方法,如流转方法 runToNextState,创建实例方法 createExecutionInstance,从已有数据中加载实例方法 loadExecutionInstance

<?php

namespace App\Services\Engine;

use ProcessMaker\Nayra\Contracts\Engine\EngineInterface;
use ProcessMaker\Nayra\Contracts\Engine\EventDefinitionBusInterface;
use ProcessMaker\Nayra\Contracts\Engine\JobManagerInterface;
use ProcessMaker\Nayra\Contracts\EventBusInterface;
use ProcessMaker\Nayra\Contracts\RepositoryInterface;
use ProcessMaker\Nayra\Engine\EngineTrait;

/**
 * Test implementation for EngineInterface.
 *
 * @package ProcessMaker\Bpmn
 */
class BpmnEngine implements EngineInterface
{
    /**
     * 中给出了核心方法,如流转方法 `runToNextState`,创建实例方法 `createExecutionInstance`,从已有数据中加载实例方法
     */
    use EngineTrait;


    /**
     *  用于存储和检索流程定义和实例
     * @var RepositoryInterface
     */
    private RepositoryInterface $repository;

    /**
     * 负责处理事件和消息
     * @var EventBusInterface $dispatcher
     */
    protected EventBusInterface $dispatcher;

    /**
     * Test engine constructor.
     *
     * @param RepositoryInterface $repository
     * @param EventBusInterface $dispatcher
     * @param JobManagerInterface|null $jobManager
     * @param EventDefinitionBusInterface|null $eventDefinitionBus
     */
    public function __construct(RepositoryInterface $repository, EventBusInterface $dispatcher, JobManagerInterface $jobManager = null, EventDefinitionBusInterface $eventDefinitionBus = null)
    {
        $this->setRepository($repository);
        $this->setDispatcher($dispatcher);
        $this->setJobManager($jobManager);
        $eventDefinitionBus && $this->setEventDefinitionBus($eventDefinitionBus);
    }

    /**
     * @return EventBusInterface
     */
    public function getDispatcher(): EventBusInterface
    {
        return $this->dispatcher;
    }

    /**
     * @param EventBusInterface $dispatcher
     *
     * @return $this
     */
    public function setDispatcher(EventBusInterface $dispatcher): static
    {
        $this->dispatcher = $dispatcher;
        return $this;
    }

    /**
     * @return RepositoryInterface
     */
    public function getRepository(): RepositoryInterface
    {
        return $this->repository;
    }

    /**
     * @param RepositoryInterface $factory
     *
     * @return $this
     */
    public function setRepository(RepositoryInterface $factory): static
    {
        $this->repository = $factory;
        return $this;
    }
}

定义了一个名为 BpmnEngine 的类,实现了 EngineInterface 接口。这个类是 ProcessMaker Nayra 工作流引擎的核心类,负责管理和执行业务流程

这个类实现了 EngineInterface 接口,这意味着它需要实现一组预定义的方法来支持流程引擎的操作。这个类主要负责管理流程实例、处理事件和消息,以及与其他系统和服务的集成。

实现 ProcessMaker\Nayra\Contracts\RepositoryInterface 接口

<?php

namespace App\Services\Engine;


use ProcessMaker\Nayra\Contracts\RepositoryInterface;
use ProcessMaker\Nayra\RepositoryTrait;

/**
 * Repository
 *
 * @package ProcessMaker\Test\Models
 */
class RepositoryEngine implements RepositoryInterface
{
    //实现了 RepositoryInterface 接口中核心方法
    use RepositoryTrait;

    /**
     * 创建一个 FormalExpression 类的实例。FormalExpression 是一个用于表示 BPMN 表达式的类,通常用于条件、脚本等地方
     *
     * @return \ProcessMaker\Nayra\Contracts\Bpmn\FormalExpressionInterface
     */
    public function createFormalExpression()
    {
        return new FormalExpression();
    }

    /**
     * 创建一个 CallActivity 类的实例。CallActivity 是一个 BPMN 构造,表示在一个流程中调用另一个流程
     *
     * @return \ProcessMaker\Nayra\Contracts\Bpmn\CallActivityInterface
     */
    public function createCallActivity()
    {
        return new CallActivity();
    }

    /**
     * 这个方法创建一个 ExecutionInstanceRepository 类的实例。ExecutionInstanceRepository 是一个用于管理和存储流程执行实例的仓库类
     *
     * @return ExecutionInstanceRepository
     */
    public function createExecutionInstanceRepository()
    {
        return new ExecutionInstanceRepository();
    }

    /**
     * 获取一个 TokenRepositoryEngine 类的实例。如果实例尚未创建,则创建一个新的实例并将其分配给 $this->tokenRepo 属性。TokenRepositoryEngine 是一个用于管理和存储令牌的仓库类。令牌是 BPMN 引擎中用于表示流程实例中的活动状态的实体
     * @return TokenRepositoryEngine|\ProcessMaker\Nayra\Contracts\Repositories\TokenRepositoryInterface|null
     */
    public function getTokenRepository()
    {
        if ($this->tokenRepo === null) {
            $this->tokenRepo = new TokenRepositoryEngine();
        }
        return $this->tokenRepo;

    }
}

RepositoryEngine 类是一个仓库类,负责创建和管理工作流引擎中的不同对象和实体,以支持流程的执行和管理。它实现了 RepositoryInterface 接口,这意味着它需要实现一组预定义的方法来支持仓库的操作。

实现 ProcessMaker\Nayra\Contracts\EventBusInterface 接口

<?php

namespace App\Services\Engine;

use ProcessMaker\Nayra\Contracts\EventBusInterface;

class EventEngine implements EventBusInterface
{
    /**
     * 存储已注册的事件监听器。键是事件名称,值是一个包含监听器的数组
     * @var array
     */
    protected array $listeners = [];

    /**
     * 用于存储已推送但尚未处理的事件和其相关数据。键是事件名称,值是一个包含事件数据的数组
     * @var array
     */
    protected array $queuedListeners = [];

    /**
     * 用于注册事件监听器。它接受一个事件名称(字符串)或多个事件名称(数组),以及一个监听器(通常是一个回调函数)。方法会遍历事件名称并将监听器添加到 $listeners 数组中
     * @param $events
     * @param $listener
     * @return void
     */
    public function listen($events, $listener)
    {
        $events = is_array($events) ? $events : [$events];
        foreach ($events as $event) {
            $this->listeners[$event][] = $listener;
        }
    }

    /**
     * 检查给定事件是否有注册的监听器。如果有,返回 true;否则返回 false。
     * @param $eventName
     * @return bool
     */
    public function hasListeners($eventName): bool
    {
        return isset($this->listeners[$eventName]) && count($this->listeners[$eventName]) > 0;
    }

    /**
     * 用于订阅事件,但在此示例中未实现。
     * @param $subscriber
     * @return void
     */
    public function subscribe($subscriber)
    {
        // Not implemented
    }

    /**
     * 调用 dispatch 方法,但将 $halt 参数设置为 true。这意味着在分发事件时,如果有一个监听器返回非空值,该方法将立即返回该值,而不再处理剩余的监听器。
     * @param $event
     * @param $payload
     * @return array|mixed|null
     */
    public function until($event, $payload = [])
    {
        return $this->dispatch($event, $payload, true);
    }

    /**
     * 负责分发事件。它接受事件名称、事件数据和一个可选的 $halt 参数。如果 $halt 为 true,则在处理事件时,一旦有一个监听器返回非空值,分发将停止。该方法返回事件处理的结果。
     * @param $event
     * @param $payload
     * @param $halt
     * @return array|mixed|null
     */
    public function dispatch($event, $payload = [], $halt = false)
    {
        if (!$this->hasListeners($event)) {
            return null;
        }

        $responses = [];
        foreach ($this->listeners[$event] as $listener) {
            $response = call_user_func($listener, $event, $payload);
            if ($halt && !is_null($response)) {
                return $response;
            }
            $responses[] = $response;
        }

        return $halt ? null : $responses;
    }

    /**
     * 将事件推入队列,稍后处理。它接受事件名称和事件数据。推送的事件将添加到 $queuedListeners 数组中。
     * @param $event
     * @param $payload
     * @return void
     */
    public function push($event, $payload = [])
    {
        $this->queuedListeners[$event][] = $payload;
    }

    /**
     * 处理队列中的所有指定事件。它会遍历队列中的事件并调用 dispatch 方法进行处理。处理完成后,它会调用 forget 方法清除事件监听器。
     * @param $event
     * @return void
     */
    public function flush($event)
    {
        if (isset($this->queuedListeners[$event])) {
            foreach ($this->queuedListeners[$event] as $payload) {
                $this->dispatch($event, $payload);
            }
            $this->forget($event);
        }
    }

    /**
     *  $listeners 数组中删除指定事件的监听器。
     * @param $event
     * @return void
     */
    public function forget($event)
    {
        unset($this->listeners[$event]);
    }

    /**
     * 清空 $queuedListeners 数组,删除所有推送的事件及其数据。
     * @return void
     */
    public function forgetPushed()
    {
        $this->queuedListeners = [];
    }
}

通过实现 EventBusInterface 接口,EventEngine 类提供了一种机制来在工作流引擎中注册、监听和分发事件。这种事件驱动的架构使得工作流引擎能够在运行时灵活地响应和处理各种事件。

实现 ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface 接口

<?php

namespace App\Services\Engine;

use ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface;
use ProcessMaker\Nayra\Engine\ExecutionInstanceTrait;

class ExecutionInstanceEngine implements ExecutionInstanceInterface
{
    use ExecutionInstanceTrait;

    protected function initToken()
    {
        $this->setId(uniqid());
    }

}

这个接口是核心接口,它的 ProcessMaker\Nayra\Engine\ExecutionInstanceTrait 提供了包括创建执行实例的具体方法等关于执行实例的其他核心方法,我们不需要实现什么,引用它的 trait 即可

实现 ProcessMaker\Nayra\Contracts\Repositories\ExecutionInstanceRepositoryInterface jiekou

<?php

namespace App\Services\Engine;


use ProcessMaker\Nayra\Contracts\Bpmn\ParticipantInterface;
use ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface;
use ProcessMaker\Nayra\Contracts\Repositories\ExecutionInstanceRepositoryInterface;
use ProcessMaker\Nayra\Contracts\Repositories\StorageInterface;
use ProcessMaker\Nayra\Engine\ExecutionInstance;

/**
 * 这个接口提供了两个方法,分别是启动流程和结束流程要做出的操作,persistInstanceCreated(ExecutionInstanceInterface $instance)是启动流程时执行的,persistInstanceCompleted(ExecutionInstanceInterface $instance)是结束流程时执行的方法,它的参数中可以获取到bpmn文件的processid为$instance->getProcess()->getId(),在这两个方法中我们需要做出自己的数据库操作,比如写入用户的申请,和修改用户申请的状态为完成。具体代码大家自己定义就好,我就不给大家实现了。

 */

class ExecutionInstanceRepository implements ExecutionInstanceRepositoryInterface
{
    private array $instances = [];


    /**
     * 加载执行实例
     * @param $uid
     * @param StorageInterface $storage
     * @return mixed|ExecutionInstanceInterface|null
     */
    public function loadExecutionInstanceByUid($uid, StorageInterface $storage)
    {
        // 仅通过 getExecutionInstance() 方法搜索存储库。
        // 您可以根据需要实现从数据库或其他持久性存储中加载执行实例的逻辑。
        return $this->getExecutionInstance($uid);
    }

    /**
     * 创建执行实例
     * @return ExecutionInstance
     */
    public function createExecutionInstance(): ExecutionInstance
    {
        // 创建一个新的 ExecutionInstance 对象并返回。
        // 根据需要实现自定义执行实例对象的创建。
        return new ExecutionInstance();
    }

    /**
     * 持久化实例创建
     * @param ExecutionInstanceInterface $instance
     * @return void
     */
    public function persistInstanceCreated(ExecutionInstanceInterface $instance): void
    {
        // 在这个示例中,我们仅将实例添加到内存存储库。
        // 您可以根据需要实现将实例保存到数据库或其他持久性存储的逻辑。
        $this->instances[$instance->getId()] = $instance;
    }

    /**
     * 持久化实例完成
     * @param ExecutionInstanceInterface $instance
     * @return void
     */
    public function persistInstanceCompleted(ExecutionInstanceInterface $instance): void
    {
        // 在这个示例中,我们仅从内存存储库中删除实例。
        // 您可以根据需要实现将实例从数据库或其他持久性存储中删除的逻辑。
        unset($this->instances[$instance->getId()]);
    }

    /**
     * 持久化实例协作
     * @param ExecutionInstanceInterface $target
     * @param ParticipantInterface $targetParticipant
     * @param ExecutionInstanceInterface $source
     * @param ParticipantInterface $sourceParticipant
     * @return null
     */
    public function persistInstanceCollaboration(ExecutionInstanceInterface $target, ParticipantInterface $targetParticipant, ExecutionInstanceInterface $source, ParticipantInterface $sourceParticipant)
    {
        // 在这个示例中,我们不执行任何操作,因为我们没有实现协作逻辑。
        // 您可以根据需要实现执行实例之间协作的逻辑。
        return null;
    }

    /**
     * 获取执行实例
     * @param $uid
     * @return mixed|null
     */
    public function getExecutionInstance($uid): mixed
    {
        return $this->instances[$uid] ?? null;
    }

}

这个接口提供了两个方法,分别是启动流程和结束流程要做出的操作,persistInstanceCreated(ExecutionInstanceInterface $instance)是启动流程时执行的,persistInstanceCompleted(ExecutionInstanceInterface $instance)是结束流程时执行的方法,它的参数中可以获取到bpmn文件的processid为$instance->getProcess()->getId(),在这两个方法中我们需要做出自己的数据库操作,比如写入用户的申请,和修改用户申请的状态为完成

实现 ProcessMaker\Nayra\Contracts\Repositories\TokenRepositoryInterface 接口

<?php

namespace App\Services\Engine;

use ProcessMaker\Nayra\Bpmn\Collection;
use ProcessMaker\Nayra\Bpmn\Models\Token;
use ProcessMaker\Nayra\Bpmn\Models\EndEvent;
use ProcessMaker\Nayra\Contracts\Bpmn\ActivityInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\CatchEventInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\EventBasedGatewayInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\GatewayInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\StartEventInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\ThrowEventInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\CallActivityInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\ScriptTaskInterface;
use ProcessMaker\Nayra\Contracts\Repositories\TokenRepositoryInterface;

/**
 * Token Repository.
 *
 * @package ProcessMaker\Models
 */
class TokenRepositoryEngine implements TokenRepositoryInterface
{

    public int $persistCalls = 0;


    /**
     * 获取当前登陆用户信息
     *
     * @return array
     */
    public function getUserInfo()
    {

        return di()->get('userinfo');
    }

    /**
     * Create a token instance.
     *
     * @return TokenInterface
     */
    public function createTokenInstance()
    {
        $token = new Token();
        return $token;
    }

    /**
     * Load a token from a persistent storage.
     *
     * @param string $uid
     *
     * @return \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface
     */
    public function loadTokenByUid($uid)
    {

    }

    /**
     * Create or update a activity to a persistent storage.
     *
     * @param \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $token
     * @param bool $saveChildElements
     *
     * @return $this
     */
    public function store(TokenInterface $token, $saveChildElements = false)
    {

    }

    /**
     * Persists instance and token data when a token arrives to an activity
     *
     * @param ActivityInterface $activity
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistActivityActivated(ActivityInterface $activity, TokenInterface $token)
    {
    }

    /**
     * Persists instance and token data when a token within an activity change to error state
     *
     * @param ActivityInterface $activity
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistActivityException(ActivityInterface $activity, TokenInterface $token)
    {
//        echo 'Exception:' . $token->getStatus() . '->' . $activity->getId() . '<br>';
    }

    /**
     * Persists instance and token data when a token is completed within an activity
     *
     * @param ActivityInterface $activity
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistActivityCompleted(ActivityInterface $activity, TokenInterface $token)
    {
    }

    /**
     * Persists instance and token data when a token is closed by an activity
     *
     * @param ActivityInterface $activity
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistActivityClosed(ActivityInterface $activity, TokenInterface $token)
    {
    }

    /**
     * Get persist calls
     *
     * @return int
     */
    public function getPersistCalls()
    {
        return $this->persistCalls;
    }

    /**
     * Reset persist calls
     *
     */
    public function resetPersistCalls()
    {
        $this->persistCalls = 0;
    }

    /**
     * Persists instance and token data when a token arrives in a throw event
     *
     * @param ThrowEventInterface $event
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistThrowEventTokenArrives(ThrowEventInterface $event, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a token is consumed in a throw event
     *
     * @param ThrowEventInterface $endEvent
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistThrowEventTokenConsumed(ThrowEventInterface $endEvent, TokenInterface $token)
    {
    }

    /**
     * Persists instance and token data when a token is passed in a throw event
     *
     * @param ThrowEventInterface $endEvent
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistThrowEventTokenPassed(ThrowEventInterface $endEvent, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a token arrives in a gateway
     *
     * @param GatewayInterface $exclusiveGateway
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistGatewayTokenArrives(GatewayInterface $gateway, TokenInterface $token)
    {
    }

    /**
     * Persists instance and token data when a token is consumed in a gateway
     *
     * @param GatewayInterface $exclusiveGateway
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistGatewayTokenConsumed(GatewayInterface $exclusiveGateway, TokenInterface $token)
    {
    }

    /**
     * Persists instance and token data when a token is passed in a gateway
     *
     * @param GatewayInterface $exclusiveGateway
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistGatewayTokenPassed(GatewayInterface $exclusiveGateway, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a token arrives in a catch event
     *
     * @param CatchEventInterface $intermediateCatchEvent
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistCatchEventTokenArrives(CatchEventInterface $intermediateCatchEvent, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a token is consumed in a catch event
     *
     * @param CatchEventInterface $intermediateCatchEvent
     * @param TokenInterface $token
     *
     * @return mixed
     */
    public function persistCatchEventTokenConsumed(CatchEventInterface $intermediateCatchEvent, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a token is passed in a catch event
     *
     * @param CatchEventInterface $intermediateCatchEvent
     * @param Collection $consumedTokens
     *
     * @return mixed
     */
    public function persistCatchEventTokenPassed(CatchEventInterface $intermediateCatchEvent, Collection $consumedTokens)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a message arrives to a catch event
     *
     * @param CatchEventInterface $intermediateCatchEvent
     * @param TokenInterface $token
     */
    public function persistCatchEventMessageArrives(CatchEventInterface $intermediateCatchEvent, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists instance and token data when a message is consumed in a catch event
     *
     * @param CatchEventInterface $intermediateCatchEvent
     * @param TokenInterface $token
     */
    public function persistCatchEventMessageConsumed(CatchEventInterface $intermediateCatchEvent, TokenInterface $token)
    {
        $this->persistCalls++;
    }

    /**
     * Persists tokens that triggered a Start Event
     *
     * @param StartEventInterface $startEvent
     * @param CollectionInterface $tokens
     *
     */
    public function persistStartEventTriggered(StartEventInterface $startEvent, CollectionInterface $tokens)
    {
    }

    /**
     * Persists instance and token data when a token is consumed in a event based gateway
     *
     * @param \ProcessMaker\Nayra\Contracts\Bpmn\EventBasedGatewayInterface $eventBasedGateway
     * @param \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $passedToken
     * @param \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface $consumedTokens
     *
     * @return mixed
     */
    public function persistEventBasedGatewayActivated(EventBasedGatewayInterface $eventBasedGateway, TokenInterface $passedToken, CollectionInterface $consumedTokens)
    {

    }

    private function getActivityType($activity)
    {
        if ($activity instanceof ScriptTaskInterface) {
            return 'scriptTask';
        }

        if ($activity instanceof CallActivityInterface) {
            return 'callActivity';
        }

        if ($activity instanceof ActivityInterface) {
            return 'task';
        }

        return 'task';
    }

}
  1. persistStartEventTriggered(StartEventInterface $startEvent, CollectionInterface $tokens) 此方法会返回启动节点的数据,并且会在启动流程时被调用,其中$startEvent->getId()为节点id,$startEvent->getName()为节点名称。

  2. persistActivityActivated(ActivityInterface $activity, TokenInterface $token) 此方法会返回下一步要执行的节点的数据,并且会在存在下一步需要执行的节点时被调用,其中$token->getStatus()为节点状态,$activity->getId()为节点id,$activity->getName()为节点名称。

  3. persistActivityCompleted(ActivityInterface $activity, TokenInterface $token) 此方法会返回被完成的节点的数据,并且会在节点被完成时被调用,其中$token->getStatus()为节点状态,$activity->getId()为节点id,$activity->getName()为节点名称。

  4. persistActivityClosed(ActivityInterface $activity, TokenInterface $token) 此方法会返回被关闭的节点的数据,并且会在节点被关闭时被调用,其中$token->getStatus()为节点状态,$activity->getId()为节点id,$activity->getName()为节点名称。

  5. persistThrowEventTokenConsumed(ThrowEventInterface $endEvent, TokenInterface $token) 此方法会返回结束节点的数据,并且会在触发结束节点时被调用,其中$endEvent->getId()为节点id,$endEvent->getName()为节点名称。

以上代码仅作参考,资料 blog.csdn.net/u011115903/article/d...

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!