From ece7e35959689bfea99939773cf74c734f4b3e94 Mon Sep 17 00:00:00 2001 From: Skylear Date: Thu, 15 Jul 2021 15:42:16 -0500 Subject: [PATCH 1/5] Update uri tokenizing to accept \w and \- --- src/Splashsky/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Splashsky/Router.php b/src/Splashsky/Router.php index 32e55b3..1c235d2 100644 --- a/src/Splashsky/Router.php +++ b/src/Splashsky/Router.php @@ -50,7 +50,7 @@ class Router private static function tokenize(string $uri) { - return preg_replace('/(?:{([A-Za-z]+)})+/', '([\w]+)', $uri); + return preg_replace('/(?:{([\w\-]+)})+/', '([\w\-]+)', $uri); } public static function run(string $basePath = '', bool $multimatch = false) From 3a1e5b65d74e49bc1c85981c6e093e4c75376755 Mon Sep 17 00:00:00 2001 From: Skylear Date: Thu, 15 Jul 2021 16:14:20 -0500 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=91=B7=20rebuild=20tokenize()=20to=20?= =?UTF-8?q?allow=20for=20RegEx=20constraints=20on=20routes=20via=20a=20cha?= =?UTF-8?q?in=20method=20/=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Splashsky/Router.php | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Splashsky/Router.php b/src/Splashsky/Router.php index 1c235d2..c6e3044 100644 --- a/src/Splashsky/Router.php +++ b/src/Splashsky/Router.php @@ -5,8 +5,10 @@ namespace Splashsky; class Router { private static array $routes = []; + private static array $constraints = []; private static $pathNotFound; private static $methodNotAllowed; + private static string $defaultConstraint = '([\w\-]+)'; /** * A quick static function to register a route in the router. Used by the shorthand methods as well. @@ -21,16 +23,18 @@ class Router 'action' => $action, 'methods' => $methods ]; + + return new self; } public static function get(string $route, callable $action) { - self::add($route, $action, 'GET'); + return self::add($route, $action, 'GET'); } public static function post(string $route, callable $action) { - self::add($route, $action, 'POST'); + return self::add($route, $action, 'POST'); } public static function getAllRoutes() @@ -48,9 +52,39 @@ class Router self::$methodNotAllowed = $action; } + public static function with(string|array $parameter, string $constraint = '') + { + if (is_array($parameter)) { + foreach ($parameter as $param => $constraint) { + self::$constraints[$param] = $constraint; + } + + return new self; + } + + self::$constraints[$parameter] = $constraint; + + return new self; + } + private static function tokenize(string $uri) { - return preg_replace('/(?:{([\w\-]+)})+/', '([\w\-]+)', $uri); + $constraints = array_keys(self::$constraints); + + preg_match_all('/(?:{([\w\-]+)})+/', $uri, $matches); + $matches = $matches[1]; + + foreach ($matches as $match) { + $pattern = "/(?:{".$match."})+/"; + + if (in_array($match, $constraints)) { + $uri = preg_replace($pattern, '('.self::$constraints[$match].')', $uri); + } else { + $uri = preg_replace($pattern, self::$defaultConstraint, $uri); + } + } + + return $uri; } public static function run(string $basePath = '', bool $multimatch = false) From 8a523c3ed26026e4095ace156bffcaa449f48b2e Mon Sep 17 00:00:00 2001 From: Skylear Date: Thu, 15 Jul 2021 16:17:53 -0500 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=92=A1=20Add=20function=20to=20redefi?= =?UTF-8?q?ne=20default=20parameter=20constraint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Splashsky/Router.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Splashsky/Router.php b/src/Splashsky/Router.php index c6e3044..8b89370 100644 --- a/src/Splashsky/Router.php +++ b/src/Splashsky/Router.php @@ -12,9 +12,11 @@ class Router /** * A quick static function to register a route in the router. Used by the shorthand methods as well. + * * @param string $route The path to be used as the route. * @param callable|string $action Either a callable to be executed, or a string reference to a method. * @param string|array $methods The HTTP verb(s) this route accepts. + * @return Router */ public static function add(string $route, callable|string $action, string|array $methods = 'GET') { @@ -52,6 +54,17 @@ class Router self::$methodNotAllowed = $action; } + /** + * Redefine the default constraint for route parameters. Default is '([\w\-]+)' + * + * @param string $constraint The RegEx you want parameters to adhere to by default. Defaults to '([\w\-]+)' + * @return void + */ + public static function setDefaultConstraint(string $constraint = '([\w\-]+)') + { + self::$defaultConstraint = $constraint; + } + public static function with(string|array $parameter, string $constraint = '') { if (is_array($parameter)) { From 64119b258baa5febce0f38683e7a868e5f327dda Mon Sep 17 00:00:00 2001 From: Skylear Date: Thu, 15 Jul 2021 16:44:30 -0500 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=93=91=20write=20docblocks=20for=20th?= =?UTF-8?q?e=20router=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Splashsky/Router.php | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Splashsky/Router.php b/src/Splashsky/Router.php index 8b89370..8fc2405 100644 --- a/src/Splashsky/Router.php +++ b/src/Splashsky/Router.php @@ -29,26 +29,53 @@ class Router return new self; } + /** + * Shorthand function to define a GET route + * + * @param string $route + * @param callable $action + */ public static function get(string $route, callable $action) { return self::add($route, $action, 'GET'); } + /** + * Default function to define a POST route + * + * @param string $route + * @param callable $action + */ public static function post(string $route, callable $action) { return self::add($route, $action, 'POST'); } + /** + * Return all routes currently registered + * + * @return array + */ public static function getAllRoutes() { return self::$routes; } + /** + * Defines an action to be called when a path isn't found - i.e. a 404 + * + * @param callable $action + */ public static function pathNotFound(callable $action) { self::$pathNotFound = $action; } + /** + * Defines an action to be called with a method isn't allowed on a route - i.e. a 405 + * + * @param callable $action + */ public static function methodNotAllowed(callable $action) { self::$methodNotAllowed = $action; @@ -65,6 +92,16 @@ class Router self::$defaultConstraint = $constraint; } + /** + * Define a constraint for a route parameter. If only passing one parameter, + * provide the parameter name as first argument and constraint as second. If + * adding constraints for multiple parameters, pass an array of 'parameter' => 'constraint' + * pairs. + * + * @param string|array $parameter + * @param string $constraint + * @return Router + */ public static function with(string|array $parameter, string $constraint = '') { if (is_array($parameter)) { @@ -80,6 +117,12 @@ class Router return new self; } + /** + * Tokenizes the given URI using our constraint rules and returns the tokenized URI + * + * @param string $uri + * @return string + */ private static function tokenize(string $uri) { $constraints = array_keys(self::$constraints); @@ -100,6 +143,13 @@ class Router return $uri; } + /** + * Runs the router. Accepts a base path from which to serve the routes, and optionally whether you want to try + * and match multiple routes. + * + * @param string $basePath + * @param boolean $multimatch + */ public static function run(string $basePath = '', bool $multimatch = false) { $basePath = rtrim($basePath, '/'); From 0890106d41b2921af9463468a813b2bb4a10f2ab Mon Sep 17 00:00:00 2001 From: Skylear Date: Thu, 15 Jul 2021 16:45:56 -0500 Subject: [PATCH 5/5] Move $uri var in run() --- src/Splashsky/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Splashsky/Router.php b/src/Splashsky/Router.php index 8fc2405..1ec3aff 100644 --- a/src/Splashsky/Router.php +++ b/src/Splashsky/Router.php @@ -153,8 +153,8 @@ class Router public static function run(string $basePath = '', bool $multimatch = false) { $basePath = rtrim($basePath, '/'); - $uri = parse_url($_SERVER['REQUEST_URI'])['path']; $method = $_SERVER['REQUEST_METHOD']; + $uri = parse_url($_SERVER['REQUEST_URI'])['path']; $path = urldecode(rtrim($uri, '/')); // If the path is empty (no slash in URI) place one to satisfy the root route ('/')