137 lines
5.4 KiB
PHP
137 lines
5.4 KiB
PHP
<?php
|
|
require_once 'db/config.php';
|
|
require_once 'lib/ErrorHandler.php';
|
|
|
|
register_error_handler();
|
|
|
|
session_start();
|
|
|
|
function validate_definition_json($json) {
|
|
if (empty($json)) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Process definition JSON cannot be empty.');
|
|
}
|
|
$data = json_decode($json, true);
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Invalid JSON format in definition.');
|
|
}
|
|
|
|
$allowed_statuses = ['none', 'negative', 'in_progress', 'positive', 'active', 'processing', 'paused', 'completed', 'terminated'];
|
|
|
|
if (isset($data['nodes'])) {
|
|
foreach ($data['nodes'] as $node) {
|
|
if (isset($node['ui_hints']['status']) && !in_array($node['ui_hints']['status'], $allowed_statuses)) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Invalid status in ui_hints. Allowed values are: ' . implode(', ', $allowed_statuses));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($data['transitions'])) {
|
|
foreach ($data['transitions'] as $transition) {
|
|
if (isset($transition['actions'])) {
|
|
foreach ($transition['actions'] as $action) {
|
|
if ($action['type'] === 'start_process' && isset($action['process_name'])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Use process_code instead of process_name in transition actions.');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($data['eligibility_rules'])) {
|
|
foreach ($data['eligibility_rules'] as $rule) {
|
|
if ($rule['type'] === 'process_completed' && isset($rule['process_name'])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Use process_code instead of process_name in eligibility_rules.');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isset($data['start_node_id'])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Process definition is missing start_node_id.');
|
|
}
|
|
|
|
$start_node_id = $data['start_node_id'];
|
|
|
|
if (!isset($data['nodes']) || !is_array($data['nodes'])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Process definition is missing a valid "nodes" object.');
|
|
}
|
|
|
|
if (!isset($data['nodes'][$start_node_id])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException("start_node_id '{$start_node_id}' does not exist in nodes.");
|
|
}
|
|
|
|
if (!isset($data['transitions']) || !is_array($data['transitions'])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException('Process definition is missing a valid "transitions" array.');
|
|
}
|
|
|
|
foreach ($data['transitions'] as $index => $transition) {
|
|
if (!isset($transition['from']) || !isset($transition['to'])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException("Transition at index {$index} is missing 'from' or 'to' property.");
|
|
}
|
|
if (!isset($data['nodes'][$transition['from']])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException("Transition from an unknown node: '{$transition['from']}'.");
|
|
}
|
|
if (!isset($data['nodes'][$transition['to']])) {
|
|
http_response_code(422);
|
|
throw new WorkflowRuleFailedException("Transition to an unknown node: '{$transition['to']}'.");
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$processId = $_POST['process_id'] ?? null;
|
|
$name = $_POST['name'] ?? '';
|
|
$definition_json = $_POST['definition_json'] ?? '';
|
|
|
|
validate_definition_json($definition_json);
|
|
|
|
// Generate a simple code from the name
|
|
$code = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $name)));
|
|
|
|
if (empty($name)) {
|
|
throw new WorkflowRuleFailedException('Process name is required.');
|
|
}
|
|
|
|
$pdo = db();
|
|
$start_node = json_decode($definition_json, true)['start_node_id'] ?? null;
|
|
|
|
if (empty($processId)) {
|
|
// Create new process
|
|
$sql = 'INSERT INTO process_definitions (name, code, definition_json, start_node_id, is_active) VALUES (?, ?, ?, ?, 1)';
|
|
$params = [$name, $code, $definition_json, $start_node];
|
|
$message = 'Process created successfully.';
|
|
} else {
|
|
// Update existing process
|
|
$is_active = isset($_POST['is_active']) ? (int)$_POST['is_active'] : 0;
|
|
$sql = 'UPDATE process_definitions SET name = ?, definition_json = ?, start_node_id = ?, is_active = ? WHERE id = ?';
|
|
$params = [$name, $definition_json, $start_node, $is_active, $processId];
|
|
$message = 'Process updated successfully.';
|
|
}
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
if (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false) {
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['message' => $message]);
|
|
} else {
|
|
$_SESSION['success_message'] = $message;
|
|
header('Location: process_definitions.php');
|
|
exit();
|
|
}
|
|
}
|
|
} catch (WorkflowRuleFailedException $e) {
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['error' => $e->getMessage()]);
|
|
}
|