Add caching layer and database helper
- Add CacheHelper for file-based caching with TTL support - Add Database helper for centralized connection management - Update WorkflowModel to cache status transitions (10 min TTL) - Update UserPreferencesModel to cache user prefs (5 min TTL) - Update manage_workflows.php to clear cache on changes - Update get_users.php to use Database helper (example migration) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* WorkflowModel - Handles status transition workflows and validation
|
||||
*
|
||||
* Uses caching for frequently accessed transition rules since they rarely change.
|
||||
*/
|
||||
require_once dirname(__DIR__) . '/helpers/CacheHelper.php';
|
||||
|
||||
class WorkflowModel {
|
||||
private $conn;
|
||||
private static $CACHE_PREFIX = 'workflow';
|
||||
private static $CACHE_TTL = 600; // 10 minutes
|
||||
|
||||
public function __construct($conn) {
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active transitions (with caching)
|
||||
*
|
||||
* @return array All active transitions indexed by from_status
|
||||
*/
|
||||
private function getAllTransitions() {
|
||||
return CacheHelper::remember(self::$CACHE_PREFIX, 'all_transitions', function() {
|
||||
$sql = "SELECT from_status, to_status, requires_comment, requires_admin
|
||||
FROM status_transitions
|
||||
WHERE is_active = TRUE";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$transitions = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$from = $row['from_status'];
|
||||
if (!isset($transitions[$from])) {
|
||||
$transitions[$from] = [];
|
||||
}
|
||||
$transitions[$from][$row['to_status']] = [
|
||||
'to_status' => $row['to_status'],
|
||||
'requires_comment' => (bool)$row['requires_comment'],
|
||||
'requires_admin' => (bool)$row['requires_admin']
|
||||
];
|
||||
}
|
||||
|
||||
return $transitions;
|
||||
}, self::$CACHE_TTL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed status transitions for a given status
|
||||
*
|
||||
@@ -16,21 +51,13 @@ class WorkflowModel {
|
||||
* @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();
|
||||
$allTransitions = $this->getAllTransitions();
|
||||
|
||||
$transitions = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$transitions[] = $row;
|
||||
if (!isset($allTransitions[$currentStatus])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return $transitions;
|
||||
return array_values($allTransitions[$currentStatus]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,22 +74,15 @@ class WorkflowModel {
|
||||
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();
|
||||
$allTransitions = $this->getAllTransitions();
|
||||
|
||||
if ($result->num_rows === 0) {
|
||||
$stmt->close();
|
||||
if (!isset($allTransitions[$fromStatus][$toStatus])) {
|
||||
return false; // Transition not defined
|
||||
}
|
||||
|
||||
$row = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
$transition = $allTransitions[$fromStatus][$toStatus];
|
||||
|
||||
if ($row['requires_admin'] && !$isAdmin) {
|
||||
if ($transition['requires_admin'] && !$isAdmin) {
|
||||
return false; // Admin required
|
||||
}
|
||||
|
||||
@@ -75,18 +95,20 @@ class WorkflowModel {
|
||||
* @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);
|
||||
return CacheHelper::remember(self::$CACHE_PREFIX, 'all_statuses', function() {
|
||||
$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'];
|
||||
}
|
||||
$statuses = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$statuses[] = $row['status'];
|
||||
}
|
||||
|
||||
return $statuses;
|
||||
return $statuses;
|
||||
}, self::$CACHE_TTL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,21 +119,23 @@ class WorkflowModel {
|
||||
* @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();
|
||||
$allTransitions = $this->getAllTransitions();
|
||||
|
||||
if ($result->num_rows === 0) {
|
||||
$stmt->close();
|
||||
if (!isset($allTransitions[$fromStatus][$toStatus])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$row = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
return $row;
|
||||
$transition = $allTransitions[$fromStatus][$toStatus];
|
||||
return [
|
||||
'requires_comment' => $transition['requires_comment'],
|
||||
'requires_admin' => $transition['requires_admin']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear workflow cache (call when transitions are modified)
|
||||
*/
|
||||
public static function clearCache() {
|
||||
CacheHelper::delete(self::$CACHE_PREFIX);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user