From 66b94fb7d69f8b5e14b5f539585301d836012bb1 Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Thu, 16 Feb 2023 00:21:57 +0100 Subject: [PATCH] Url::add_url_handler(): clean code and return bool --- src/Url.php | 129 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 54 deletions(-) diff --git a/src/Url.php b/src/Url.php index d87c70e..010f378 100644 --- a/src/Url.php +++ b/src/Url.php @@ -79,36 +79,68 @@ class Url { * authenticated users (optional, default: true if the * special force_authentication function is defined, * false otherwise) - * @param boolean $override Allow override if a command already exists with the + * @param boolean $overwrite Allow overwrite if a command already exists with the * same name (optional, default: false) * @param boolean $api_mode Enable API mode (optional, default: false) - * @param array|string|null $methods HTTP method (optional, default: array('GET', 'POST')) + * @param array|string|null $http_methods HTTP method (optional, default: array('GET', 'POST')) + * @return bool **/ public static function add_url_handler($pattern, $handler=null, $additional_info=null, - $authenticated=null, $override=true, $api_mode=false, - $methods=null) { + $authenticated=null, $overwrite=true, $api_mode=false, + $http_methods=null) { $authenticated = ( is_null($authenticated)? function_exists('force_authentication'): (bool)$authenticated ); - if (is_null($methods)) - $methods = array('GET', 'POST'); - elseif (!is_array($methods)) - $methods = array($methods); + + // Check HTTP methods parameter + if (is_null($http_methods)) + $http_methods = array('GET', 'POST'); + elseif (!is_array($http_methods)) + $http_methods = array($http_methods); + + // If multiple patterns specify using an array, add each of them if (is_array($pattern)) { + $error = false; if (is_null($handler)) foreach($pattern as $p => $h) - self :: add_url_handler( - $p, $h, $additional_info, $authenticated, $override, $api_mode, $methods); + if ( + !self :: add_url_handler( + $p, $h, $additional_info, $authenticated, $overwrite, $api_mode, $http_methods) + ) $error = true; else foreach($pattern as $p) - self :: add_url_handler( - $p, $handler, $additional_info, $authenticated, $override, $api_mode, $methods); + if ( + !self :: add_url_handler( + $p, $handler, $additional_info, $authenticated, $overwrite, $api_mode, $http_methods) + ) $error = true; + return !$error; } - else { - if (!isset(self :: $patterns[$pattern])) { - self :: $patterns[$pattern] = array( + + $error = false; + foreach($http_methods as $http_method) { + if (!isset(self :: $patterns[$http_method])) + self :: $patterns[$http_method] = array(); + // Check overwrite + if (isset(self :: $patterns[$http_method][$pattern])) { + if (!$overwrite) { + Log :: error( + "URL : pattern '%s' already defined for HTTP method %s: do not overwrite.". + $pattern, $http_method); + $error = true; + continue; + } + Log :: debug( + "URL : overwrite pattern '%s' for HTTP method %s with handler '%s' ". + "(old handler = '%s')", + $pattern, $http_method, format_callable($handler), + vardump(self :: $patterns[$http_method][$pattern]) + ); + } + + // Register URL pattern info + self :: $patterns[$http_method][$pattern] = array( 'handler' => $handler, 'additional_info' => ( is_array($additional_info)? @@ -116,29 +148,14 @@ class Url { ), 'authenticated' => $authenticated, 'api_mode' => $api_mode, - 'methods' => $methods, - ); - } - elseif ($override) { - Log :: debug( - "URL : override pattern '%s' with handler '%s' (old handler = '%s')". - $pattern, format_callable($handler), vardump(self :: $patterns[$pattern]) - ); - self :: $patterns[$pattern] = array( - 'handler' => $handler, - 'additional_info' => ( - is_array($additional_info)? - $additional_info:array() - ), - 'authenticated' => $authenticated, - 'api_mode' => $api_mode, - 'methods' => $methods, - ); - } - else { - Log :: debug("URL : pattern '$pattern' already defined : do not override."); - } + ); + Log :: trace( + "URL: Register pattern '%s' on HTTP %s with :\n%s", + $pattern, $http_method, vardump(self :: $patterns[$http_method][$pattern]) + ); } + + return !$error; } /** @@ -248,21 +265,28 @@ class Url { } Log :: debug("URL : current url = '$current_url'"); - Log :: trace( - "URL : check current url with the following URL patterns :\n - ". - implode("\n - ", array_keys(self :: $patterns)) - ); - foreach (self :: $patterns as $pattern => $handler_infos) { - $m = self :: url_match($pattern, $current_url, $handler_infos['methods']); - if (is_array($m)) { - $request = new UrlRequest($current_url, $handler_infos, $m); - // Reset last redirect - if (isset($_SESSION['last_redirect'])) - unset($_SESSION['last_redirect']); - Log :: trace("URL : result :\n".vardump($request)); - return $request; + if (array_key_exists($_SERVER['REQUEST_METHOD'], self :: $patterns)) { + Log :: trace( + "URL : check current url with the following URL patterns :\n - ". + implode("\n - ", array_keys(self :: $patterns)) + ); + foreach (self :: $patterns[$_SERVER['REQUEST_METHOD']] as $pattern => $handler_infos) { + $m = self :: url_match($pattern, $current_url); + if (is_array($m)) { + $request = new UrlRequest($current_url, $handler_infos, $m); + // Reset last redirect + if (isset($_SESSION['last_redirect'])) + unset($_SESSION['last_redirect']); + Log :: trace("URL : result :\n".vardump($request)); + return $request; + } } } + else { + Log :: debug( + 'URL: no URL pattern registered for %s HTTP method', + $_SERVER['REQUEST_METHOD']); + } if ($default_url !== false) { Log :: debug("Current url match with no pattern. Redirect to default url ('$default_url')"); self :: redirect($default_url); @@ -287,13 +311,10 @@ class Url { * * @param string $pattern The URL pattern * @param string|false $current_url The current URL (optional) - * @param array|null $methods HTTP method (optional, default: no check) * * @return array|false The URL info if pattern matched, false otherwise. **/ - public static function url_match($pattern, $current_url=false, $methods=null) { - if ($methods && !in_array($_SERVER['REQUEST_METHOD'], $methods)) - return false; + public static function url_match($pattern, $current_url=false) { if ($current_url === false) { $current_url = self :: get_current_url(); if (!$current_url) return False;