118 lines
3.4 KiB
PHP
118 lines
3.4 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* WorkflowModel - Handles status transition workflows and validation
|
||
|
|
*/
|
||
|
|
class WorkflowModel {
|
||
|
|
private $conn;
|
||
|
|
|
||
|
|
public function __construct($conn) {
|
||
|
|
$this->conn = $conn;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get allowed status transitions for a given status
|
||
|
|
*
|
||
|
|
* @param string $currentStatus Current ticket status
|
||
|
|
* @return array Array of allowed transitions with requirements
|
||
|
|
*/
|
||
|
|
public function getAllowedTransitions($currentStatus) {
|
||
|
|
$sql = "SELECT to_status, requires_comment, requires_admin
|
||
|
|
FROM status_transitions
|
||
|
|
WHERE from_status = ? AND is_active = TRUE";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param("s", $currentStatus);
|
||
|
|
$stmt->execute();
|
||
|
|
$result = $stmt->get_result();
|
||
|
|
|
||
|
|
$transitions = [];
|
||
|
|
while ($row = $result->fetch_assoc()) {
|
||
|
|
$transitions[] = $row;
|
||
|
|
}
|
||
|
|
|
||
|
|
$stmt->close();
|
||
|
|
return $transitions;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if a status transition is allowed
|
||
|
|
*
|
||
|
|
* @param string $fromStatus Current status
|
||
|
|
* @param string $toStatus Desired status
|
||
|
|
* @param bool $isAdmin Whether user is admin
|
||
|
|
* @return bool True if transition is allowed
|
||
|
|
*/
|
||
|
|
public function isTransitionAllowed($fromStatus, $toStatus, $isAdmin = false) {
|
||
|
|
// Allow same status (no change)
|
||
|
|
if ($fromStatus === $toStatus) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$sql = "SELECT requires_admin FROM status_transitions
|
||
|
|
WHERE from_status = ? AND to_status = ? AND is_active = TRUE";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param("ss", $fromStatus, $toStatus);
|
||
|
|
$stmt->execute();
|
||
|
|
$result = $stmt->get_result();
|
||
|
|
|
||
|
|
if ($result->num_rows === 0) {
|
||
|
|
$stmt->close();
|
||
|
|
return false; // Transition not defined
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $result->fetch_assoc();
|
||
|
|
$stmt->close();
|
||
|
|
|
||
|
|
if ($row['requires_admin'] && !$isAdmin) {
|
||
|
|
return false; // Admin required
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all possible statuses from transitions table
|
||
|
|
*
|
||
|
|
* @return array Array of unique status values
|
||
|
|
*/
|
||
|
|
public function getAllStatuses() {
|
||
|
|
$sql = "SELECT DISTINCT from_status as status FROM status_transitions
|
||
|
|
UNION
|
||
|
|
SELECT DISTINCT to_status as status FROM status_transitions
|
||
|
|
ORDER BY status";
|
||
|
|
$result = $this->conn->query($sql);
|
||
|
|
|
||
|
|
$statuses = [];
|
||
|
|
while ($row = $result->fetch_assoc()) {
|
||
|
|
$statuses[] = $row['status'];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $statuses;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get transition requirements
|
||
|
|
*
|
||
|
|
* @param string $fromStatus Current status
|
||
|
|
* @param string $toStatus Desired status
|
||
|
|
* @return array|null Transition requirements or null if not found
|
||
|
|
*/
|
||
|
|
public function getTransitionRequirements($fromStatus, $toStatus) {
|
||
|
|
$sql = "SELECT requires_comment, requires_admin
|
||
|
|
FROM status_transitions
|
||
|
|
WHERE from_status = ? AND to_status = ? AND is_active = TRUE";
|
||
|
|
$stmt = $this->conn->prepare($sql);
|
||
|
|
$stmt->bind_param("ss", $fromStatus, $toStatus);
|
||
|
|
$stmt->execute();
|
||
|
|
$result = $stmt->get_result();
|
||
|
|
|
||
|
|
if ($result->num_rows === 0) {
|
||
|
|
$stmt->close();
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $result->fetch_assoc();
|
||
|
|
$stmt->close();
|
||
|
|
return $row;
|
||
|
|
}
|
||
|
|
}
|