action = $action; $this->params = $params; $this->level = $level; $this->handler = $handler; $this->resp_type = $resp_type; $this->hint = $hint; $this->rh = &$rh; // assign be reference } } // Request Handler class class ReqHandler { private array $mapping; // action-handler mapping private array $request; // reference to $_REQUEST private array $files; // reference to $_FILES private string $level; // max privilege level // Constructor function __construct() { // create reference bindings $this->request = &$_REQUEST; $this->files = &$_FILES; $this->mapping = [PRIVILEGE_NONE => [], PRIVILEGE_PLAYER => [], PRIVILEGE_CREATOR => [], PRIVILEGE_QUIZMASTER => []]; // create assignment categories $this->level = PRIVILEGE_NONE; } // Add new handler function add(string|array $actions, array $params, string $level, string $handler, string $resp_type, string $hint): bool { // convert single actions to array $actions = is_string($actions) ? [$actions] : $actions; // cannot assign more than one handler to the same action foreach ($actions as $action) { if (in_array($action, $this->mapping[$level])) { return false; } // create the assignment object $assignment = new ReqHandlerAssignment($action, $params, $level, $handler, $resp_type, $hint, $this); $this->mapping[$level][$action] = $assignment; } return true; } const ACTION_KEY = "action"; // Process possible pending request. Also check access privilege. function process(string $level = null, string $action_key = self::ACTION_KEY) : array { // get action $action = $this->request[$action_key] ?? ""; // don't process empty actions if (trim($action) === "") { return ["", false]; } // if privilege level is specified, then store $this->level = $level ?? $this->level; $resp = ""; $success = false; // look up action $categories = array_keys($this->mapping); $highest_category_index = array_search($this->level, $categories); for ($i = 0; ($i < count($categories)) && ($i <= $highest_category_index); $i++) { // get category $category = &$this->mapping[$categories[$i]]; // find the command level category that includes this action if (array_key_exists($action, $category)) { // get assignment $assignment = &$category[$action]; // check that all required parameters were passed $all_params_passed = true; foreach ($assignment->params as $param) { $all_params_passed &= array_key_exists($param, $this->request); } // if params were provided, then invoke the callback if ($all_params_passed) { $handler = $assignment->handler; $raw_resp = $handler($this, $this->request); // convert response to preset response type if ($assignment->resp_type !== RESP_NONE) { // if command returns with anything at all if ($assignment->resp_type === RESP_JSON) { // JSON $resp = json_encode($raw_resp); } else if ($assignment->resp_type === RESP_PLAIN) { // PLAIN $resp = $raw_resp; } } // processing successful $success = true; break; // break the loop } } } return [$resp, $success]; } // Set access privilege level function set_privilege_level(string $level) { $this->level = $level; } }