Skip to content

Instantly share code, notes, and snippets.

@dbluhm
Last active August 8, 2017 21:21
Show Gist options
  • Save dbluhm/6904913713f3df252ca5eec6c646c9da to your computer and use it in GitHub Desktop.
Save dbluhm/6904913713f3df252ca5eec6c646c9da to your computer and use it in GitHub Desktop.
<?php
namespace Fsl\FastRoute;
class NamedRouteCollector extends \FastRoute\RouteCollector {
/** @var array */
private $lookup;
/**
* Constructs a route collector.
*
* @param RouteParser $routeParser
* @param DataGenerator $dataGenerator
*/
public function __construct(\FastRoute\RouteParser $routeParser, \FastRoute\DataGenerator $dataGenerator) {
parent::__construct($routeParser, $dataGenerator);
$this->lookup = [];
}
/**
* Adds a route to the collection and adds the name and route data to the lookup table.
*
* The syntax used in the $route string depends on the used route parser.
*
* @param string|string[] $httpMethod
* @param string $route
* @param mixed $handler
* @param string $name
*/
public function addNamedRoute($name, $httpMethod, $route, $handler) {
if ($name === '') {
throw new \FastRoute\BadRouteException('Empty name is invalid');
}
if (isset($this->lookup[$name])) {
throw new \FastRoute\BadRouteException("Route name $name is already in use");
}
parent::addRoute($httpMethod, $route, $handler);
// This part is duplicated from the parent function because we need
// $routeDatas
$route = $this->currentGroupPrefix . $route;
$routeDatas = $this->routeParser->parse($route);
// Save only the longest route
$this->lookup[$name] = [$routeDatas[0], end($routeDatas)];
}
/**
* Generate a url for a named route using inputs.
*
* @param string $route_name
* @param array $inputs
*
* @throws BadUrlInputsException
*
* @return string
*/
public function gen_url($route_name, $inputs = []) {
$route = $this->lookup[$route_name];
$url = '';
if (count($inputs) == 0) {
return $route[0][0];
} else {
$route = end($route);
}
// Uses longest route and shortcircuits after consuming all input
foreach ($route as $part) {
if (count($inputs) == 0) {
break;
}
if (!is_array($part)) {
$url .= $part;
continue;
}
if (!isset($inputs[$part[0]])) {
throw new BadUrlInputsException("No var {$part[0]} in inputs for named route \"$route_name\"");
}
$var = $inputs[$part[0]];
$regex = preg_replace('/\//', '\\\/', $part[1]);
$regex = "/$regex/";
if (!preg_match($regex, $var, $matches) || $matches[0] != $var) {
throw new BadUrlInputsException("Input {$part[0]} did not match pattern {$part[1]}");
} else {
unset($inputs[$part[0]]);
}
$url .= $var;
}
if (count($inputs) != 0) {
throw new BadUrlInputsException("Invalid number of inputs for named route \"$route_name\"");
} else {
return $url;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment