/** * Have the engine start a new process instance. * * @param ProcessDefinition $definition * @param Node $startNode * @param string $businessKey * @param array $variables */ public function __construct(ProcessDefinition $definition, Node $startNode, $businessKey = NULL, array $variables = []) { $this->definitionId = $definition->getId(); $this->startNodeId = $startNode->getId(); $this->businessKey = $businessKey === NULL ? NULL : (string) $businessKey; $this->variables = serialize($variables); }
/** * {@inheritdoc} */ public function executeCommand(ProcessEngine $engine) { $sql = "\tSELECT s.`id`, s.`execution_id`, s.`activity_id`, s.`node`\r\n\t\t\t\t\tFROM `#__bpmn_event_subscription` AS s\r\n\t\t\t\t\tINNER JOIN `#__bpmn_execution` AS e ON (e.`id` = s.`execution_id`)\r\n\t\t\t\t\tWHERE s.`name` = :signal\r\n\t\t\t\t\tAND s.`flags` = :flags\r\n\t\t\t\t\tORDER BY e.`depth` DESC\r\n\t\t"; if ($this->executionId !== NULL) { $sql .= ' AND s.`execution_id` = :eid'; } $stmt = $engine->prepareQuery($sql); $stmt->bindValue('signal', $this->signal); $stmt->bindValue('flags', EventSubscription::TYPE_SIGNAL); if ($this->executionId !== NULL) { $stmt->bindValue('eid', $this->executionId); } $stmt->transform('execution_id', new UUIDTransformer()); $stmt->execute(); $ids = []; $executions = []; $delegations = []; foreach ($stmt->fetchRows() as $row) { $execution = $executions[] = $engine->findExecution($row['execution_id']); $ids[(string) $execution->getId()] = [$execution->getId(), $row['activity_id']]; if ($row['node'] !== NULL) { $delegations[(string) $execution->getId()] = ['nodeId' => $row['node']]; } } if (!empty($ids)) { $sql = "SELECT `job_id` FROM `#__bpmn_event_subscription` WHERE `flags` = :flags AND `job_id` IS NOT NULL AND ("; $where = []; $params = ['flags' => EventSubscription::TYPE_TIMER]; foreach (array_values($ids) as $i => $tmp) { $where[] = sprintf("(`execution_id` = :e%u AND `activity_id` = :a%u)", $i, $i); $params['e' . $i] = $tmp[0]; $params['a' . $i] = $tmp[1]; } $stmt = $engine->prepareQuery($sql . implode(' OR ', $where) . ')'); $stmt->bindAll($params); $stmt->transform('job_id', new UUIDTransformer()); $stmt->execute(); $management = $engine->getManagementService(); foreach ($stmt->fetchColumns('job_id') as $jobId) { $management->removeJob($jobId); } unset($params['flags']); $stmt = $engine->prepareQuery("DELETE FROM `#__bpmn_event_subscription` WHERE " . implode(' OR ', $where)); $stmt->bindAll($params); $count = $stmt->execute(); $message = sprintf('Cleared {count} event subscription%s related to signal <{signal}>', $count == 1 ? '' : 's'); $engine->debug($message, ['count' => $count, 'signal' => $this->signal === NULL ? 'NULL' : $this->signal]); } $vars = unserialize($this->variables); foreach ($executions as $execution) { $id = (string) $execution->getId(); $execution->signal($this->signal, $vars, empty($delegations[$id]) ? [] : $delegations[$id]); } // Include signal start events subscriptions. $sql = "\tSELECT s.`name` AS signal_name, d.* \r\n\t\t\t\t\tFROM `#__bpmn_process_subscription` AS s\r\n\t\t\t\t\tINNER JOIN `#__bpmn_process_definition` AS d ON (d.`id` = s.`definition_id`)\r\n\t\t\t\t\tWHERE s.`flags` = :flags\r\n\t\t\t\t\tAND s.`name` = :name\r\n\t\t"; $stmt = $engine->prepareQuery($sql); $stmt->bindValue('flags', EventSubscription::TYPE_SIGNAL); $stmt->bindValue('name', $this->signal); $stmt->transform('id', new UUIDTransformer()); $stmt->transform('deployment_id', new UUIDTransformer()); $stmt->execute(); $source = $this->sourceExecutionId === NULL ? NULL : $engine->findExecution($this->sourceExecutionId); while ($row = $stmt->fetchNextRow()) { $definition = new ProcessDefinition($row['id'], $row['process_key'], $row['revision'], unserialize(BinaryData::decode($row['definition'])), $row['name'], new \DateTimeImmutable('@' . $row['deployed_at']), $row['deployment_id']); $engine->pushCommand(new StartProcessInstanceCommand($definition, $definition->findSignalStartEvent($row['signal_name']), $source === NULL ? NULL : $source->getBusinessKey(), $vars)); } if ($source !== NULL) { $source->signal(); } }
/** * Start a process from the given definition using a singular * * @param ProcessDefinition $def * @param string $businessKey * @param array<string, mixed> $variables * @return HistoricProcessInstance */ public function startProcessInstance(ProcessDefinition $def, $businessKey = NULL, array $variables = []) { $startNode = $def->findNoneStartEvent(); $id = $this->engine->executeCommand(new StartProcessInstanceCommand($def, $startNode, $businessKey, $variables)); return $this->engine->getHistoryService()->createHistoricProcessInstanceQuery()->processInstanceId($id)->findOne(); }