mirror of
https://github.com/linuxserver/Heimdall.git
synced 2025-12-10 17:03:52 +09:00
Update dependencies
This commit is contained in:
@@ -26,18 +26,15 @@ use Symfony\Component\Routing\RouteCollection;
|
||||
*/
|
||||
class CompiledUrlMatcherDumper extends MatcherDumper
|
||||
{
|
||||
private $expressionLanguage;
|
||||
private $signalingException;
|
||||
private ExpressionLanguage $expressionLanguage;
|
||||
private ?\Exception $signalingException = null;
|
||||
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
*/
|
||||
private $expressionLanguageProviders = [];
|
||||
private array $expressionLanguageProviders = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dump(array $options = [])
|
||||
public function dump(array $options = []): string
|
||||
{
|
||||
return <<<EOF
|
||||
<?php
|
||||
@@ -53,6 +50,9 @@ return [
|
||||
EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
||||
{
|
||||
$this->expressionLanguageProviders[] = $provider;
|
||||
@@ -115,7 +115,7 @@ EOF;
|
||||
}
|
||||
|
||||
$checkConditionCode = <<<EOF
|
||||
static function (\$condition, \$context, \$request) { // \$checkCondition
|
||||
static function (\$condition, \$context, \$request, \$params) { // \$checkCondition
|
||||
switch (\$condition) {
|
||||
{$this->indent(implode("\n", $conditions), 3)}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ EOF;
|
||||
foreach ($staticRoutes as $path => $routes) {
|
||||
$code .= sprintf(" %s => [\n", self::export($path));
|
||||
foreach ($routes as $route) {
|
||||
$code .= sprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", ...array_map([__CLASS__, 'export'], $route));
|
||||
$code .= vsprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", array_map([__CLASS__, 'export'], $route));
|
||||
}
|
||||
$code .= " ],\n";
|
||||
}
|
||||
@@ -151,7 +151,7 @@ EOF;
|
||||
foreach ($dynamicRoutes as $path => $routes) {
|
||||
$code .= sprintf(" %s => [\n", self::export($path));
|
||||
foreach ($routes as $route) {
|
||||
$code .= sprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", ...array_map([__CLASS__, 'export'], $route));
|
||||
$code .= vsprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", array_map([__CLASS__, 'export'], $route));
|
||||
}
|
||||
$code .= " ],\n";
|
||||
}
|
||||
@@ -332,7 +332,7 @@ EOF;
|
||||
if ($hasTrailingSlash = '/' !== $regex && '/' === $regex[-1]) {
|
||||
$regex = substr($regex, 0, -1);
|
||||
}
|
||||
$hasTrailingVar = (bool) preg_match('#\{\w+\}/?$#', $route->getPath());
|
||||
$hasTrailingVar = (bool) preg_match('#\{[\w\x80-\xFF]+\}/?$#', $route->getPath());
|
||||
|
||||
$tree->addRoute($regex, [$name, $regex, $state->vars, $route, $hasTrailingSlash, $hasTrailingVar]);
|
||||
}
|
||||
@@ -349,7 +349,7 @@ EOF;
|
||||
$state->markTail = 0;
|
||||
|
||||
// if the regex is too large, throw a signaling exception to recompute with smaller chunk size
|
||||
set_error_handler(function ($type, $message) { throw str_contains($message, $this->signalingException->getMessage()) ? $this->signalingException : new \ErrorException($message); });
|
||||
set_error_handler(fn ($type, $message) => throw str_contains($message, $this->signalingException->getMessage()) ? $this->signalingException : new \ErrorException($message));
|
||||
try {
|
||||
preg_match($state->regex, '');
|
||||
} finally {
|
||||
@@ -416,7 +416,7 @@ EOF;
|
||||
/**
|
||||
* Compiles a single Route to PHP code used to match it against the path info.
|
||||
*/
|
||||
private function compileRoute(Route $route, string $name, $vars, bool $hasTrailingSlash, bool $hasTrailingVar, array &$conditions): array
|
||||
private function compileRoute(Route $route, string $name, string|array|null $vars, bool $hasTrailingSlash, bool $hasTrailingVar, array &$conditions): array
|
||||
{
|
||||
$defaults = $route->getDefaults();
|
||||
|
||||
@@ -426,8 +426,8 @@ EOF;
|
||||
}
|
||||
|
||||
if ($condition = $route->getCondition()) {
|
||||
$condition = $this->getExpressionLanguage()->compile($condition, ['context', 'request']);
|
||||
$condition = $conditions[$condition] ?? $conditions[$condition] = (str_contains($condition, '$request') ? 1 : -1) * \count($conditions);
|
||||
$condition = $this->getExpressionLanguage()->compile($condition, ['context', 'request', 'params']);
|
||||
$condition = $conditions[$condition] ??= (str_contains($condition, '$request') ? 1 : -1) * \count($conditions);
|
||||
} else {
|
||||
$condition = null;
|
||||
}
|
||||
@@ -445,9 +445,9 @@ EOF;
|
||||
|
||||
private function getExpressionLanguage(): ExpressionLanguage
|
||||
{
|
||||
if (null === $this->expressionLanguage) {
|
||||
if (!isset($this->expressionLanguage)) {
|
||||
if (!class_exists(ExpressionLanguage::class)) {
|
||||
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
|
||||
}
|
||||
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
|
||||
}
|
||||
@@ -463,7 +463,7 @@ EOF;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function export($value): string
|
||||
public static function export(mixed $value): string
|
||||
{
|
||||
if (null === $value) {
|
||||
return 'null';
|
||||
|
||||
@@ -26,15 +26,11 @@ use Symfony\Component\Routing\RequestContext;
|
||||
*/
|
||||
trait CompiledUrlMatcherTrait
|
||||
{
|
||||
private $matchHost = false;
|
||||
private $staticRoutes = [];
|
||||
private $regexpList = [];
|
||||
private $dynamicRoutes = [];
|
||||
|
||||
/**
|
||||
* @var callable|null
|
||||
*/
|
||||
private $checkCondition;
|
||||
private bool $matchHost = false;
|
||||
private array $staticRoutes = [];
|
||||
private array $regexpList = [];
|
||||
private array $dynamicRoutes = [];
|
||||
private ?\Closure $checkCondition;
|
||||
|
||||
public function match(string $pathinfo): array
|
||||
{
|
||||
@@ -92,10 +88,6 @@ trait CompiledUrlMatcherTrait
|
||||
$supportsRedirections = 'GET' === $canonicalMethod && $this instanceof RedirectableUrlMatcherInterface;
|
||||
|
||||
foreach ($this->staticRoutes[$trimmedPathinfo] ?? [] as [$ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash, , $condition]) {
|
||||
if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ?? $request = $this->request ?: $this->createRequest($pathinfo) : null)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($requiredHost) {
|
||||
if ('{' !== $requiredHost[0] ? $requiredHost !== $host : !preg_match($requiredHost, $host, $hostMatches)) {
|
||||
continue;
|
||||
@@ -106,6 +98,10 @@ trait CompiledUrlMatcherTrait
|
||||
}
|
||||
}
|
||||
|
||||
if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ??= $this->request ?: $this->createRequest($pathinfo) : null, $ret)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('/' !== $pathinfo && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
|
||||
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
|
||||
return $allow = $allowSchemes = [];
|
||||
@@ -132,13 +128,8 @@ trait CompiledUrlMatcherTrait
|
||||
foreach ($this->regexpList as $offset => $regex) {
|
||||
while (preg_match($regex, $matchedPathinfo, $matches)) {
|
||||
foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as [$ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition]) {
|
||||
if (null !== $condition) {
|
||||
if (0 === $condition) { // marks the last route in the regexp
|
||||
continue 3;
|
||||
}
|
||||
if (!($this->checkCondition)($condition, $context, 0 < $condition ? $request ?? $request = $this->request ?: $this->createRequest($pathinfo) : null)) {
|
||||
continue;
|
||||
}
|
||||
if (0 === $condition) { // marks the last route in the regexp
|
||||
continue 3;
|
||||
}
|
||||
|
||||
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && $hasTrailingVar;
|
||||
@@ -151,6 +142,16 @@ trait CompiledUrlMatcherTrait
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($vars as $i => $v) {
|
||||
if (isset($matches[1 + $i])) {
|
||||
$ret[$v] = $matches[1 + $i];
|
||||
}
|
||||
}
|
||||
|
||||
if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ??= $this->request ?: $this->createRequest($pathinfo) : null, $ret)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
|
||||
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
|
||||
return $allow = $allowSchemes = [];
|
||||
@@ -158,12 +159,6 @@ trait CompiledUrlMatcherTrait
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($vars as $i => $v) {
|
||||
if (isset($matches[1 + $i])) {
|
||||
$ret[$v] = $matches[1 + $i];
|
||||
}
|
||||
}
|
||||
|
||||
if ($requiredSchemes && !isset($requiredSchemes[$context->getScheme()])) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
continue;
|
||||
|
||||
@@ -20,17 +20,14 @@ use Symfony\Component\Routing\RouteCollection;
|
||||
*/
|
||||
abstract class MatcherDumper implements MatcherDumperInterface
|
||||
{
|
||||
private $routes;
|
||||
private RouteCollection $routes;
|
||||
|
||||
public function __construct(RouteCollection $routes)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRoutes()
|
||||
public function getRoutes(): RouteCollection
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
@@ -23,15 +23,11 @@ interface MatcherDumperInterface
|
||||
/**
|
||||
* Dumps a set of routes to a string representation of executable code
|
||||
* that can then be used to match a request against these routes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dump(array $options = []);
|
||||
public function dump(array $options = []): string;
|
||||
|
||||
/**
|
||||
* Gets the routes to dump.
|
||||
*
|
||||
* @return RouteCollection
|
||||
*/
|
||||
public function getRoutes();
|
||||
public function getRoutes(): RouteCollection;
|
||||
}
|
||||
|
||||
@@ -23,22 +23,22 @@ use Symfony\Component\Routing\RouteCollection;
|
||||
*/
|
||||
class StaticPrefixCollection
|
||||
{
|
||||
private $prefix;
|
||||
private string $prefix;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $staticPrefixes = [];
|
||||
private array $staticPrefixes = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $prefixes = [];
|
||||
private array $prefixes = [];
|
||||
|
||||
/**
|
||||
* @var array[]|self[]
|
||||
*/
|
||||
private $items = [];
|
||||
private array $items = [];
|
||||
|
||||
public function __construct(string $prefix = '/')
|
||||
{
|
||||
@@ -60,10 +60,8 @@ class StaticPrefixCollection
|
||||
|
||||
/**
|
||||
* Adds a route to a group.
|
||||
*
|
||||
* @param array|self $route
|
||||
*/
|
||||
public function addRoute(string $prefix, $route)
|
||||
public function addRoute(string $prefix, array|self $route): void
|
||||
{
|
||||
[$prefix, $staticPrefix] = $this->getCommonPrefix($prefix, $prefix);
|
||||
|
||||
@@ -149,12 +147,12 @@ class StaticPrefixCollection
|
||||
$baseLength = \strlen($this->prefix);
|
||||
$end = min(\strlen($prefix), \strlen($anotherPrefix));
|
||||
$staticLength = null;
|
||||
set_error_handler([__CLASS__, 'handleError']);
|
||||
set_error_handler(self::handleError(...));
|
||||
|
||||
try {
|
||||
for ($i = $baseLength; $i < $end && $prefix[$i] === $anotherPrefix[$i]; ++$i) {
|
||||
if ('(' === $prefix[$i]) {
|
||||
$staticLength = $staticLength ?? $i;
|
||||
$staticLength ??= $i;
|
||||
for ($j = 1 + $i, $n = 1; $j < $end && 0 < $n; ++$j) {
|
||||
if ($prefix[$j] !== $anotherPrefix[$j]) {
|
||||
break 2;
|
||||
@@ -198,7 +196,7 @@ class StaticPrefixCollection
|
||||
return [substr($prefix, 0, $i), substr($prefix, 0, $staticLength ?? $i)];
|
||||
}
|
||||
|
||||
public static function handleError(int $type, string $msg)
|
||||
public static function handleError(int $type, string $msg): bool
|
||||
{
|
||||
return str_contains($msg, 'Compilation failed: lookbehind assertion is not fixed length');
|
||||
}
|
||||
|
||||
@@ -22,29 +22,22 @@ use Symfony\Contracts\Service\ServiceProviderInterface;
|
||||
*/
|
||||
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
|
||||
{
|
||||
private $functions;
|
||||
private ServiceProviderInterface $functions;
|
||||
|
||||
public function __construct(ServiceProviderInterface $functions)
|
||||
{
|
||||
$this->functions = $functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions()
|
||||
public function getFunctions(): array
|
||||
{
|
||||
$functions = [];
|
||||
|
||||
foreach ($this->functions->getProvidedServices() as $function => $type) {
|
||||
$functions[] = new ExpressionFunction(
|
||||
$function,
|
||||
static function (...$args) use ($function) {
|
||||
return sprintf('($context->getParameter(\'_functions\')->get(%s)(%s))', var_export($function, true), implode(', ', $args));
|
||||
},
|
||||
function ($values, ...$args) use ($function) {
|
||||
return $values['context']->getParameter('_functions')->get($function)(...$args);
|
||||
}
|
||||
static fn (...$args) => sprintf('($context->getParameter(\'_functions\')->get(%s)(%s))', var_export($function, true), implode(', ', $args)),
|
||||
fn ($values, ...$args) => $values['context']->getParameter('_functions')->get($function)(...$args)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,7 @@ use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
*/
|
||||
abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function match(string $pathinfo)
|
||||
public function match(string $pathinfo): array
|
||||
{
|
||||
try {
|
||||
return parent::match($pathinfo);
|
||||
@@ -39,7 +36,7 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
|
||||
$ret = parent::match($pathinfo);
|
||||
|
||||
return $this->redirect($pathinfo, $ret['_route'] ?? null, $this->context->getScheme()) + $ret;
|
||||
} catch (ExceptionInterface $e2) {
|
||||
} catch (ExceptionInterface) {
|
||||
throw $e;
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
@@ -52,7 +49,7 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
|
||||
$ret = parent::match($pathinfo);
|
||||
|
||||
return $this->redirect($pathinfo, $ret['_route'] ?? null) + $ret;
|
||||
} catch (ExceptionInterface $e2) {
|
||||
} catch (ExceptionInterface) {
|
||||
if ($this->allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ interface RedirectableUrlMatcherInterface
|
||||
* @param string $path The path info to redirect to
|
||||
* @param string $route The route name that matched
|
||||
* @param string|null $scheme The URL scheme (null to keep the current one)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function redirect(string $path, string $route, string $scheme = null);
|
||||
public function redirect(string $path, string $route, ?string $scheme = null): array;
|
||||
}
|
||||
|
||||
@@ -29,11 +29,9 @@ interface RequestMatcherInterface
|
||||
* If the matcher cannot find information, it must throw one of the exceptions documented
|
||||
* below.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws NoConfigurationException If no routing configuration could be found
|
||||
* @throws ResourceNotFoundException If no matching resource could be found
|
||||
* @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed
|
||||
*/
|
||||
public function matchRequest(Request $request);
|
||||
public function matchRequest(Request $request): array;
|
||||
}
|
||||
|
||||
@@ -29,18 +29,24 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
|
||||
protected $traces;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTraces(string $pathinfo)
|
||||
{
|
||||
$this->traces = [];
|
||||
|
||||
try {
|
||||
$this->match($pathinfo);
|
||||
} catch (ExceptionInterface $e) {
|
||||
} catch (ExceptionInterface) {
|
||||
}
|
||||
|
||||
return $this->traces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTracesForRequest(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
@@ -50,7 +56,7 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
return $traces;
|
||||
}
|
||||
|
||||
protected function matchCollection(string $pathinfo, RouteCollection $routes)
|
||||
protected function matchCollection(string $pathinfo, RouteCollection $routes): array
|
||||
{
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
@@ -99,7 +105,7 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
continue;
|
||||
}
|
||||
|
||||
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\{\w+\}/?$#', $route->getPath());
|
||||
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\{[\w\x80-\xFF]+\}/?$#', $route->getPath());
|
||||
|
||||
if ($hasTrailingVar && ($hasTrailingSlash || (null === $m = $matches[\count($compiledRoute->getPathVariables())] ?? null) || '/' !== ($m[-1] ?? '/')) && preg_match($regex, $trimmedPathinfo, $m)) {
|
||||
if ($hasTrailingSlash) {
|
||||
@@ -115,7 +121,9 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
|
||||
$attributes = $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
|
||||
|
||||
$status = $this->handleRouteRequirements($pathinfo, $name, $route, $attributes);
|
||||
|
||||
if (self::REQUIREMENT_MISMATCH === $status[0]) {
|
||||
$this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $route->getCondition()), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
@@ -146,19 +154,19 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
|
||||
$this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);
|
||||
|
||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, $status[1] ?? []));
|
||||
return array_replace($attributes, $status[1] ?? []);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private function addTrace(string $log, int $level = self::ROUTE_DOES_NOT_MATCH, string $name = null, Route $route = null)
|
||||
private function addTrace(string $log, int $level = self::ROUTE_DOES_NOT_MATCH, ?string $name = null, ?Route $route = null): void
|
||||
{
|
||||
$this->traces[] = [
|
||||
'log' => $log,
|
||||
'name' => $name,
|
||||
'level' => $level,
|
||||
'path' => null !== $route ? $route->getPath() : null,
|
||||
'path' => $route?->getPath(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
68
vendor/symfony/routing/Matcher/UrlMatcher.php
vendored
68
vendor/symfony/routing/Matcher/UrlMatcher.php
vendored
@@ -45,7 +45,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected $allowSchemes = [];
|
||||
protected array $allowSchemes = [];
|
||||
|
||||
protected $routes;
|
||||
protected $request;
|
||||
@@ -63,25 +63,19 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function setContext(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext()
|
||||
public function getContext(): RequestContext
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function match(string $pathinfo)
|
||||
public function match(string $pathinfo): array
|
||||
{
|
||||
$this->allow = $this->allowSchemes = [];
|
||||
|
||||
@@ -96,10 +90,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
throw 0 < \count($this->allow) ? new MethodNotAllowedException(array_unique($this->allow)) : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matchRequest(Request $request)
|
||||
public function matchRequest(Request $request): array
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
@@ -110,6 +101,9 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
||||
{
|
||||
$this->expressionLanguageProviders[] = $provider;
|
||||
@@ -120,13 +114,11 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
*
|
||||
* @param string $pathinfo The path info to be parsed
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws NoConfigurationException If no routing configuration could be found
|
||||
* @throws ResourceNotFoundException If the resource could not be found
|
||||
* @throws MethodNotAllowedException If the resource was found but the request method is not allowed
|
||||
*/
|
||||
protected function matchCollection(string $pathinfo, RouteCollection $routes)
|
||||
protected function matchCollection(string $pathinfo, RouteCollection $routes): array
|
||||
{
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
@@ -154,7 +146,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\{\w+\}/?$#', $route->getPath());
|
||||
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\{[\w\x80-\xFF]+\}/?$#', $route->getPath());
|
||||
|
||||
if ($hasTrailingVar && ($hasTrailingSlash || (null === $m = $matches[\count($compiledRoute->getPathVariables())] ?? null) || '/' !== ($m[-1] ?? '/')) && preg_match($regex, $trimmedPathinfo, $m)) {
|
||||
if ($hasTrailingSlash) {
|
||||
@@ -169,7 +161,9 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
|
||||
$attributes = $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
|
||||
|
||||
$status = $this->handleRouteRequirements($pathinfo, $name, $route, $attributes);
|
||||
|
||||
if (self::REQUIREMENT_MISMATCH === $status[0]) {
|
||||
continue;
|
||||
@@ -192,7 +186,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, $status[1] ?? []));
|
||||
return array_replace($attributes, $status[1] ?? []);
|
||||
}
|
||||
|
||||
return [];
|
||||
@@ -204,10 +198,8 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
* As this method requires the Route object, it is not available
|
||||
* in matchers that do not have access to the matched Route instance
|
||||
* (like the PHP and Apache matcher dumpers).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getAttributes(Route $route, string $name, array $attributes)
|
||||
protected function getAttributes(Route $route, string $name, array $attributes): array
|
||||
{
|
||||
$defaults = $route->getDefaults();
|
||||
if (isset($defaults['_canonical_route'])) {
|
||||
@@ -224,10 +216,25 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
*
|
||||
* @return array The first element represents the status, the second contains additional information
|
||||
*/
|
||||
protected function handleRouteRequirements(string $pathinfo, string $name, Route $route)
|
||||
protected function handleRouteRequirements(string $pathinfo, string $name, Route $route/* , array $routeParameters */): array
|
||||
{
|
||||
if (\func_num_args() < 4) {
|
||||
trigger_deprecation('symfony/routing', '6.1', 'The "%s()" method will have a new "array $routeParameters" argument in version 7.0, not defining it is deprecated.', __METHOD__);
|
||||
$routeParameters = [];
|
||||
} else {
|
||||
$routeParameters = func_get_arg(3);
|
||||
|
||||
if (!\is_array($routeParameters)) {
|
||||
throw new \TypeError(sprintf('"%s": Argument $routeParameters is expected to be an array, got "%s".', __METHOD__, get_debug_type($routeParameters)));
|
||||
}
|
||||
}
|
||||
|
||||
// expression condition
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), ['context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)])) {
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), [
|
||||
'context' => $this->context,
|
||||
'request' => $this->request ?: $this->createRequest($pathinfo),
|
||||
'params' => $routeParameters,
|
||||
])) {
|
||||
return [self::REQUIREMENT_MISMATCH, null];
|
||||
}
|
||||
|
||||
@@ -236,10 +243,8 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
|
||||
/**
|
||||
* Get merged default parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function mergeDefaults(array $params, array $defaults)
|
||||
protected function mergeDefaults(array $params, array $defaults): array
|
||||
{
|
||||
foreach ($params as $key => $value) {
|
||||
if (!\is_int($key) && null !== $value) {
|
||||
@@ -250,11 +255,14 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ExpressionLanguage
|
||||
*/
|
||||
protected function getExpressionLanguage()
|
||||
{
|
||||
if (null === $this->expressionLanguage) {
|
||||
if (!isset($this->expressionLanguage)) {
|
||||
if (!class_exists(ExpressionLanguage::class)) {
|
||||
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
|
||||
}
|
||||
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
|
||||
}
|
||||
|
||||
@@ -31,11 +31,9 @@ interface UrlMatcherInterface extends RequestContextAwareInterface
|
||||
*
|
||||
* @param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded)
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws NoConfigurationException If no routing configuration could be found
|
||||
* @throws ResourceNotFoundException If the resource could not be found
|
||||
* @throws MethodNotAllowedException If the resource was found but the request method is not allowed
|
||||
*/
|
||||
public function match(string $pathinfo);
|
||||
public function match(string $pathinfo): array;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user