122 lines
5.4 KiB
PHP
122 lines
5.4 KiB
PHP
<?php
|
|
|
|
$content = file_get_contents('WorkflowEngine.php');
|
|
if (strpos($content, 'function getOrCreateInstanceBySubject') !== false) {
|
|
echo "Method already exists.\n";
|
|
exit;
|
|
}
|
|
|
|
$newMethod = <<<'EOD'
|
|
|
|
public function getOrCreateInstanceBySubject(string $subjectType, int $subjectId, string $processCode, int $userId, string $mode='resume_or_create'): array {
|
|
if (!in_array($subjectType, ['person', 'meeting', 'bni_group', 'organization'])) {
|
|
throw new \InvalidArgumentException("Invalid subjectType.");
|
|
}
|
|
if ($subjectId <= 0) {
|
|
throw new \InvalidArgumentException("subjectId must be > 0.");
|
|
}
|
|
if (empty($processCode)) {
|
|
throw new \InvalidArgumentException("processCode cannot be empty.");
|
|
}
|
|
|
|
$inTransaction = $this->pdo->inTransaction();
|
|
if (!$inTransaction) { $this->pdo->beginTransaction(); }
|
|
|
|
try {
|
|
$sql = "SELECT * FROM process_definitions WHERE code = ? AND is_active = 1 AND subject_scope = ? ORDER BY version DESC, id DESC LIMIT 1";
|
|
$stmt = $this->pdo->prepare($sql);
|
|
$stmt->execute([$processCode, $subjectType]);
|
|
$definition = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
|
|
if (!$definition) {
|
|
$stmt = $this->pdo->prepare("SELECT * FROM process_definitions WHERE code = ? AND is_active = 1 ORDER BY version DESC, id DESC LIMIT 1");
|
|
$stmt->execute([$processCode]);
|
|
$definition = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
if (!$definition) {
|
|
throw new WorkflowNotFoundException("No active process definition found for code '$processCode'");
|
|
}
|
|
}
|
|
|
|
$defId = $definition['id'];
|
|
$defJson = json_decode($definition['definition_json'], true);
|
|
$startNodeId = $defJson['start_node_id'] ?? null;
|
|
if (!$startNodeId) {
|
|
throw new \Exception("Process definition missing start_node_id");
|
|
}
|
|
|
|
$instance = null;
|
|
if ($mode === 'resume_or_create') {
|
|
$stmt = $this->pdo->prepare(
|
|
"SELECT pi.* FROM process_instances pi\n JOIN process_definitions pd ON pi.process_definition_id = pd.id\n WHERE pi.subject_type = ? AND pi.subject_id = ? AND pd.code = ?\n ORDER BY pi.id DESC LIMIT 1"
|
|
);
|
|
$stmt->execute([$subjectType, $subjectId, $processCode]);
|
|
$instance = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
if (!$instance) {
|
|
$stmt = $this->pdo->prepare(
|
|
"SELECT MAX(pi.run_number)
|
|
FROM process_instances pi
|
|
JOIN process_definitions pd ON pi.process_definition_id = pd.id
|
|
WHERE pi.subject_type = ? AND pi.subject_id = ? AND pd.code = ?"
|
|
);
|
|
$stmt->execute([$subjectType, $subjectId, $processCode]);
|
|
$maxRun = (int)$stmt->fetchColumn();
|
|
$runNumber = $maxRun + 1;
|
|
|
|
$personIdVal = ($subjectType === 'person') ? $subjectId : null;
|
|
$status = $defJson['nodes'][$startNodeId]['ui_hints']['status'] ?? 'in_progress';
|
|
$reason = $defJson['nodes'][$startNodeId]['ui_hints']['reason'] ?? '';
|
|
$nextStep = $defJson['nodes'][$startNodeId]['ui_hints']['next_step'] ?? '';
|
|
|
|
$stmt = $this->pdo->prepare(
|
|
"INSERT INTO process_instances
|
|
(subject_type, subject_id, person_id, process_definition_id, current_node_id, current_status, current_reason, suggested_next_step, run_number, last_activity_at, data_json)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), '{}')"
|
|
);
|
|
$stmt->execute([
|
|
$subjectType, $subjectId, $personIdVal, $defId, $startNodeId, $status, $reason, $nextStep, $runNumber
|
|
]);
|
|
|
|
$instanceId = $this->pdo->lastInsertId();
|
|
$this->addEvent($instanceId, 'system', 'Process started.', $startNodeId, [], $userId);
|
|
|
|
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE id = ?");
|
|
$stmt->execute([$instanceId]);
|
|
$instance = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
if (!$inTransaction) { $this->pdo->commit(); }
|
|
|
|
return [
|
|
'instance_id' => $instance['id'],
|
|
'process_definition_id' => $instance['process_definition_id'],
|
|
'process_code' => $processCode,
|
|
'subject_type' => $instance['subject_type'],
|
|
'subject_id' => $instance['subject_id'],
|
|
'person_id' => $instance['person_id'],
|
|
'current_node_id' => $instance['current_node_id'],
|
|
'current_status' => $instance['current_status'],
|
|
'last_activity_at' => $instance['last_activity_at'],
|
|
'data_json' => $instance['data_json']
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
if (!$inTransaction) { $this->pdo->rollBack(); }
|
|
throw $e;
|
|
}
|
|
}
|
|
EOD;
|
|
|
|
$lastBracePos = strrpos($content, '}');
|
|
if ($lastBracePos !== false) {
|
|
$content = substr($content, 0, $lastBracePos) . $newMethod . "\n}
|
|
";
|
|
file_put_contents('WorkflowEngine.php', $content);
|
|
echo "Method added.\n";
|
|
} else {
|
|
echo "Failed to find closing brace.\n";
|
|
}
|
|
|
|
|