From 7e19efd420d526024590be3f2fce69d71e766b2f Mon Sep 17 00:00:00 2001 From: tracer Date: Mon, 24 Oct 2022 18:54:43 +0200 Subject: [PATCH] added path method --- src/Service/Router.php | 52 ++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/Service/Router.php b/src/Service/Router.php index a9db1a7..a2a4975 100644 --- a/src/Service/Router.php +++ b/src/Service/Router.php @@ -16,17 +16,17 @@ use Closure; /* * A small router implementation for the address book demo. * Currently it doesn't handle GET requests, as not needed. - * But if I reuse the code in my bindApi I'll support GET as well. + * But if I reuse the code in my bindApi I'll maybe support GET as well. */ class Router { /* - * The easiest wy to differentiate between static and dynamic routes is using + * The easiest way to differentiate between static and dynamic routes is using * two arrays, no need to pollute the class Route with that information */ - private array $staticRoutes; - private array $dynamicRoutes; + private array $staticRoutes = []; + private array $dynamicRoutes = []; public function __construct(private readonly Template $template) { @@ -44,13 +44,9 @@ class Router $parameters = $matches[0]; // create regex for route: - $regex = preg_replace(pattern: '/(?<={).+?(?=})/', replacement: '(.*?)', subject: $route); - - // code below is ugly, better match including the braces - $regex = str_replace(search: '{', replace: '', subject: $regex); - $regex = str_replace(search: '}', replace: '', subject: $regex); - + $regex = preg_replace(pattern: '/{(?<=).+?(?=)}/', replacement: '([a-zA-Z0-9]*)', subject: $route); $regex = '/^' . str_replace(search: "/", replace: '\\/', subject: $regex) . '$/i'; + $route = new Route(name: $name, route: $route, regEx: $regex, parameters: $parameters, callback: $callback); if ($parameters) { @@ -61,7 +57,7 @@ class Router } /* - * Check if there is a known route and executes the callback. + * Checks if there is a known route and executes the callback. */ public function handleRouting(): void { @@ -71,28 +67,56 @@ class Router * Static routes have preference over dynamic ones, so * /admin/user/add to add and * /admin/user/{name} to edit is possible. + * A user named "add" of course not :) + * + * But who wants to call their users "add" or "delete"? + * That's as weird as Little Bobby Tables … (https://xkcd.com/327/) */ foreach ($this->staticRoutes as $route) { if (preg_match(pattern: $route->getRegex(), subject: $requestUri, matches: $matches)) { call_user_func(callback: $route->getCallback()); + + // We've found our route, bail out. return; } } foreach ($this->dynamicRoutes as $route) { + $parameters = []; if (preg_match(pattern: $route->getRegex(), subject: $requestUri, matches: $matches)) { - $parameters = []; foreach ($route->getParameters() as $id => $parameter) { $parameters[$parameter] = $matches[$id + 1]; } - // PHP is mad about named parameters in call_user_func - // Uncaught Error: Unknown named parameter $args in … + // PHP is mad about named parameters in call_user_func when adding parameters. + // Uncaught Error: Unknown named parameter $args in // But PHPStorm seems happy without them. So what? call_user_func($route->getCallback(), $parameters); return; } } + // if no route is matched, throw a 404 $this->template->render(templateName: 'status/404.html.php'); } + public function path(string $routeName, array $vars = []) + { + foreach (array_merge($this->dynamicRoutes, $this->staticRoutes) as $route) { + + if ($route->getName() == $routeName) { + if ($vars) { + // build route + $route = $route->getRoute(); + // replace placeholder with current values + foreach ($vars as $key => $value) { + $route = str_replace(search: '{' . $key . '}', replace: $value, subject: $route); + } + return $route; + } else { + return $route->getRoute(); + } + } + } + // no 404, this is reached only if the code is wrong + die("Missing Route: $routeName"); + } } \ No newline at end of file