response(true, $data, $status); } #[NoReturn] public function response(bool $success, mixed $data, int $status = null): void { global $DEBUG; header('Content-Type: application/json'); if ($status) { http_response_code($status); } else { http_response_code($success ? 200 : 400); } // If the data isn't an array, convert it to an array if (!is_array($data)) { $data = ['message' => $data]; } // If the debug mode is enabled, add the debug data to the response if ($DEBUG) { $this->add_include('debug', [ 'memory' => memory_get_usage(), 'time' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'], 'data' => $this->get_data() ]); } echo json_encode([ 'success' => $success, 'data' => $data, 'meta' => $this->meta, 'includes' => $this->includes ]); exit; } public function add_include(string $string, array $dataArray): void { $this->add_included($string, $dataArray); } public function add_included(string $key, mixed $value): void { $this->includes[$key] = $value; } public function get_data(): array { return $this->data; } #[NoReturn] public function not_found(): void { $this->error('Not found', 404); } #[NoReturn] public function error(mixed $data, int $status = null): void { $this->response(false, $data, $status); } #[NoReturn] public function rate_limit_exceeded(): void { $this->error('Rate limit exceeded', 429); } public function matching_route_found(): void { $this->matching_route_found = true; } #[NoReturn] public function method_not_allowed(): void { $this->error('Method not allowed', 405); } #[NoReturn] public function internal_server_error($error): void { $this->error('Internal server error' . ($error ? ': ' . $error : ''), 500); } public function paginate(int $page, int $per_page, int $total, string $search = null, array $filters = null, array $order = null): void { // If the total is 0, return 1 page, 0 total if ($total === 0) { $total = 1; } $this->add_meta('pagination', [ 'page' => $page, 'per_page' => $per_page, 'total' => $total, 'search' => $search, 'filters' => $filters, 'order' => $order ]); } public function add_meta(string $key, mixed $value): void { $this->meta[$key] = $value; } public function is_matching_route_found(): bool { return $this->matching_route_found; } public function add_debug(mixed $data): void { $this->add_data('debug', $data); } public function add_data(string $key, mixed $value): void { $this->data[$key] = $value; } public function getRequestParameter(string $key): string|null { // Get the request data if the method is POST, PUT or PATCH if ($_SERVER['REQUEST_METHOD'] === 'POST' || $_SERVER['REQUEST_METHOD'] === 'PUT' || $_SERVER['REQUEST_METHOD'] === 'PATCH') { $data = json_decode(file_get_contents('php://input'), true); } // Get the request data if the method is GET, DELETE or OPTIONS if ($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'DELETE' || $_SERVER['REQUEST_METHOD'] === 'OPTIONS') { $data = $_GET; } // Return the data return $data[$key] ?? null; } public function parseFilters(?string $filters): array|null { if ($filters) { $filters = explode(',', $filters); $temp = []; foreach ( $filters as $filter ) { $filter = explode(':', $filter); $temp[$filter[0]] = $filter[1]; } $filters = $temp; } if ($filters) { return $filters; } return null; } public function add_debug_list(string $list_name, int $key, $value): void { $this->add_data($list_name, [$key => $value]); } }