في آخر الملف if (session_status() === PHP_SESSION_NONE) { session_start(); } function h($value) { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); } function is_admin() { return isset($_SESSION['admin_id']); } function require_admin() { if (!is_admin()) { $base = defined('BASE_URL') ? BASE_URL : ''; header("Location: " . $base . "/admin/login.php"); exit; } } function log_activity($action, $meta = '') { global $pdo; if (!isset($pdo)) return; try { $uid = $_SESSION['admin_id'] ?? null; $ip = $_SERVER['REMOTE_ADDR'] ?? ''; $ua = $_SERVER['HTTP_USER_AGENT'] ?? ''; $stmt = $pdo->prepare("INSERT INTO activity_log (user_id, action, meta, ip, user_agent) VALUES (?,?,?,?,?)"); $stmt->execute([$uid, $action, $meta, $ip, $ua]); } catch (Throwable $e) {} } function has_role($role) { global $pdo; if (!is_admin()) return false; try { $stmt = $pdo->prepare("SELECT r.name FROM roles r JOIN user_roles ur ON ur.role_id = r.id WHERE ur.user_id = ?"); $stmt->execute([$_SESSION['admin_id']]); $roles = []; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) $roles[] = $row['name']; return in_array($role, $roles, true); } catch (Throwable $e) { return false; } } function require_role($roles) { if (!is_array($roles)) $roles = [$roles]; foreach ($roles as $r) { if (has_role($r)) return; } http_response_code(403); echo "403 Forbidden"; exit; } function require_any_role($roles) { return require_role($roles); } /* CSRF */ function csrf_token() { if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } return $_SESSION['csrf_token']; } function csrf_field() { echo ''; } function csrf_verify() { $sent = $_POST['csrf_token'] ?? ''; $sess = $_SESSION['csrf_token'] ?? ''; if (!$sent || !$sess || !hash_equals($sess, $sent)) { http_response_code(403); echo "403 Forbidden (CSRF)"; exit; } }