632bac8661
This version ditches backwards compatibility with PHP earlier than 5.6.
51 lines
1.3 KiB
PHP
51 lines
1.3 KiB
PHP
<?php
|
|
namespace Szurubooru;
|
|
|
|
final class Route
|
|
{
|
|
public $query;
|
|
public $route;
|
|
|
|
public function __construct($query, callable $route)
|
|
{
|
|
$this->query = $query;
|
|
$this->route = $route;
|
|
$this->regex = $this->getRegex();
|
|
}
|
|
|
|
public function handle($query, &$output)
|
|
{
|
|
$query = trim($query, '/');
|
|
if (!preg_match($this->regex, $query, $matches))
|
|
return false;
|
|
$routeArguments = $this->getRouteArguments($matches);
|
|
$func = $this->route;
|
|
$output = $func(...array_values($routeArguments));
|
|
return true;
|
|
}
|
|
|
|
private function getRegex()
|
|
{
|
|
$quotedQuery = preg_quote(trim($this->query, '/'), '/');
|
|
return '/^' . preg_replace('/\\\?\:([a-zA-Z_-]*)/', '(?P<\1>[^\/]+)', $quotedQuery) . '$/i';
|
|
}
|
|
|
|
private function getRouteArguments($matches)
|
|
{
|
|
$reflectionFunction = is_array($this->route)
|
|
? new \ReflectionMethod($this->route[0], $this->route[1])
|
|
: new \ReflectionFunction($this->route);
|
|
$arguments = [];
|
|
foreach ($reflectionFunction->getParameters() as $reflectionParameter)
|
|
{
|
|
$key = $reflectionParameter->name;
|
|
if (isset($matches[$key]))
|
|
$arguments[$key] = $matches[$key];
|
|
elseif ($reflectionParameter->isDefaultValueAvailable())
|
|
$arguments[$key] = $reflectionParameter->getDefaultValue();
|
|
else
|
|
$arguments[$key] = null;
|
|
}
|
|
return $arguments;
|
|
}
|
|
}
|