Skip to content
This repository has been archived by the owner on Aug 1, 2021. It is now read-only.

Commit

Permalink
Added ability to generate URLs for routes that contain wildcards
Browse files Browse the repository at this point in the history
  • Loading branch information
o-alquimista committed Apr 15, 2020
1 parent aef321b commit 67632b6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
4 changes: 2 additions & 2 deletions src/Fragments/Component/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ public function redirect(string $routeId)
/**
* Generates a path from a route ID and redirects to it.
*/
public function redirectToRoute(string $routeId)
public function redirectToRoute(string $routeId, array $parameters = [])
{
$router = new Router;
$path = $router->generateUrl($routeId);
$path = $router->generateUrl($routeId, $parameters);

header('Location: ' . $path, true, 301);
exit;
Expand Down
55 changes: 39 additions & 16 deletions src/Fragments/Component/Routing/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use Fragments\Component\Request;
use Fragments\Bundle\Exception\NotFoundHttpException;
use Fragments\Bundle\Exception\MethodNotAllowedHttpException;
use Fragments\Bundle\Exception\ServerErrorHttpException;

class Router
{
Expand All @@ -41,14 +42,19 @@ public function __construct()

public function start()
{
$routes = $this->parser->getRoutes();
$route = $this->getMatchingRoute($routes);
$route = $this->getMatchingRoute();

$this->load($route);
$controller = $route->getController();
$action = $route->getAction();
$parameters = $route->getParameters();

$controller = new $controller;
$controller->{$action}(...$parameters);
}

private function getMatchingRoute(array $routes): Route
private function getMatchingRoute(): Route
{
$routes = $this->parser->getRoutes();
$uri = $this->request->getURI();

// Ignore GET parameters in the URI, if present
Expand Down Expand Up @@ -105,16 +111,6 @@ private function getMatchingRoute(array $routes): Route
throw new NotFoundHttpException('Route not found.');
}

private function load(Route $route)
{
$controller = $route->getController();
$action = $route->getAction();
$parameters = $route->getParameters();

$controller = new $controller;
$controller->{$action}(...$parameters);
}

private function getRouteById(string $routeId): Route
{
$routes = $this->parser->getRoutes();
Expand All @@ -128,10 +124,37 @@ private function getRouteById(string $routeId): Route
throw new NotFoundHttpException('Route not found.');
}

public function generateUrl(string $routeId): string
public function generateUrl(string $routeId, array $parameters = []): string
{
$route = $this->getRouteById($routeId);
$routePath = $route->getPath();

// If there are no wildcards in this route path, return it as is
if (!preg_match('/{(\w+)}/', $routePath)) {
return $routePath;
}

// Break the route path in segments, without forward slashes
$routePath = explode('/', trim($routePath, '/'));

/*
* Iterate over the parameters, trying to find a corresponding wildcard
* in one of the route path segments. If found, replace it with the
* parameter value.
*/
foreach ($parameters as $parameterName => $parameterValue) {
foreach ($routePath as $pathKey => $pathSegment) {
$routePath[$pathKey] = preg_replace('/{' . $parameterName . '}/', $parameterValue, $pathSegment);
}
}

// Rebuild the path as a string, restoring forward slashes
$routePath = '/' . implode('/', $routePath);

if (preg_match('/{(\w+)}/', $routePath)) {
throw new ServerErrorHttpException('Failed to generate URL due to missing or invalid parameters: ' . $routePath);
}

return $route->getPath();
return $routePath;
}
}

0 comments on commit 67632b6

Please sign in to comment.