Augmentation vers version 3.3.0
This commit is contained in:
50
vendor/symfony/routing/Annotation/Route.php
vendored
50
vendor/symfony/routing/Annotation/Route.php
vendored
@@ -23,12 +23,12 @@ class Route
|
||||
{
|
||||
private $path;
|
||||
private $name;
|
||||
private $requirements = array();
|
||||
private $options = array();
|
||||
private $defaults = array();
|
||||
private $requirements = [];
|
||||
private $options = [];
|
||||
private $defaults = [];
|
||||
private $host;
|
||||
private $methods = array();
|
||||
private $schemes = array();
|
||||
private $methods = [];
|
||||
private $schemes = [];
|
||||
private $condition;
|
||||
|
||||
/**
|
||||
@@ -52,26 +52,6 @@ class Route
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 2.2, to be removed in 3.0. Use setPath instead.
|
||||
*/
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.2 and will be removed in 3.0. Use the setPath() method instead and use the "path" option instead of the "pattern" option in the route definition.', E_USER_DEPRECATED);
|
||||
|
||||
$this->path = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 2.2, to be removed in 3.0. Use getPath instead.
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.2 and will be removed in 3.0. Use the getPath() method instead and use the "path" option instead of the "pattern" option in the route definition.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
@@ -104,22 +84,6 @@ class Route
|
||||
|
||||
public function setRequirements($requirements)
|
||||
{
|
||||
if (isset($requirements['_method'])) {
|
||||
if (0 === \count($this->methods)) {
|
||||
$this->methods = explode('|', $requirements['_method']);
|
||||
}
|
||||
|
||||
@trigger_error('The "_method" requirement is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "methods" option instead.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (isset($requirements['_scheme'])) {
|
||||
if (0 === \count($this->schemes)) {
|
||||
$this->schemes = explode('|', $requirements['_scheme']);
|
||||
}
|
||||
|
||||
@trigger_error('The "_scheme" requirement is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "schemes" option instead.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->requirements = $requirements;
|
||||
}
|
||||
|
||||
@@ -150,7 +114,7 @@ class Route
|
||||
|
||||
public function setSchemes($schemes)
|
||||
{
|
||||
$this->schemes = \is_array($schemes) ? $schemes : array($schemes);
|
||||
$this->schemes = \is_array($schemes) ? $schemes : [$schemes];
|
||||
}
|
||||
|
||||
public function getSchemes()
|
||||
@@ -160,7 +124,7 @@ class Route
|
||||
|
||||
public function setMethods($methods)
|
||||
{
|
||||
$this->methods = \is_array($methods) ? $methods : array($methods);
|
||||
$this->methods = \is_array($methods) ? $methods : [$methods];
|
||||
}
|
||||
|
||||
public function getMethods()
|
||||
|
||||
13
vendor/symfony/routing/CompiledRoute.php
vendored
13
vendor/symfony/routing/CompiledRoute.php
vendored
@@ -37,7 +37,7 @@ class CompiledRoute implements \Serializable
|
||||
* @param array $hostVariables An array of host variables
|
||||
* @param array $variables An array of variables (variables defined in the path and in the host patterns)
|
||||
*/
|
||||
public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array())
|
||||
public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = [], array $hostVariables = [], array $variables = [])
|
||||
{
|
||||
$this->staticPrefix = (string) $staticPrefix;
|
||||
$this->regex = $regex;
|
||||
@@ -54,7 +54,7 @@ class CompiledRoute implements \Serializable
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
return serialize([
|
||||
'vars' => $this->variables,
|
||||
'path_prefix' => $this->staticPrefix,
|
||||
'path_regex' => $this->regex,
|
||||
@@ -63,7 +63,7 @@ class CompiledRoute implements \Serializable
|
||||
'host_regex' => $this->hostRegex,
|
||||
'host_tokens' => $this->hostTokens,
|
||||
'host_vars' => $this->hostVariables,
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,12 @@ class CompiledRoute implements \Serializable
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($serialized);
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
$data = unserialize($serialized, ['allowed_classes' => false]);
|
||||
} else {
|
||||
$data = unserialize($serialized);
|
||||
}
|
||||
|
||||
$this->variables = $data['vars'];
|
||||
$this->staticPrefix = $data['path_prefix'];
|
||||
$this->regex = $data['path_regex'];
|
||||
|
||||
49
vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php
vendored
Normal file
49
vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Adds tagged routing.loader services to routing.resolver service.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RoutingResolverPass implements CompilerPassInterface
|
||||
{
|
||||
use PriorityTaggedServiceTrait;
|
||||
|
||||
private $resolverServiceId;
|
||||
private $loaderTag;
|
||||
|
||||
public function __construct($resolverServiceId = 'routing.resolver', $loaderTag = 'routing.loader')
|
||||
{
|
||||
$this->resolverServiceId = $resolverServiceId;
|
||||
$this->loaderTag = $loaderTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (false === $container->hasDefinition($this->resolverServiceId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition($this->resolverServiceId);
|
||||
|
||||
foreach ($this->findAndSortTaggedServices($this->loaderTag, $container) as $id) {
|
||||
$definition->addMethodCall('addLoader', [new Reference($id)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace Symfony\Component\Routing\Exception;
|
||||
*/
|
||||
class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
protected $allowedMethods = array();
|
||||
protected $allowedMethods = [];
|
||||
|
||||
public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null)
|
||||
{
|
||||
|
||||
21
vendor/symfony/routing/Exception/NoConfigurationException.php
vendored
Normal file
21
vendor/symfony/routing/Exception/NoConfigurationException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when no routes are configured.
|
||||
*
|
||||
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||
*/
|
||||
class NoConfigurationException extends ResourceNotFoundException
|
||||
{
|
||||
}
|
||||
@@ -28,7 +28,7 @@ interface GeneratorDumperInterface
|
||||
*
|
||||
* @return string Executable code
|
||||
*/
|
||||
public function dump(array $options = array());
|
||||
public function dump(array $options = []);
|
||||
|
||||
/**
|
||||
* Gets the routes to dump.
|
||||
|
||||
@@ -31,12 +31,12 @@ class PhpGeneratorDumper extends GeneratorDumper
|
||||
*
|
||||
* @return string A PHP class representing the generator class
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
public function dump(array $options = [])
|
||||
{
|
||||
$options = array_merge(array(
|
||||
$options = array_merge([
|
||||
'class' => 'ProjectUrlGenerator',
|
||||
'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
), $options);
|
||||
], $options);
|
||||
|
||||
return <<<EOF
|
||||
<?php
|
||||
@@ -76,11 +76,11 @@ EOF;
|
||||
*/
|
||||
private function generateDeclaredRoutes()
|
||||
{
|
||||
$routes = "array(\n";
|
||||
$routes = "[\n";
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
$properties = array();
|
||||
$properties = [];
|
||||
$properties[] = $compiledRoute->getVariables();
|
||||
$properties[] = $route->getDefaults();
|
||||
$properties[] = $route->getRequirements();
|
||||
@@ -90,7 +90,7 @@ EOF;
|
||||
|
||||
$routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
|
||||
}
|
||||
$routes .= ' )';
|
||||
$routes .= ' ]';
|
||||
|
||||
return $routes;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ EOF;
|
||||
private function generateGenerateMethod()
|
||||
{
|
||||
return <<<'EOF'
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (!isset(self::$declaredRoutes[$name])) {
|
||||
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
|
||||
|
||||
@@ -45,7 +45,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
* "?" and "#" (would be interpreted wrongly as query and fragment identifier),
|
||||
* "'" and """ (are used as delimiters in HTML).
|
||||
*/
|
||||
protected $decodedChars = array(
|
||||
protected $decodedChars = [
|
||||
// the slash can be used to designate a hierarchical structure and we want allow using it with this meaning
|
||||
// some webservers don't allow the slash in encoded form in the path for security reasons anyway
|
||||
// see http://stackoverflow.com/questions/4069002/http-400-if-2f-part-of-get-url-in-jboss
|
||||
@@ -63,7 +63,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
'%21' => '!',
|
||||
'%2A' => '*',
|
||||
'%7C' => '|',
|
||||
);
|
||||
];
|
||||
|
||||
public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null)
|
||||
{
|
||||
@@ -107,7 +107,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (null === $route = $this->routes->get($name)) {
|
||||
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
|
||||
@@ -123,23 +123,11 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
* @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
|
||||
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
|
||||
* it does not match the requirement
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array())
|
||||
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = [])
|
||||
{
|
||||
if (\is_bool($referenceType) || \is_string($referenceType)) {
|
||||
@trigger_error('The hardcoded value you are using for the $referenceType argument of the '.__CLASS__.'::generate method is deprecated since Symfony 2.8 and will not be supported anymore in 3.0. Use the constants defined in the UrlGeneratorInterface instead.', E_USER_DEPRECATED);
|
||||
|
||||
if (true === $referenceType) {
|
||||
$referenceType = self::ABSOLUTE_URL;
|
||||
} elseif (false === $referenceType) {
|
||||
$referenceType = self::ABSOLUTE_PATH;
|
||||
} elseif ('relative' === $referenceType) {
|
||||
$referenceType = self::RELATIVE_PATH;
|
||||
} elseif ('network' === $referenceType) {
|
||||
$referenceType = self::NETWORK_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
$variables = array_flip($variables);
|
||||
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
|
||||
|
||||
@@ -150,21 +138,21 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
|
||||
$url = '';
|
||||
$optional = true;
|
||||
$message = 'Parameter "{parameter}" for route "{route}" must match "{expected}" ("{given}" given) to generate a corresponding URL.';
|
||||
foreach ($tokens as $token) {
|
||||
if ('variable' === $token[0]) {
|
||||
if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) {
|
||||
// check requirement
|
||||
if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) {
|
||||
$message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]);
|
||||
if (!$optional || !\array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) {
|
||||
// check requirement (while ignoring look-around patterns)
|
||||
if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\(\?(?:=|<=|!|<!)((?:[^()\\\\]+|\\\\.|\((?1)\))*)\)/', '', $token[2]).'$#'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
|
||||
if ($this->strictRequirements) {
|
||||
throw new InvalidParameterException($message);
|
||||
throw new InvalidParameterException(strtr($message, ['{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]]));
|
||||
}
|
||||
|
||||
if ($this->logger) {
|
||||
$this->logger->error($message);
|
||||
$this->logger->error($message, ['parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]]);
|
||||
}
|
||||
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
$url = $token[1].$mergedParams[$token[3]].$url;
|
||||
@@ -187,7 +175,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
// the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
|
||||
// so we need to encode them as they are not used for this purpose here
|
||||
// otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
|
||||
$url = strtr($url, array('/../' => '/%2E%2E/', '/./' => '/%2E/'));
|
||||
$url = strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/']);
|
||||
if ('/..' === substr($url, -3)) {
|
||||
$url = substr($url, 0, -2).'%2E%2E';
|
||||
} elseif ('/.' === substr($url, -2)) {
|
||||
@@ -203,28 +191,23 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
$referenceType = self::ABSOLUTE_URL;
|
||||
$scheme = current($requiredSchemes);
|
||||
}
|
||||
} elseif (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) {
|
||||
// We do this for BC; to be removed if _scheme is not supported anymore
|
||||
$referenceType = self::ABSOLUTE_URL;
|
||||
$scheme = $req;
|
||||
}
|
||||
|
||||
if ($hostTokens) {
|
||||
$routeHost = '';
|
||||
foreach ($hostTokens as $token) {
|
||||
if ('variable' === $token[0]) {
|
||||
if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i', $mergedParams[$token[3]])) {
|
||||
$message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]);
|
||||
|
||||
// check requirement (while ignoring look-around patterns)
|
||||
if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\(\?(?:=|<=|!|<!)((?:[^()\\\\]+|\\\\.|\((?1)\))*)\)/', '', $token[2]).'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
|
||||
if ($this->strictRequirements) {
|
||||
throw new InvalidParameterException($message);
|
||||
throw new InvalidParameterException(strtr($message, ['{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]]));
|
||||
}
|
||||
|
||||
if ($this->logger) {
|
||||
$this->logger->error($message);
|
||||
$this->logger->error($message, ['parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]]);
|
||||
}
|
||||
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
$routeHost = $token[1].$mergedParams[$token[3]].$routeHost;
|
||||
@@ -241,16 +224,18 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
}
|
||||
}
|
||||
|
||||
if ((self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) && !empty($host)) {
|
||||
$port = '';
|
||||
if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
|
||||
$port = ':'.$this->context->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
|
||||
$port = ':'.$this->context->getHttpsPort();
|
||||
}
|
||||
if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) {
|
||||
if ('' !== $host || ('' !== $scheme && 'http' !== $scheme && 'https' !== $scheme)) {
|
||||
$port = '';
|
||||
if ('http' === $scheme && 80 !== $this->context->getHttpPort()) {
|
||||
$port = ':'.$this->context->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 !== $this->context->getHttpsPort()) {
|
||||
$port = ':'.$this->context->getHttpsPort();
|
||||
}
|
||||
|
||||
$schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "$scheme://";
|
||||
$schemeAuthority .= $host.$port;
|
||||
$schemeAuthority = self::NETWORK_PATH === $referenceType || '' === $scheme ? '//' : "$scheme://";
|
||||
$schemeAuthority .= $host.$port;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::RELATIVE_PATH === $referenceType) {
|
||||
@@ -264,10 +249,25 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
return $a == $b ? 0 : 1;
|
||||
});
|
||||
|
||||
if ($extra && $query = http_build_query($extra, '', '&')) {
|
||||
// extract fragment
|
||||
$fragment = '';
|
||||
if (isset($defaults['_fragment'])) {
|
||||
$fragment = $defaults['_fragment'];
|
||||
}
|
||||
|
||||
if (isset($extra['_fragment'])) {
|
||||
$fragment = $extra['_fragment'];
|
||||
unset($extra['_fragment']);
|
||||
}
|
||||
|
||||
if ($extra && $query = http_build_query($extra, '', '&', PHP_QUERY_RFC3986)) {
|
||||
// "/" and "?" can be left decoded for better user experience, see
|
||||
// http://tools.ietf.org/html/rfc3986#section-3.4
|
||||
$url .= '?'.strtr($query, array('%2F' => '/'));
|
||||
$url .= '?'.strtr($query, ['%2F' => '/']);
|
||||
}
|
||||
|
||||
if ('' !== $fragment) {
|
||||
$url .= '#'.strtr(rawurlencode($fragment), ['%2F' => '/', '%3F' => '?']);
|
||||
}
|
||||
|
||||
return $url;
|
||||
|
||||
@@ -69,9 +69,11 @@ interface UrlGeneratorInterface extends RequestContextAwareInterface
|
||||
*
|
||||
* If there is no route with the given name, the generator must throw the RouteNotFoundException.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed $parameters An array of parameters
|
||||
* @param int $referenceType The type of reference to be generated (one of the constants)
|
||||
* The special parameter _fragment will be used as the document fragment suffixed to the final URL.
|
||||
*
|
||||
* @param string $name The name of the route
|
||||
* @param mixed[] $parameters An array of parameters
|
||||
* @param int $referenceType The type of reference to be generated (one of the constants)
|
||||
*
|
||||
* @return string The generated URL
|
||||
*
|
||||
@@ -80,5 +82,5 @@ interface UrlGeneratorInterface extends RequestContextAwareInterface
|
||||
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
|
||||
* it does not match the requirement
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH);
|
||||
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH);
|
||||
}
|
||||
|
||||
2
vendor/symfony/routing/LICENSE
vendored
2
vendor/symfony/routing/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2004-2018 Fabien Potencier
|
||||
Copyright (c) 2004-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -15,6 +15,7 @@ use Doctrine\Common\Annotations\Reader;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\Config\Loader\LoaderResolverInterface;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Routing\Annotation\Route as RouteAnnotation;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
@@ -32,7 +33,6 @@ use Symfony\Component\Routing\RouteCollection;
|
||||
* recognizes several parameters: requirements, options, defaults, schemes,
|
||||
* methods, host, and name. The name parameter is mandatory.
|
||||
* Here is an example of how you should be able to use it:
|
||||
*
|
||||
* /**
|
||||
* * @Route("/Blog")
|
||||
* * /
|
||||
@@ -44,7 +44,6 @@ use Symfony\Component\Routing\RouteCollection;
|
||||
* public function index()
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* /**
|
||||
* * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
|
||||
* * /
|
||||
@@ -119,15 +118,29 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === $collection->count() && $class->hasMethod('__invoke')) {
|
||||
$globals = $this->resetGlobals();
|
||||
foreach ($this->reader->getClassAnnotations($class) as $annot) {
|
||||
if ($annot instanceof $this->routeAnnotationClass) {
|
||||
$this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RouteAnnotation $annot or an object that exposes a similar interface
|
||||
* @param array $globals
|
||||
*/
|
||||
protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method)
|
||||
{
|
||||
$name = $annot->getName();
|
||||
if (null === $name) {
|
||||
$name = $this->getDefaultRouteName($class, $method);
|
||||
}
|
||||
$name = $globals['name'].$name;
|
||||
|
||||
$defaults = array_replace($globals['defaults'], $annot->getDefaults());
|
||||
foreach ($method->getParameters() as $param) {
|
||||
@@ -182,14 +195,12 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
/**
|
||||
* Gets the default route name for a class method.
|
||||
*
|
||||
* @param \ReflectionClass $class
|
||||
* @param \ReflectionMethod $method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
|
||||
{
|
||||
$name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name);
|
||||
$name = str_replace('\\', '_', $class->name).'_'.$method->name;
|
||||
$name = \function_exists('mb_strtolower') && preg_match('//u', $name) ? mb_strtolower($name, 'UTF-8') : strtolower($name);
|
||||
if ($this->defaultRouteIndex > 0) {
|
||||
$name .= '_'.$this->defaultRouteIndex;
|
||||
}
|
||||
@@ -200,23 +211,15 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
|
||||
protected function getGlobals(\ReflectionClass $class)
|
||||
{
|
||||
$globals = array(
|
||||
'path' => '',
|
||||
'requirements' => array(),
|
||||
'options' => array(),
|
||||
'defaults' => array(),
|
||||
'schemes' => array(),
|
||||
'methods' => array(),
|
||||
'host' => '',
|
||||
'condition' => '',
|
||||
);
|
||||
$globals = $this->resetGlobals();
|
||||
|
||||
if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
|
||||
// for BC reasons
|
||||
if (null !== $annot->getName()) {
|
||||
$globals['name'] = $annot->getName();
|
||||
}
|
||||
|
||||
if (null !== $annot->getPath()) {
|
||||
$globals['path'] = $annot->getPath();
|
||||
} elseif (null !== $annot->getPattern()) {
|
||||
$globals['path'] = $annot->getPattern();
|
||||
}
|
||||
|
||||
if (null !== $annot->getRequirements()) {
|
||||
@@ -251,6 +254,21 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
return $globals;
|
||||
}
|
||||
|
||||
private function resetGlobals()
|
||||
{
|
||||
return [
|
||||
'path' => '',
|
||||
'requirements' => [],
|
||||
'options' => [],
|
||||
'defaults' => [],
|
||||
'schemes' => [],
|
||||
'methods' => [],
|
||||
'host' => '',
|
||||
'condition' => '',
|
||||
'name' => '',
|
||||
];
|
||||
}
|
||||
|
||||
protected function createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition)
|
||||
{
|
||||
return new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
|
||||
|
||||
@@ -34,13 +34,15 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
|
||||
*/
|
||||
public function load($path, $type = null)
|
||||
{
|
||||
$dir = $this->locator->locate($path);
|
||||
if (!is_dir($dir = $this->locator->locate($path))) {
|
||||
return parent::supports($path, $type) ? parent::load($path, $type) : new RouteCollection();
|
||||
}
|
||||
|
||||
$collection = new RouteCollection();
|
||||
$collection->addResource(new DirectoryResource($dir, '/\.php$/'));
|
||||
$files = iterator_to_array(new \RecursiveIteratorIterator(
|
||||
new RecursiveCallbackFilterIterator(
|
||||
new \RecursiveDirectoryIterator($dir),
|
||||
new \RecursiveCallbackFilterIterator(
|
||||
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
|
||||
function (\SplFileInfo $current) {
|
||||
return '.' !== substr($current->getBasename(), 0, 1);
|
||||
}
|
||||
@@ -74,47 +76,18 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
if (!\is_string($resource)) {
|
||||
if ('annotation' === $type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($type || !\is_string($resource)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$path = $this->locator->locate($resource);
|
||||
return is_dir($this->locator->locate($resource));
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_dir($path) && (!$type || 'annotation' === $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal To be removed as RecursiveCallbackFilterIterator is available since PHP 5.4
|
||||
*/
|
||||
class RecursiveCallbackFilterIterator extends \FilterIterator implements \RecursiveIterator
|
||||
{
|
||||
private $iterator;
|
||||
private $callback;
|
||||
|
||||
public function __construct(\RecursiveIterator $iterator, $callback)
|
||||
{
|
||||
$this->iterator = $iterator;
|
||||
$this->callback = $callback;
|
||||
parent::__construct($iterator);
|
||||
}
|
||||
|
||||
public function accept()
|
||||
{
|
||||
return \call_user_func($this->callback, $this->current(), $this->key(), $this->iterator);
|
||||
}
|
||||
|
||||
public function hasChildren()
|
||||
{
|
||||
return $this->iterator->hasChildren();
|
||||
}
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
return new static($this->iterator->getChildren(), $this->callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class AnnotationFileLoader extends FileLoader
|
||||
* @param string $file A PHP file path
|
||||
* @param string|null $type The resource type
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
* @return RouteCollection|null A RouteCollection instance
|
||||
*
|
||||
* @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
|
||||
*/
|
||||
@@ -56,6 +56,11 @@ class AnnotationFileLoader extends FileLoader
|
||||
|
||||
$collection = new RouteCollection();
|
||||
if ($class = $this->findClass($path)) {
|
||||
$refl = new \ReflectionClass($class);
|
||||
if ($refl->isAbstract()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$collection->addResource(new FileResource($path));
|
||||
$collection->addCollection($this->loader->load($class, $type));
|
||||
}
|
||||
@@ -87,6 +92,11 @@ class AnnotationFileLoader extends FileLoader
|
||||
$class = false;
|
||||
$namespace = false;
|
||||
$tokens = token_get_all(file_get_contents($file));
|
||||
|
||||
if (1 === \count($tokens) && T_INLINE_HTML === $tokens[0][0]) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not contain PHP code. Did you forgot to add the "<?php" start tag at the beginning of the file?', $file));
|
||||
}
|
||||
|
||||
for ($i = 0; isset($tokens[$i]); ++$i) {
|
||||
$token = $tokens[$i];
|
||||
|
||||
@@ -100,7 +110,7 @@ class AnnotationFileLoader extends FileLoader
|
||||
|
||||
if (true === $namespace && T_STRING === $token[0]) {
|
||||
$namespace = $token[1];
|
||||
while (isset($tokens[++$i][1]) && \in_array($tokens[$i][0], array(T_NS_SEPARATOR, T_STRING))) {
|
||||
while (isset($tokens[++$i][1]) && \in_array($tokens[$i][0], [T_NS_SEPARATOR, T_STRING])) {
|
||||
$namespace .= $tokens[$i][1];
|
||||
}
|
||||
$token = $tokens[$i];
|
||||
@@ -117,7 +127,7 @@ class AnnotationFileLoader extends FileLoader
|
||||
if (T_DOUBLE_COLON === $tokens[$j][0] || T_NEW === $tokens[$j][0]) {
|
||||
$skipClassToken = true;
|
||||
break;
|
||||
} elseif (!\in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
|
||||
} elseif (!\in_array($tokens[$j][0], [T_WHITESPACE, T_DOC_COMMENT, T_COMMENT])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
81
vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php
vendored
Normal file
81
vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CollectionConfigurator
|
||||
{
|
||||
use Traits\AddTrait;
|
||||
use Traits\RouteTrait;
|
||||
|
||||
private $parent;
|
||||
private $parentConfigurator;
|
||||
|
||||
public function __construct(RouteCollection $parent, $name, self $parentConfigurator = null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->name = $name;
|
||||
$this->collection = new RouteCollection();
|
||||
$this->route = new Route('');
|
||||
$this->parentConfigurator = $parentConfigurator; // for GC control
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->collection->addPrefix(rtrim($this->route->getPath(), '/'));
|
||||
$this->parent->addCollection($this->collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a route.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $path
|
||||
*
|
||||
* @return RouteConfigurator
|
||||
*/
|
||||
final public function add($name, $path)
|
||||
{
|
||||
$this->collection->add($this->name.$name, $route = clone $this->route);
|
||||
|
||||
return new RouteConfigurator($this->collection, $route->setPath($path), $this->name, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a sub-collection.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
final public function collection($name = '')
|
||||
{
|
||||
return new self($this->collection, $this->name.$name, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the prefix to add to the path of all child routes.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function prefix($prefix)
|
||||
{
|
||||
$this->route->setPath($prefix);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
49
vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php
vendored
Normal file
49
vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ImportConfigurator
|
||||
{
|
||||
use Traits\RouteTrait;
|
||||
|
||||
private $parent;
|
||||
|
||||
public function __construct(RouteCollection $parent, RouteCollection $route)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->route = $route;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->parent->addCollection($this->route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the prefix to add to the path of all child routes.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function prefix($prefix)
|
||||
{
|
||||
$this->route->addPrefix($prefix);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
34
vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php
vendored
Normal file
34
vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class RouteConfigurator
|
||||
{
|
||||
use Traits\AddTrait;
|
||||
use Traits\RouteTrait;
|
||||
|
||||
private $parentConfigurator;
|
||||
|
||||
public function __construct(RouteCollection $collection, Route $route, $name = '', CollectionConfigurator $parentConfigurator = null)
|
||||
{
|
||||
$this->collection = $collection;
|
||||
$this->route = $route;
|
||||
$this->name = $name;
|
||||
$this->parentConfigurator = $parentConfigurator; // for GC control
|
||||
}
|
||||
}
|
||||
63
vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php
vendored
Normal file
63
vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\Routing\Loader\PhpFileLoader;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class RoutingConfigurator
|
||||
{
|
||||
use Traits\AddTrait;
|
||||
|
||||
private $loader;
|
||||
private $path;
|
||||
private $file;
|
||||
|
||||
public function __construct(RouteCollection $collection, PhpFileLoader $loader, $path, $file)
|
||||
{
|
||||
$this->collection = $collection;
|
||||
$this->loader = $loader;
|
||||
$this->path = $path;
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ImportConfigurator
|
||||
*/
|
||||
final public function import($resource, $type = null, $ignoreErrors = false)
|
||||
{
|
||||
$this->loader->setCurrentDir(\dirname($this->path));
|
||||
$imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file) ?: [];
|
||||
|
||||
if (!\is_array($imported)) {
|
||||
return new ImportConfigurator($this->collection, $imported);
|
||||
}
|
||||
|
||||
$mergedCollection = new RouteCollection();
|
||||
foreach ($imported as $subCollection) {
|
||||
$mergedCollection->addCollection($subCollection);
|
||||
}
|
||||
|
||||
return new ImportConfigurator($this->collection, $mergedCollection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionConfigurator
|
||||
*/
|
||||
final public function collection($name = '')
|
||||
{
|
||||
return new CollectionConfigurator($this->collection, $name);
|
||||
}
|
||||
}
|
||||
55
vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php
vendored
Normal file
55
vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
trait AddTrait
|
||||
{
|
||||
/**
|
||||
* @var RouteCollection
|
||||
*/
|
||||
private $collection;
|
||||
|
||||
private $name = '';
|
||||
|
||||
/**
|
||||
* Adds a route.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $path
|
||||
*
|
||||
* @return RouteConfigurator
|
||||
*/
|
||||
final public function add($name, $path)
|
||||
{
|
||||
$parentConfigurator = $this instanceof RouteConfigurator ? $this->parentConfigurator : null;
|
||||
$this->collection->add($this->name.$name, $route = new Route($path));
|
||||
|
||||
return new RouteConfigurator($this->collection, $route, '', $parentConfigurator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a route.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $path
|
||||
*
|
||||
* @return RouteConfigurator
|
||||
*/
|
||||
final public function __invoke($name, $path)
|
||||
{
|
||||
return $this->add($name, $path);
|
||||
}
|
||||
}
|
||||
131
vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php
vendored
Normal file
131
vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
trait RouteTrait
|
||||
{
|
||||
/**
|
||||
* @var RouteCollection|Route
|
||||
*/
|
||||
private $route;
|
||||
|
||||
/**
|
||||
* Adds defaults.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function defaults(array $defaults)
|
||||
{
|
||||
$this->route->addDefaults($defaults);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds requirements.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function requirements(array $requirements)
|
||||
{
|
||||
$this->route->addRequirements($requirements);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function options(array $options)
|
||||
{
|
||||
$this->route->addOptions($options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the condition.
|
||||
*
|
||||
* @param string $condition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function condition($condition)
|
||||
{
|
||||
$this->route->setCondition($condition);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pattern for the host.
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function host($pattern)
|
||||
{
|
||||
$this->route->setHost($pattern);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the schemes (e.g. 'https') this route is restricted to.
|
||||
* So an empty array means that any scheme is allowed.
|
||||
*
|
||||
* @param string[] $schemes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function schemes(array $schemes)
|
||||
{
|
||||
$this->route->setSchemes($schemes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP methods (e.g. 'POST') this route is restricted to.
|
||||
* So an empty array means that any method is allowed.
|
||||
*
|
||||
* @param string[] $methods
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function methods(array $methods)
|
||||
{
|
||||
$this->route->setMethods($methods);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the "_controller" entry to defaults.
|
||||
*
|
||||
* @param callable|string $controller a callable or parseable pseudo-callable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function controller($controller)
|
||||
{
|
||||
$this->route->addDefaults(['_controller' => $controller]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,12 @@
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\Routing\Loader\ObjectRouteLoader;
|
||||
|
||||
/**
|
||||
* A route loader that executes a service to load the routes.
|
||||
*
|
||||
* This depends on the DependencyInjection component.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*/
|
||||
class ServiceRouterLoader extends ObjectRouteLoader
|
||||
|
||||
47
vendor/symfony/routing/Loader/GlobFileLoader.php
vendored
Normal file
47
vendor/symfony/routing/Loader/GlobFileLoader.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* GlobFileLoader loads files from a glob pattern.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class GlobFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$collection = new RouteCollection();
|
||||
|
||||
foreach ($this->glob($resource, false, $globResource) as $path => $info) {
|
||||
$collection->addCollection($this->import($path));
|
||||
}
|
||||
|
||||
$collection->addResource($globResource);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return 'glob' === $type;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ abstract class ObjectRouteLoader extends Loader
|
||||
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, \get_class($loaderObject), $resource));
|
||||
}
|
||||
|
||||
$routeCollection = \call_user_func(array($loaderObject, $method), $this);
|
||||
$routeCollection = \call_user_func([$loaderObject, $method], $this);
|
||||
|
||||
if (!$routeCollection instanceof RouteCollection) {
|
||||
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
|
||||
|
||||
37
vendor/symfony/routing/Loader/PhpFileLoader.php
vendored
37
vendor/symfony/routing/Loader/PhpFileLoader.php
vendored
@@ -13,6 +13,7 @@ namespace Symfony\Component\Routing\Loader;
|
||||
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,21 @@ class PhpFileLoader extends FileLoader
|
||||
$path = $this->locator->locate($file);
|
||||
$this->setCurrentDir(\dirname($path));
|
||||
|
||||
$collection = self::includeFile($path, $this);
|
||||
// the closure forbids access to the private scope in the included file
|
||||
$loader = $this;
|
||||
$load = \Closure::bind(static function ($file) use ($loader) {
|
||||
return include $file;
|
||||
}, null, ProtectedPhpFileLoader::class);
|
||||
|
||||
$result = $load($path);
|
||||
|
||||
if ($result instanceof \Closure) {
|
||||
$collection = new RouteCollection();
|
||||
$result(new RoutingConfigurator($collection, $this, $path, $file));
|
||||
} else {
|
||||
$collection = $result;
|
||||
}
|
||||
|
||||
$collection->addResource(new FileResource($path));
|
||||
|
||||
return $collection;
|
||||
@@ -50,17 +65,11 @@ class PhpFileLoader extends FileLoader
|
||||
{
|
||||
return \is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe include. Used for scope isolation.
|
||||
*
|
||||
* @param string $file File to include
|
||||
* @param PhpFileLoader $loader The loader variable is exposed to the included file below
|
||||
*
|
||||
* @return RouteCollection
|
||||
*/
|
||||
private static function includeFile($file, PhpFileLoader $loader)
|
||||
{
|
||||
return include $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class ProtectedPhpFileLoader extends PhpFileLoader
|
||||
{
|
||||
}
|
||||
|
||||
201
vendor/symfony/routing/Loader/XmlFileLoader.php
vendored
201
vendor/symfony/routing/Loader/XmlFileLoader.php
vendored
@@ -107,44 +107,15 @@ class XmlFileLoader extends FileLoader
|
||||
*/
|
||||
protected function parseRoute(RouteCollection $collection, \DOMElement $node, $path)
|
||||
{
|
||||
if ('' === ($id = $node->getAttribute('id')) || (!$node->hasAttribute('pattern') && !$node->hasAttribute('path'))) {
|
||||
if ('' === ($id = $node->getAttribute('id')) || !$node->hasAttribute('path')) {
|
||||
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "path" attribute.', $path));
|
||||
}
|
||||
|
||||
if ($node->hasAttribute('pattern')) {
|
||||
if ($node->hasAttribute('path')) {
|
||||
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path));
|
||||
}
|
||||
|
||||
@trigger_error(sprintf('The "pattern" option in file "%s" is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "path" option in the route definition instead.', $path), E_USER_DEPRECATED);
|
||||
|
||||
$node->setAttribute('path', $node->getAttribute('pattern'));
|
||||
$node->removeAttribute('pattern');
|
||||
}
|
||||
|
||||
$schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY);
|
||||
$methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
|
||||
|
||||
if (isset($requirements['_method'])) {
|
||||
if (0 === \count($methods)) {
|
||||
$methods = explode('|', $requirements['_method']);
|
||||
}
|
||||
|
||||
unset($requirements['_method']);
|
||||
@trigger_error(sprintf('The "_method" requirement of route "%s" in file "%s" is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "methods" attribute instead.', $id, $path), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (isset($requirements['_scheme'])) {
|
||||
if (0 === \count($schemes)) {
|
||||
$schemes = explode('|', $requirements['_scheme']);
|
||||
}
|
||||
|
||||
unset($requirements['_scheme']);
|
||||
@trigger_error(sprintf('The "_scheme" requirement of route "%s" in file "%s" is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "schemes" attribute instead.', $id, $path), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
|
||||
$collection->add($id, $route);
|
||||
}
|
||||
@@ -175,26 +146,34 @@ class XmlFileLoader extends FileLoader
|
||||
|
||||
$this->setCurrentDir(\dirname($path));
|
||||
|
||||
$subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file);
|
||||
/* @var $subCollection RouteCollection */
|
||||
$subCollection->addPrefix($prefix);
|
||||
if (null !== $host) {
|
||||
$subCollection->setHost($host);
|
||||
}
|
||||
if (null !== $condition) {
|
||||
$subCollection->setCondition($condition);
|
||||
}
|
||||
if (null !== $schemes) {
|
||||
$subCollection->setSchemes($schemes);
|
||||
}
|
||||
if (null !== $methods) {
|
||||
$subCollection->setMethods($methods);
|
||||
}
|
||||
$subCollection->addDefaults($defaults);
|
||||
$subCollection->addRequirements($requirements);
|
||||
$subCollection->addOptions($options);
|
||||
/** @var RouteCollection[] $imported */
|
||||
$imported = $this->import($resource, ('' !== $type ? $type : null), false, $file) ?: [];
|
||||
|
||||
$collection->addCollection($subCollection);
|
||||
if (!\is_array($imported)) {
|
||||
$imported = [$imported];
|
||||
}
|
||||
|
||||
foreach ($imported as $subCollection) {
|
||||
/* @var $subCollection RouteCollection */
|
||||
$subCollection->addPrefix($prefix);
|
||||
if (null !== $host) {
|
||||
$subCollection->setHost($host);
|
||||
}
|
||||
if (null !== $condition) {
|
||||
$subCollection->setCondition($condition);
|
||||
}
|
||||
if (null !== $schemes) {
|
||||
$subCollection->setSchemes($schemes);
|
||||
}
|
||||
if (null !== $methods) {
|
||||
$subCollection->setMethods($methods);
|
||||
}
|
||||
$subCollection->addDefaults($defaults);
|
||||
$subCollection->addRequirements($requirements);
|
||||
$subCollection->addOptions($options);
|
||||
|
||||
$collection->addCollection($subCollection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,18 +204,23 @@ class XmlFileLoader extends FileLoader
|
||||
*/
|
||||
private function parseConfigs(\DOMElement $node, $path)
|
||||
{
|
||||
$defaults = array();
|
||||
$requirements = array();
|
||||
$options = array();
|
||||
$defaults = [];
|
||||
$requirements = [];
|
||||
$options = [];
|
||||
$condition = null;
|
||||
|
||||
/** @var \DOMElement $n */
|
||||
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
|
||||
if ($node !== $n->parentNode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($n->localName) {
|
||||
case 'default':
|
||||
if ($this->isElementValueNull($n)) {
|
||||
$defaults[$n->getAttribute('key')] = null;
|
||||
} else {
|
||||
$defaults[$n->getAttribute('key')] = trim($n->textContent);
|
||||
$defaults[$n->getAttribute('key')] = $this->parseDefaultsConfig($n, $path);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -244,7 +228,7 @@ class XmlFileLoader extends FileLoader
|
||||
$requirements[$n->getAttribute('key')] = trim($n->textContent);
|
||||
break;
|
||||
case 'option':
|
||||
$options[$n->getAttribute('key')] = trim($n->textContent);
|
||||
$options[$n->getAttribute('key')] = XmlUtils::phpize(trim($n->textContent));
|
||||
break;
|
||||
case 'condition':
|
||||
$condition = trim($n->textContent);
|
||||
@@ -254,7 +238,114 @@ class XmlFileLoader extends FileLoader
|
||||
}
|
||||
}
|
||||
|
||||
return array($defaults, $requirements, $options, $condition);
|
||||
if ($controller = $node->getAttribute('controller')) {
|
||||
if (isset($defaults['_controller'])) {
|
||||
$name = $node->hasAttribute('id') ? sprintf('"%s"', $node->getAttribute('id')) : sprintf('the "%s" tag', $node->tagName);
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" attribute and the defaults key "_controller" for %s.', $path, $name));
|
||||
}
|
||||
|
||||
$defaults['_controller'] = $controller;
|
||||
}
|
||||
|
||||
return [$defaults, $requirements, $options, $condition];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the "default" elements.
|
||||
*
|
||||
* @param \DOMElement $element The "default" element to parse
|
||||
* @param string $path Full path of the XML file being processed
|
||||
*
|
||||
* @return array|bool|float|int|string|null The parsed value of the "default" element
|
||||
*/
|
||||
private function parseDefaultsConfig(\DOMElement $element, $path)
|
||||
{
|
||||
if ($this->isElementValueNull($element)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check for existing element nodes in the default element. There can
|
||||
// only be a single element inside a default element. So this element
|
||||
// (if one was found) can safely be returned.
|
||||
foreach ($element->childNodes as $child) {
|
||||
if (!$child instanceof \DOMElement) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::NAMESPACE_URI !== $child->namespaceURI) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->parseDefaultNode($child, $path);
|
||||
}
|
||||
|
||||
// If the default element doesn't contain a nested "bool", "int", "float",
|
||||
// "string", "list", or "map" element, the element contents will be treated
|
||||
// as the string value of the associated default option.
|
||||
return trim($element->textContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively parses the value of a "default" element.
|
||||
*
|
||||
* @param \DOMElement $node The node value
|
||||
* @param string $path Full path of the XML file being processed
|
||||
*
|
||||
* @return array|bool|float|int|string The parsed value
|
||||
*
|
||||
* @throws \InvalidArgumentException when the XML is invalid
|
||||
*/
|
||||
private function parseDefaultNode(\DOMElement $node, $path)
|
||||
{
|
||||
if ($this->isElementValueNull($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch ($node->localName) {
|
||||
case 'bool':
|
||||
return 'true' === trim($node->nodeValue) || '1' === trim($node->nodeValue);
|
||||
case 'int':
|
||||
return (int) trim($node->nodeValue);
|
||||
case 'float':
|
||||
return (float) trim($node->nodeValue);
|
||||
case 'string':
|
||||
return trim($node->nodeValue);
|
||||
case 'list':
|
||||
$list = [];
|
||||
|
||||
foreach ($node->childNodes as $element) {
|
||||
if (!$element instanceof \DOMElement) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::NAMESPACE_URI !== $element->namespaceURI) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$list[] = $this->parseDefaultNode($element, $path);
|
||||
}
|
||||
|
||||
return $list;
|
||||
case 'map':
|
||||
$map = [];
|
||||
|
||||
foreach ($node->childNodes as $element) {
|
||||
if (!$element instanceof \DOMElement) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::NAMESPACE_URI !== $element->namespaceURI) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$map[$element->getAttribute('key')] = $this->parseDefaultNode($element, $path);
|
||||
}
|
||||
|
||||
return $map;
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "bool", "int", "float", "string", "list", or "map".', $node->localName, $path));
|
||||
}
|
||||
}
|
||||
|
||||
private function isElementValueNull(\DOMElement $element)
|
||||
|
||||
115
vendor/symfony/routing/Loader/YamlFileLoader.php
vendored
115
vendor/symfony/routing/Loader/YamlFileLoader.php
vendored
@@ -26,9 +26,9 @@ use Symfony\Component\Yaml\Parser as YamlParser;
|
||||
*/
|
||||
class YamlFileLoader extends FileLoader
|
||||
{
|
||||
private static $availableKeys = array(
|
||||
'resource', 'type', 'prefix', 'pattern', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition',
|
||||
);
|
||||
private static $availableKeys = [
|
||||
'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller',
|
||||
];
|
||||
private $yamlParser;
|
||||
|
||||
/**
|
||||
@@ -57,10 +57,18 @@ class YamlFileLoader extends FileLoader
|
||||
$this->yamlParser = new YamlParser();
|
||||
}
|
||||
|
||||
$prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($file, &$prevErrorHandler) {
|
||||
$message = E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$file.'"$0', $message) : $message;
|
||||
|
||||
return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false;
|
||||
});
|
||||
|
||||
try {
|
||||
$parsedConfig = $this->yamlParser->parse(file_get_contents($path));
|
||||
$parsedConfig = $this->yamlParser->parseFile($path);
|
||||
} catch (ParseException $e) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
$collection = new RouteCollection();
|
||||
@@ -77,17 +85,6 @@ class YamlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
foreach ($parsedConfig as $name => $config) {
|
||||
if (isset($config['pattern'])) {
|
||||
if (isset($config['path'])) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path));
|
||||
}
|
||||
|
||||
@trigger_error(sprintf('The "pattern" option in file "%s" is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "path" option in the route definition instead.', $path), E_USER_DEPRECATED);
|
||||
|
||||
$config['path'] = $config['pattern'];
|
||||
unset($config['pattern']);
|
||||
}
|
||||
|
||||
$this->validate($config, $name, $path);
|
||||
|
||||
if (isset($config['resource'])) {
|
||||
@@ -105,7 +102,7 @@ class YamlFileLoader extends FileLoader
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return \is_string($resource) && \in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true) && (!$type || 'yaml' === $type);
|
||||
return \is_string($resource) && \in_array(pathinfo($resource, PATHINFO_EXTENSION), ['yml', 'yaml'], true) && (!$type || 'yaml' === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,30 +115,16 @@ class YamlFileLoader extends FileLoader
|
||||
*/
|
||||
protected function parseRoute(RouteCollection $collection, $name, array $config, $path)
|
||||
{
|
||||
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
|
||||
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
|
||||
$options = isset($config['options']) ? $config['options'] : array();
|
||||
$defaults = isset($config['defaults']) ? $config['defaults'] : [];
|
||||
$requirements = isset($config['requirements']) ? $config['requirements'] : [];
|
||||
$options = isset($config['options']) ? $config['options'] : [];
|
||||
$host = isset($config['host']) ? $config['host'] : '';
|
||||
$schemes = isset($config['schemes']) ? $config['schemes'] : array();
|
||||
$methods = isset($config['methods']) ? $config['methods'] : array();
|
||||
$schemes = isset($config['schemes']) ? $config['schemes'] : [];
|
||||
$methods = isset($config['methods']) ? $config['methods'] : [];
|
||||
$condition = isset($config['condition']) ? $config['condition'] : null;
|
||||
|
||||
if (isset($requirements['_method'])) {
|
||||
if (0 === \count($methods)) {
|
||||
$methods = explode('|', $requirements['_method']);
|
||||
}
|
||||
|
||||
unset($requirements['_method']);
|
||||
@trigger_error(sprintf('The "_method" requirement of route "%s" in file "%s" is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "methods" option instead.', $name, $path), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (isset($requirements['_scheme'])) {
|
||||
if (0 === \count($schemes)) {
|
||||
$schemes = explode('|', $requirements['_scheme']);
|
||||
}
|
||||
|
||||
unset($requirements['_scheme']);
|
||||
@trigger_error(sprintf('The "_scheme" requirement of route "%s" in file "%s" is deprecated since Symfony 2.2 and will be removed in 3.0. Use the "schemes" option instead.', $name, $path), E_USER_DEPRECATED);
|
||||
if (isset($config['controller'])) {
|
||||
$defaults['_controller'] = $config['controller'];
|
||||
}
|
||||
|
||||
$route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
|
||||
@@ -161,36 +144,47 @@ class YamlFileLoader extends FileLoader
|
||||
{
|
||||
$type = isset($config['type']) ? $config['type'] : null;
|
||||
$prefix = isset($config['prefix']) ? $config['prefix'] : '';
|
||||
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
|
||||
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
|
||||
$options = isset($config['options']) ? $config['options'] : array();
|
||||
$defaults = isset($config['defaults']) ? $config['defaults'] : [];
|
||||
$requirements = isset($config['requirements']) ? $config['requirements'] : [];
|
||||
$options = isset($config['options']) ? $config['options'] : [];
|
||||
$host = isset($config['host']) ? $config['host'] : null;
|
||||
$condition = isset($config['condition']) ? $config['condition'] : null;
|
||||
$schemes = isset($config['schemes']) ? $config['schemes'] : null;
|
||||
$methods = isset($config['methods']) ? $config['methods'] : null;
|
||||
|
||||
if (isset($config['controller'])) {
|
||||
$defaults['_controller'] = $config['controller'];
|
||||
}
|
||||
|
||||
$this->setCurrentDir(\dirname($path));
|
||||
|
||||
$subCollection = $this->import($config['resource'], $type, false, $file);
|
||||
/* @var $subCollection RouteCollection */
|
||||
$subCollection->addPrefix($prefix);
|
||||
if (null !== $host) {
|
||||
$subCollection->setHost($host);
|
||||
}
|
||||
if (null !== $condition) {
|
||||
$subCollection->setCondition($condition);
|
||||
}
|
||||
if (null !== $schemes) {
|
||||
$subCollection->setSchemes($schemes);
|
||||
}
|
||||
if (null !== $methods) {
|
||||
$subCollection->setMethods($methods);
|
||||
}
|
||||
$subCollection->addDefaults($defaults);
|
||||
$subCollection->addRequirements($requirements);
|
||||
$subCollection->addOptions($options);
|
||||
$imported = $this->import($config['resource'], $type, false, $file) ?: [];
|
||||
|
||||
$collection->addCollection($subCollection);
|
||||
if (!\is_array($imported)) {
|
||||
$imported = [$imported];
|
||||
}
|
||||
|
||||
foreach ($imported as $subCollection) {
|
||||
/* @var $subCollection RouteCollection */
|
||||
$subCollection->addPrefix($prefix);
|
||||
if (null !== $host) {
|
||||
$subCollection->setHost($host);
|
||||
}
|
||||
if (null !== $condition) {
|
||||
$subCollection->setCondition($condition);
|
||||
}
|
||||
if (null !== $schemes) {
|
||||
$subCollection->setSchemes($schemes);
|
||||
}
|
||||
if (null !== $methods) {
|
||||
$subCollection->setMethods($methods);
|
||||
}
|
||||
$subCollection->addDefaults($defaults);
|
||||
$subCollection->addRequirements($requirements);
|
||||
$subCollection->addOptions($options);
|
||||
|
||||
$collection->addCollection($subCollection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,5 +214,8 @@ class YamlFileLoader extends FileLoader
|
||||
if (!isset($config['resource']) && !isset($config['path'])) {
|
||||
throw new \InvalidArgumentException(sprintf('You must define a "path" for the route "%s" in file "%s".', $name, $path));
|
||||
}
|
||||
if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
|
||||
throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<xsd:group name="configs">
|
||||
<xsd:choice>
|
||||
<xsd:element name="default" nillable="true" type="element" />
|
||||
<xsd:element name="default" nillable="true" type="default" />
|
||||
<xsd:element name="requirement" type="element" />
|
||||
<xsd:element name="option" type="element" />
|
||||
<xsd:element name="condition" type="xsd:string" />
|
||||
@@ -37,11 +37,11 @@
|
||||
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
|
||||
|
||||
<xsd:attribute name="id" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="path" type="xsd:string" />
|
||||
<xsd:attribute name="pattern" type="xsd:string" />
|
||||
<xsd:attribute name="path" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="host" type="xsd:string" />
|
||||
<xsd:attribute name="schemes" type="xsd:string" />
|
||||
<xsd:attribute name="methods" type="xsd:string" />
|
||||
<xsd:attribute name="controller" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="import">
|
||||
@@ -53,6 +53,19 @@
|
||||
<xsd:attribute name="host" type="xsd:string" />
|
||||
<xsd:attribute name="schemes" type="xsd:string" />
|
||||
<xsd:attribute name="methods" type="xsd:string" />
|
||||
<xsd:attribute name="controller" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="default" mixed="true">
|
||||
<xsd:choice minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="bool" type="xsd:boolean" />
|
||||
<xsd:element name="int" type="xsd:integer" />
|
||||
<xsd:element name="float" type="xsd:float" />
|
||||
<xsd:element name="string" type="xsd:string" />
|
||||
<xsd:element name="list" type="list" />
|
||||
<xsd:element name="map" type="map" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="element">
|
||||
@@ -62,4 +75,74 @@
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="list">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="bool" nillable="true" type="xsd:boolean" />
|
||||
<xsd:element name="int" nillable="true" type="xsd:integer" />
|
||||
<xsd:element name="float" nillable="true" type="xsd:float" />
|
||||
<xsd:element name="string" nillable="true" type="xsd:string" />
|
||||
<xsd:element name="list" nillable="true" type="list" />
|
||||
<xsd:element name="map" nillable="true" type="map" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="bool" nillable="true" type="map-bool-entry" />
|
||||
<xsd:element name="int" nillable="true" type="map-int-entry" />
|
||||
<xsd:element name="float" nillable="true" type="map-float-entry" />
|
||||
<xsd:element name="string" nillable="true" type="map-string-entry" />
|
||||
<xsd:element name="list" nillable="true" type="map-list-entry" />
|
||||
<xsd:element name="map" nillable="true" type="map-map-entry" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map-bool-entry">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:boolean">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map-int-entry">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:integer">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map-float-entry">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:float">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map-string-entry">
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map-list-entry">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="list">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="map-map-entry">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="map">
|
||||
<xsd:attribute name="key" type="xsd:string" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
|
||||
@@ -28,12 +28,12 @@ class DumperCollection implements \IteratorAggregate
|
||||
/**
|
||||
* @var DumperCollection[]|DumperRoute[]
|
||||
*/
|
||||
private $children = array();
|
||||
private $children = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $attributes = array();
|
||||
private $attributes = [];
|
||||
|
||||
/**
|
||||
* Returns the children routes and collections.
|
||||
@@ -106,7 +106,7 @@ class DumperCollection implements \IteratorAggregate
|
||||
/**
|
||||
* Sets the parent collection.
|
||||
*/
|
||||
protected function setParent(DumperCollection $parent)
|
||||
protected function setParent(self $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ class DumperCollection implements \IteratorAggregate
|
||||
*/
|
||||
public function hasAttribute($name)
|
||||
{
|
||||
return array_key_exists($name, $this->attributes);
|
||||
return \array_key_exists($name, $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ interface MatcherDumperInterface
|
||||
*
|
||||
* @return string Executable code
|
||||
*/
|
||||
public function dump(array $options = array());
|
||||
public function dump(array $options = []);
|
||||
|
||||
/**
|
||||
* Gets the routes to dump.
|
||||
|
||||
@@ -30,7 +30,7 @@ class PhpMatcherDumper extends MatcherDumper
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
*/
|
||||
private $expressionLanguageProviders = array();
|
||||
private $expressionLanguageProviders = [];
|
||||
|
||||
/**
|
||||
* Dumps a set of routes to a PHP class.
|
||||
@@ -44,12 +44,12 @@ class PhpMatcherDumper extends MatcherDumper
|
||||
*
|
||||
* @return string A PHP class representing the matcher class
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
public function dump(array $options = [])
|
||||
{
|
||||
$options = array_replace(array(
|
||||
$options = array_replace([
|
||||
'class' => 'ProjectUrlMatcher',
|
||||
'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
||||
), $options);
|
||||
], $options);
|
||||
|
||||
// trailing slash support is only enabled if we know how to redirect the user
|
||||
$interfaces = class_implements($options['base_class']);
|
||||
@@ -98,10 +98,16 @@ EOF;
|
||||
return <<<EOF
|
||||
public function match(\$rawPathinfo)
|
||||
{
|
||||
\$allow = array();
|
||||
\$allow = [];
|
||||
\$pathinfo = rawurldecode(\$rawPathinfo);
|
||||
\$trimmedPathinfo = rtrim(\$pathinfo, '/');
|
||||
\$context = \$this->context;
|
||||
\$request = \$this->request ?: \$this->createRequest(\$pathinfo);
|
||||
\$requestMethod = \$canonicalMethod = \$context->getMethod();
|
||||
|
||||
if ('HEAD' === \$requestMethod) {
|
||||
\$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
$code
|
||||
|
||||
@@ -121,22 +127,21 @@ EOF;
|
||||
private function compileRoutes(RouteCollection $routes, $supportsRedirections)
|
||||
{
|
||||
$fetchedHost = false;
|
||||
|
||||
$groups = $this->groupRoutesByHostRegex($routes);
|
||||
$code = '';
|
||||
|
||||
foreach ($groups as $collection) {
|
||||
if (null !== $regex = $collection->getAttribute('host_regex')) {
|
||||
if (!$fetchedHost) {
|
||||
$code .= " \$host = \$this->context->getHost();\n\n";
|
||||
$code .= " \$host = \$context->getHost();\n\n";
|
||||
$fetchedHost = true;
|
||||
}
|
||||
|
||||
$code .= sprintf(" if (preg_match(%s, \$host, \$hostMatches)) {\n", var_export($regex, true));
|
||||
}
|
||||
|
||||
$tree = $this->buildPrefixTree($collection);
|
||||
$groupCode = $this->compilePrefixRoutes($tree, $supportsRedirections);
|
||||
$tree = $this->buildStaticPrefixCollection($collection);
|
||||
$groupCode = $this->compileStaticPrefixRoutes($tree, $supportsRedirections);
|
||||
|
||||
if (null !== $regex) {
|
||||
// apply extra indention at each line (except empty ones)
|
||||
@@ -148,40 +153,59 @@ EOF;
|
||||
}
|
||||
}
|
||||
|
||||
// used to display the Welcome Page in apps that don't define a homepage
|
||||
$code .= " if ('/' === \$pathinfo && !\$allow) {\n";
|
||||
$code .= " throw new Symfony\Component\Routing\Exception\NoConfigurationException();\n";
|
||||
$code .= " }\n";
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function buildStaticPrefixCollection(DumperCollection $collection)
|
||||
{
|
||||
$prefixCollection = new StaticPrefixCollection();
|
||||
|
||||
foreach ($collection as $dumperRoute) {
|
||||
$prefix = $dumperRoute->getRoute()->compile()->getStaticPrefix();
|
||||
$prefixCollection->addRoute($prefix, $dumperRoute);
|
||||
}
|
||||
|
||||
$prefixCollection->optimizeGroups();
|
||||
|
||||
return $prefixCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates PHP code recursively to match a tree of routes.
|
||||
* Generates PHP code to match a tree of routes.
|
||||
*
|
||||
* @param DumperPrefixCollection $collection A DumperPrefixCollection instance
|
||||
* @param StaticPrefixCollection $collection A StaticPrefixCollection instance
|
||||
* @param bool $supportsRedirections Whether redirections are supported by the base class
|
||||
* @param string $parentPrefix Prefix of the parent collection
|
||||
* @param string $ifOrElseIf either "if" or "elseif" to influence chaining
|
||||
*
|
||||
* @return string PHP code
|
||||
*/
|
||||
private function compilePrefixRoutes(DumperPrefixCollection $collection, $supportsRedirections, $parentPrefix = '')
|
||||
private function compileStaticPrefixRoutes(StaticPrefixCollection $collection, $supportsRedirections, $ifOrElseIf = 'if')
|
||||
{
|
||||
$code = '';
|
||||
$prefix = $collection->getPrefix();
|
||||
$optimizable = 1 < \strlen($prefix) && 1 < \count($collection->all());
|
||||
$optimizedPrefix = $parentPrefix;
|
||||
|
||||
if ($optimizable) {
|
||||
$optimizedPrefix = $prefix;
|
||||
|
||||
$code .= sprintf(" if (0 === strpos(\$pathinfo, %s)) {\n", var_export($prefix, true));
|
||||
if (!empty($prefix) && '/' !== $prefix) {
|
||||
$code .= sprintf(" %s (0 === strpos(\$pathinfo, %s)) {\n", $ifOrElseIf, var_export($prefix, true));
|
||||
}
|
||||
|
||||
foreach ($collection as $route) {
|
||||
if ($route instanceof DumperCollection) {
|
||||
$code .= $this->compilePrefixRoutes($route, $supportsRedirections, $optimizedPrefix);
|
||||
$ifOrElseIf = 'if';
|
||||
|
||||
foreach ($collection->getItems() as $route) {
|
||||
if ($route instanceof StaticPrefixCollection) {
|
||||
$code .= $this->compileStaticPrefixRoutes($route, $supportsRedirections, $ifOrElseIf);
|
||||
$ifOrElseIf = 'elseif';
|
||||
} else {
|
||||
$code .= $this->compileRoute($route->getRoute(), $route->getName(), $supportsRedirections, $optimizedPrefix)."\n";
|
||||
$code .= $this->compileRoute($route[1]->getRoute(), $route[1]->getName(), $supportsRedirections, $prefix)."\n";
|
||||
$ifOrElseIf = 'if';
|
||||
}
|
||||
}
|
||||
|
||||
if ($optimizable) {
|
||||
if (!empty($prefix) && '/' !== $prefix) {
|
||||
$code .= " }\n\n";
|
||||
// apply extra indention at each line (except empty ones)
|
||||
$code = preg_replace('/^.{2,}$/m', ' $0', $code);
|
||||
@@ -206,22 +230,18 @@ EOF;
|
||||
{
|
||||
$code = '';
|
||||
$compiledRoute = $route->compile();
|
||||
$conditions = array();
|
||||
$conditions = [];
|
||||
$hasTrailingSlash = false;
|
||||
$matches = false;
|
||||
$hostMatches = false;
|
||||
$methods = $route->getMethods();
|
||||
|
||||
// GET and HEAD are equivalent
|
||||
if (\in_array('GET', $methods) && !\in_array('HEAD', $methods)) {
|
||||
$methods[] = 'HEAD';
|
||||
}
|
||||
|
||||
$supportsTrailingSlash = $supportsRedirections && (!$methods || \in_array('GET', $methods));
|
||||
$regex = $compiledRoute->getRegex();
|
||||
|
||||
if (!\count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) {
|
||||
if (!\count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#'.('u' === substr($regex, -1) ? 'u' : ''), $regex, $m)) {
|
||||
if ($supportsTrailingSlash && '/' === substr($m['url'], -1)) {
|
||||
$conditions[] = sprintf("%s === rtrim(\$pathinfo, '/')", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
|
||||
$conditions[] = sprintf('%s === $trimmedPathinfo', var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
|
||||
$hasTrailingSlash = true;
|
||||
} else {
|
||||
$conditions[] = sprintf('%s === $pathinfo', var_export(str_replace('\\', '', $m['url']), true));
|
||||
@@ -231,7 +251,6 @@ EOF;
|
||||
$conditions[] = sprintf('0 === strpos($pathinfo, %s)', var_export($compiledRoute->getStaticPrefix(), true));
|
||||
}
|
||||
|
||||
$regex = $compiledRoute->getRegex();
|
||||
if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) {
|
||||
$regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2);
|
||||
$hasTrailingSlash = true;
|
||||
@@ -246,7 +265,7 @@ EOF;
|
||||
}
|
||||
|
||||
if ($route->getCondition()) {
|
||||
$conditions[] = $this->getExpressionLanguage()->compile($route->getCondition(), array('context', 'request'));
|
||||
$conditions[] = $this->getExpressionLanguage()->compile($route->getCondition(), ['context', 'request']);
|
||||
}
|
||||
|
||||
$conditions = implode(' && ', $conditions);
|
||||
@@ -259,42 +278,71 @@ EOF;
|
||||
|
||||
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
|
||||
|
||||
// the offset where the return value is appended below, with indendation
|
||||
$retOffset = 12 + \strlen($code);
|
||||
|
||||
// optimize parameters array
|
||||
if ($matches || $hostMatches) {
|
||||
$vars = [];
|
||||
if ($hostMatches) {
|
||||
$vars[] = '$hostMatches';
|
||||
}
|
||||
if ($matches) {
|
||||
$vars[] = '$matches';
|
||||
}
|
||||
$vars[] = "['_route' => '$name']";
|
||||
|
||||
$code .= sprintf(
|
||||
" \$ret = \$this->mergeDefaults(array_replace(%s), %s);\n",
|
||||
implode(', ', $vars),
|
||||
str_replace("\n", '', var_export($route->getDefaults(), true))
|
||||
);
|
||||
} elseif ($route->getDefaults()) {
|
||||
$code .= sprintf(" \$ret = %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), ['_route' => $name]), true)));
|
||||
} else {
|
||||
$code .= sprintf(" \$ret = ['_route' => '%s'];\n", $name);
|
||||
}
|
||||
|
||||
if ($hasTrailingSlash) {
|
||||
$code .= <<<EOF
|
||||
if ('/' === substr(\$pathinfo, -1)) {
|
||||
// no-op
|
||||
} elseif (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) {
|
||||
} elseif ('GET' !== \$canonicalMethod) {
|
||||
goto $gotoname;
|
||||
} else {
|
||||
return \$this->redirect(\$rawPathinfo.'/', '$name');
|
||||
return array_replace(\$ret, \$this->redirect(\$rawPathinfo.'/', '$name'));
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
if ($methods) {
|
||||
$methodVariable = \in_array('GET', $methods) ? '$canonicalMethod' : '$requestMethod';
|
||||
$methods = implode("', '", $methods);
|
||||
}
|
||||
|
||||
if ($schemes = $route->getSchemes()) {
|
||||
if (!$supportsRedirections) {
|
||||
throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
|
||||
}
|
||||
$schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
|
||||
if ($methods) {
|
||||
$methods = implode("', '", $methods);
|
||||
$code .= <<<EOF
|
||||
\$requiredSchemes = $schemes;
|
||||
\$hasRequiredScheme = isset(\$requiredSchemes[\$this->context->getScheme()]);
|
||||
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
|
||||
\$hasRequiredScheme = isset(\$requiredSchemes[\$context->getScheme()]);
|
||||
if (!in_array($methodVariable, ['$methods'])) {
|
||||
if (\$hasRequiredScheme) {
|
||||
\$allow = array_merge(\$allow, array('$methods'));
|
||||
\$allow = array_merge(\$allow, ['$methods']);
|
||||
}
|
||||
goto $gotoname;
|
||||
}
|
||||
if (!\$hasRequiredScheme) {
|
||||
if (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) {
|
||||
if ('GET' !== \$canonicalMethod) {
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes));
|
||||
return array_replace(\$ret, \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)));
|
||||
}
|
||||
|
||||
|
||||
@@ -302,60 +350,32 @@ EOF;
|
||||
} else {
|
||||
$code .= <<<EOF
|
||||
\$requiredSchemes = $schemes;
|
||||
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
|
||||
if (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) {
|
||||
if (!isset(\$requiredSchemes[\$context->getScheme()])) {
|
||||
if ('GET' !== \$canonicalMethod) {
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes));
|
||||
return array_replace(\$ret, \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)));
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
} elseif ($methods) {
|
||||
if (1 === \count($methods)) {
|
||||
$code .= <<<EOF
|
||||
if (\$this->context->getMethod() != '$methods[0]') {
|
||||
\$allow[] = '$methods[0]';
|
||||
$code .= <<<EOF
|
||||
if (!in_array($methodVariable, ['$methods'])) {
|
||||
\$allow = array_merge(\$allow, ['$methods']);
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
} else {
|
||||
$methods = implode("', '", $methods);
|
||||
$code .= <<<EOF
|
||||
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
|
||||
\$allow = array_merge(\$allow, array('$methods'));
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
|
||||
// optimize parameters array
|
||||
if ($matches || $hostMatches) {
|
||||
$vars = array();
|
||||
if ($hostMatches) {
|
||||
$vars[] = '$hostMatches';
|
||||
}
|
||||
if ($matches) {
|
||||
$vars[] = '$matches';
|
||||
}
|
||||
$vars[] = "array('_route' => '$name')";
|
||||
|
||||
$code .= sprintf(
|
||||
" return \$this->mergeDefaults(array_replace(%s), %s);\n",
|
||||
implode(', ', $vars),
|
||||
str_replace("\n", '', var_export($route->getDefaults(), true))
|
||||
);
|
||||
} elseif ($route->getDefaults()) {
|
||||
$code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
|
||||
if ($hasTrailingSlash || $schemes || $methods) {
|
||||
$code .= " return \$ret;\n";
|
||||
} else {
|
||||
$code .= sprintf(" return array('_route' => '%s');\n", $name);
|
||||
$code = substr_replace($code, 'return', $retOffset, 6);
|
||||
}
|
||||
$code .= " }\n";
|
||||
|
||||
@@ -378,7 +398,6 @@ EOF;
|
||||
private function groupRoutesByHostRegex(RouteCollection $routes)
|
||||
{
|
||||
$groups = new DumperCollection();
|
||||
|
||||
$currentGroup = new DumperCollection();
|
||||
$currentGroup->setAttribute('host_regex', null);
|
||||
$groups->add($currentGroup);
|
||||
@@ -396,28 +415,6 @@ EOF;
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes the routes into a prefix tree.
|
||||
*
|
||||
* Routes order is preserved such that traversing the tree will traverse the
|
||||
* routes in the origin order.
|
||||
*
|
||||
* @return DumperPrefixCollection
|
||||
*/
|
||||
private function buildPrefixTree(DumperCollection $collection)
|
||||
{
|
||||
$tree = new DumperPrefixCollection();
|
||||
$current = $tree;
|
||||
|
||||
foreach ($collection as $route) {
|
||||
$current = $current->addPrefixRoute($route);
|
||||
}
|
||||
|
||||
$tree->mergeSlashNodes();
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
private function getExpressionLanguage()
|
||||
{
|
||||
if (null === $this->expressionLanguage) {
|
||||
|
||||
238
vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
vendored
Normal file
238
vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Routing\Matcher\Dumper;
|
||||
|
||||
/**
|
||||
* Prefix tree of routes preserving routes order.
|
||||
*
|
||||
* @author Frank de Jonge <info@frankdejonge.nl>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class StaticPrefixCollection
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* @var array[]|StaticPrefixCollection[]
|
||||
*/
|
||||
private $items = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $matchStart = 0;
|
||||
|
||||
public function __construct($prefix = '')
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
public function getPrefix()
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|StaticPrefixCollection[]
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a route to a group.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param mixed $route
|
||||
*/
|
||||
public function addRoute($prefix, $route)
|
||||
{
|
||||
$prefix = '/' === $prefix ? $prefix : rtrim($prefix, '/');
|
||||
$this->guardAgainstAddingNotAcceptedRoutes($prefix);
|
||||
|
||||
if ($this->prefix === $prefix) {
|
||||
// When a prefix is exactly the same as the base we move up the match start position.
|
||||
// This is needed because otherwise routes that come afterwards have higher precedence
|
||||
// than a possible regular expression, which goes against the input order sorting.
|
||||
$this->items[] = [$prefix, $route];
|
||||
$this->matchStart = \count($this->items);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->items as $i => $item) {
|
||||
if ($i < $this->matchStart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item instanceof self && $item->accepts($prefix)) {
|
||||
$item->addRoute($prefix, $route);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$group = $this->groupWithItem($item, $prefix, $route);
|
||||
|
||||
if ($group instanceof self) {
|
||||
$this->items[$i] = $group;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No optimised case was found, in this case we simple add the route for possible
|
||||
// grouping when new routes are added.
|
||||
$this->items[] = [$prefix, $route];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to combine a route with another route or group.
|
||||
*
|
||||
* @param StaticPrefixCollection|array $item
|
||||
* @param string $prefix
|
||||
* @param mixed $route
|
||||
*
|
||||
* @return StaticPrefixCollection|null
|
||||
*/
|
||||
private function groupWithItem($item, $prefix, $route)
|
||||
{
|
||||
$itemPrefix = $item instanceof self ? $item->prefix : $item[0];
|
||||
$commonPrefix = $this->detectCommonPrefix($prefix, $itemPrefix);
|
||||
|
||||
if (!$commonPrefix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$child = new self($commonPrefix);
|
||||
|
||||
if ($item instanceof self) {
|
||||
$child->items = [$item];
|
||||
} else {
|
||||
$child->addRoute($item[0], $item[1]);
|
||||
}
|
||||
|
||||
$child->addRoute($prefix, $route);
|
||||
|
||||
return $child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a prefix can be contained within the group.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool Whether a prefix could belong in a given group
|
||||
*/
|
||||
private function accepts($prefix)
|
||||
{
|
||||
return '' === $this->prefix || 0 === strpos($prefix, $this->prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects whether there's a common prefix relative to the group prefix and returns it.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param string $anotherPrefix
|
||||
*
|
||||
* @return false|string A common prefix, longer than the base/group prefix, or false when none available
|
||||
*/
|
||||
private function detectCommonPrefix($prefix, $anotherPrefix)
|
||||
{
|
||||
$baseLength = \strlen($this->prefix);
|
||||
$commonLength = $baseLength;
|
||||
$end = min(\strlen($prefix), \strlen($anotherPrefix));
|
||||
|
||||
for ($i = $baseLength; $i <= $end; ++$i) {
|
||||
if (substr($prefix, 0, $i) !== substr($anotherPrefix, 0, $i)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$commonLength = $i;
|
||||
}
|
||||
|
||||
$commonPrefix = rtrim(substr($prefix, 0, $commonLength), '/');
|
||||
|
||||
if (\strlen($commonPrefix) > $baseLength) {
|
||||
return $commonPrefix;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimizes the tree by inlining items from groups with less than 3 items.
|
||||
*/
|
||||
public function optimizeGroups()
|
||||
{
|
||||
$index = -1;
|
||||
|
||||
while (isset($this->items[++$index])) {
|
||||
$item = $this->items[$index];
|
||||
|
||||
if ($item instanceof self) {
|
||||
$item->optimizeGroups();
|
||||
|
||||
// When a group contains only two items there's no reason to optimize because at minimum
|
||||
// the amount of prefix check is 2. In this case inline the group.
|
||||
if ($item->shouldBeInlined()) {
|
||||
array_splice($this->items, $index, 1, $item->items);
|
||||
|
||||
// Lower index to pass through the same index again after optimizing.
|
||||
// The first item of the replacements might be a group needing optimization.
|
||||
--$index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function shouldBeInlined()
|
||||
{
|
||||
if (\count($this->items) >= 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if ($item instanceof self) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if (\is_array($item) && $item[0] === $this->prefix) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guards against adding incompatible prefixes in a group.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @throws \LogicException when a prefix does not belong in a group
|
||||
*/
|
||||
private function guardAgainstAddingNotAcceptedRoutes($prefix)
|
||||
{
|
||||
if (!$this->accepts($prefix)) {
|
||||
$message = sprintf('Could not add route with prefix %s to collection with prefix %s', $prefix, $this->prefix);
|
||||
|
||||
throw new \LogicException($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,14 +27,14 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
|
||||
try {
|
||||
$parameters = parent::match($pathinfo);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
if ('/' === substr($pathinfo, -1) || !\in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
|
||||
if ('/' === substr($pathinfo, -1) || !\in_array($this->context->getMethod(), ['HEAD', 'GET'])) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
try {
|
||||
parent::match($pathinfo.'/');
|
||||
$parameters = parent::match($pathinfo.'/');
|
||||
|
||||
return $this->redirect($pathinfo.'/', null);
|
||||
return array_replace($parameters, $this->redirect($pathinfo.'/', isset($parameters['_route']) ? $parameters['_route'] : null));
|
||||
} catch (ResourceNotFoundException $e2) {
|
||||
throw $e;
|
||||
}
|
||||
@@ -49,17 +49,17 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
|
||||
protected function handleRouteRequirements($pathinfo, $name, Route $route)
|
||||
{
|
||||
// expression condition
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
|
||||
return array(self::REQUIREMENT_MISMATCH, null);
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), ['context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)])) {
|
||||
return [self::REQUIREMENT_MISMATCH, null];
|
||||
}
|
||||
|
||||
// check HTTP scheme requirement
|
||||
$scheme = $this->context->getScheme();
|
||||
$schemes = $route->getSchemes();
|
||||
if ($schemes && !$route->hasScheme($scheme)) {
|
||||
return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes)));
|
||||
return [self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes))];
|
||||
}
|
||||
|
||||
return array(self::REQUIREMENT_MATCH, null);
|
||||
return [self::REQUIREMENT_MATCH, null];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Symfony\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\NoConfigurationException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -30,6 +31,7 @@ interface RequestMatcherInterface
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
|
||||
public function getTraces($pathinfo)
|
||||
{
|
||||
$this->traces = array();
|
||||
$this->traces = [];
|
||||
|
||||
try {
|
||||
$this->match($pathinfo);
|
||||
@@ -52,12 +52,43 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
|
||||
protected function matchCollection($pathinfo, RouteCollection $routes)
|
||||
{
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
$method = 'GET';
|
||||
}
|
||||
$supportsTrailingSlash = '/' !== $pathinfo && '' !== $pathinfo && $this instanceof RedirectableUrlMatcherInterface;
|
||||
|
||||
foreach ($routes as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
$staticPrefix = $compiledRoute->getStaticPrefix();
|
||||
$requiredMethods = $route->getMethods();
|
||||
|
||||
if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
|
||||
// check the static prefix of the URL first. Only use the more expensive preg_match when it matches
|
||||
if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) {
|
||||
// no-op
|
||||
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods)) || 'GET' !== $method) {
|
||||
$this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);
|
||||
continue;
|
||||
} elseif ('/' === substr($staticPrefix, -1) && substr($staticPrefix, 0, -1) === $pathinfo) {
|
||||
$this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);
|
||||
|
||||
return $this->allow = [];
|
||||
} else {
|
||||
$this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);
|
||||
continue;
|
||||
}
|
||||
$regex = $compiledRoute->getRegex();
|
||||
|
||||
if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) {
|
||||
$regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2);
|
||||
$hasTrailingSlash = true;
|
||||
} else {
|
||||
$hasTrailingSlash = false;
|
||||
}
|
||||
|
||||
if (!preg_match($regex, $pathinfo, $matches)) {
|
||||
// does it match without any requirements?
|
||||
$r = new Route($route->getPath(), $route->getDefaults(), array(), $route->getOptions());
|
||||
$r = new Route($route->getPath(), $route->getDefaults(), [], $route->getOptions());
|
||||
$cr = $r->compile();
|
||||
if (!preg_match($cr->getRegex(), $pathinfo)) {
|
||||
$this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);
|
||||
@@ -66,7 +97,7 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
}
|
||||
|
||||
foreach ($route->getRequirements() as $n => $regex) {
|
||||
$r = new Route($route->getPath(), $route->getDefaults(), array($n => $regex), $route->getOptions());
|
||||
$r = new Route($route->getPath(), $route->getDefaults(), [$n => $regex], $route->getOptions());
|
||||
$cr = $r->compile();
|
||||
|
||||
if (\in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) {
|
||||
@@ -79,63 +110,61 @@ class TraceableUrlMatcher extends UrlMatcher
|
||||
continue;
|
||||
}
|
||||
|
||||
// check host requirement
|
||||
$hostMatches = array();
|
||||
if ($hasTrailingSlash && '/' !== substr($pathinfo, -1)) {
|
||||
if ((!$requiredMethods || \in_array('GET', $requiredMethods)) && 'GET' === $method) {
|
||||
$this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);
|
||||
|
||||
return $this->allow = [];
|
||||
}
|
||||
$this->addTrace(sprintf('Method "%s" does not match any of the required methods (%s)', $this->context->getMethod(), implode(', ', $requiredMethods)), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
continue;
|
||||
}
|
||||
|
||||
$hostMatches = [];
|
||||
if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
|
||||
$this->addTrace(sprintf('Host "%s" does not match the requirement ("%s")', $this->context->getHost(), $route->getHost()), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
|
||||
|
||||
if (self::REQUIREMENT_MISMATCH === $status[0]) {
|
||||
if ($route->getCondition()) {
|
||||
$this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $route->getCondition()), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
} else {
|
||||
$this->addTrace(sprintf('Scheme "%s" does not match any of the required schemes (%s); the user will be redirected to first required scheme', $this->getContext()->getScheme(), implode(', ', $route->getSchemes())), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// check HTTP method requirement
|
||||
if ($requiredMethods = $route->getMethods()) {
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
$method = 'GET';
|
||||
}
|
||||
|
||||
if ($requiredMethods) {
|
||||
if (!\in_array($method, $requiredMethods)) {
|
||||
$this->allow = array_merge($this->allow, $requiredMethods);
|
||||
|
||||
if (self::REQUIREMENT_MATCH === $status[0]) {
|
||||
$this->allow = array_merge($this->allow, $requiredMethods);
|
||||
}
|
||||
$this->addTrace(sprintf('Method "%s" does not match any of the required methods (%s)', $this->context->getMethod(), implode(', ', $requiredMethods)), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check condition
|
||||
if ($condition = $route->getCondition()) {
|
||||
if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
|
||||
$this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $condition), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check HTTP scheme requirement
|
||||
if ($requiredSchemes = $route->getSchemes()) {
|
||||
$scheme = $this->context->getScheme();
|
||||
|
||||
if (!$route->hasScheme($scheme)) {
|
||||
$this->addTrace(sprintf('Scheme "%s" does not match any of the required schemes (%s); the user will be redirected to first required scheme', $scheme, implode(', ', $requiredSchemes)), self::ROUTE_ALMOST_MATCHES, $name, $route);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);
|
||||
|
||||
return true;
|
||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : []));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private function addTrace($log, $level = self::ROUTE_DOES_NOT_MATCH, $name = null, $route = null)
|
||||
{
|
||||
$this->traces[] = array(
|
||||
$this->traces[] = [
|
||||
'log' => $log,
|
||||
'name' => $name,
|
||||
'level' => $level,
|
||||
'path' => null !== $route ? $route->getPath() : null,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
76
vendor/symfony/routing/Matcher/UrlMatcher.php
vendored
76
vendor/symfony/routing/Matcher/UrlMatcher.php
vendored
@@ -15,6 +15,7 @@ use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\NoConfigurationException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\Route;
|
||||
@@ -32,7 +33,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
const ROUTE_MATCH = 2;
|
||||
|
||||
protected $context;
|
||||
protected $allow = array();
|
||||
protected $allow = [];
|
||||
protected $routes;
|
||||
protected $request;
|
||||
protected $expressionLanguage;
|
||||
@@ -40,7 +41,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
*/
|
||||
protected $expressionLanguageProviders = array();
|
||||
protected $expressionLanguageProviders = [];
|
||||
|
||||
public function __construct(RouteCollection $routes, RequestContext $context)
|
||||
{
|
||||
@@ -69,15 +70,17 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
*/
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$this->allow = array();
|
||||
$this->allow = [];
|
||||
|
||||
if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
throw 0 < \count($this->allow)
|
||||
? new MethodNotAllowedException(array_unique($this->allow))
|
||||
: new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
|
||||
if ('/' === $pathinfo && !$this->allow) {
|
||||
throw new NoConfigurationException();
|
||||
}
|
||||
|
||||
throw 0 < \count($this->allow) ? new MethodNotAllowedException(array_unique($this->allow)) : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,24 +110,54 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @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($pathinfo, RouteCollection $routes)
|
||||
{
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
$method = 'GET';
|
||||
}
|
||||
$supportsTrailingSlash = '/' !== $pathinfo && '' !== $pathinfo && $this instanceof RedirectableUrlMatcherInterface;
|
||||
|
||||
foreach ($routes as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
$staticPrefix = $compiledRoute->getStaticPrefix();
|
||||
$requiredMethods = $route->getMethods();
|
||||
|
||||
// check the static prefix of the URL first. Only use the more expensive preg_match when it matches
|
||||
if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
|
||||
if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) {
|
||||
// no-op
|
||||
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods)) || 'GET' !== $method) {
|
||||
continue;
|
||||
} elseif ('/' === substr($staticPrefix, -1) && substr($staticPrefix, 0, -1) === $pathinfo) {
|
||||
return $this->allow = [];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$regex = $compiledRoute->getRegex();
|
||||
|
||||
if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) {
|
||||
$regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2);
|
||||
$hasTrailingSlash = true;
|
||||
} else {
|
||||
$hasTrailingSlash = false;
|
||||
}
|
||||
|
||||
if (!preg_match($regex, $pathinfo, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
|
||||
if ($hasTrailingSlash && '/' !== substr($pathinfo, -1)) {
|
||||
if ((!$requiredMethods || \in_array('GET', $requiredMethods)) && 'GET' === $method) {
|
||||
return $this->allow = [];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$hostMatches = array();
|
||||
$hostMatches = [];
|
||||
if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
|
||||
continue;
|
||||
}
|
||||
@@ -136,12 +169,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
// check HTTP method requirement
|
||||
if ($requiredMethods = $route->getMethods()) {
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
$method = 'GET';
|
||||
}
|
||||
|
||||
if ($requiredMethods) {
|
||||
if (!\in_array($method, $requiredMethods)) {
|
||||
if (self::REQUIREMENT_MATCH === $status[0]) {
|
||||
$this->allow = array_merge($this->allow, $requiredMethods);
|
||||
@@ -151,12 +179,10 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
}
|
||||
|
||||
if (self::ROUTE_MATCH === $status[0]) {
|
||||
return $status[1];
|
||||
}
|
||||
|
||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
|
||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : []));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,15 +217,15 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
protected function handleRouteRequirements($pathinfo, $name, Route $route)
|
||||
{
|
||||
// expression condition
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
|
||||
return array(self::REQUIREMENT_MISMATCH, null);
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), ['context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)])) {
|
||||
return [self::REQUIREMENT_MISMATCH, null];
|
||||
}
|
||||
|
||||
// check HTTP scheme requirement
|
||||
$scheme = $this->context->getScheme();
|
||||
$status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
|
||||
|
||||
return array($status, null);
|
||||
return [$status, null];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,9 +268,9 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array(
|
||||
return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), [], [], [
|
||||
'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
|
||||
'SCRIPT_NAME' => $this->context->getBaseUrl(),
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\NoConfigurationException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
|
||||
@@ -32,6 +33,7 @@ interface UrlMatcherInterface extends RequestContextAwareInterface
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
8
vendor/symfony/routing/RequestContext.php
vendored
8
vendor/symfony/routing/RequestContext.php
vendored
@@ -31,7 +31,7 @@ class RequestContext
|
||||
private $httpPort;
|
||||
private $httpsPort;
|
||||
private $queryString;
|
||||
private $parameters = array();
|
||||
private $parameters = [];
|
||||
|
||||
/**
|
||||
* @param string $baseUrl The base URL
|
||||
@@ -67,8 +67,8 @@ class RequestContext
|
||||
$this->setMethod($request->getMethod());
|
||||
$this->setHost($request->getHost());
|
||||
$this->setScheme($request->getScheme());
|
||||
$this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
|
||||
$this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
|
||||
$this->setHttpPort($request->isSecure() || null === $request->getPort() ? $this->httpPort : $request->getPort());
|
||||
$this->setHttpsPort($request->isSecure() && null !== $request->getPort() ? $request->getPort() : $this->httpsPort);
|
||||
$this->setQueryString($request->server->get('QUERY_STRING', ''));
|
||||
|
||||
return $this;
|
||||
@@ -316,7 +316,7 @@ class RequestContext
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
return array_key_exists($name, $this->parameters);
|
||||
return \array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
106
vendor/symfony/routing/Route.php
vendored
106
vendor/symfony/routing/Route.php
vendored
@@ -21,11 +21,11 @@ class Route implements \Serializable
|
||||
{
|
||||
private $path = '/';
|
||||
private $host = '';
|
||||
private $schemes = array();
|
||||
private $methods = array();
|
||||
private $defaults = array();
|
||||
private $requirements = array();
|
||||
private $options = array();
|
||||
private $schemes = [];
|
||||
private $methods = [];
|
||||
private $defaults = [];
|
||||
private $requirements = [];
|
||||
private $options = [];
|
||||
private $condition = '';
|
||||
|
||||
/**
|
||||
@@ -39,6 +39,7 @@ class Route implements \Serializable
|
||||
* Available options:
|
||||
*
|
||||
* * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
|
||||
* * utf8: Whether UTF-8 matching is enforced ot not
|
||||
*
|
||||
* @param string $path The path pattern to match
|
||||
* @param array $defaults An array of default parameter values
|
||||
@@ -49,21 +50,15 @@ class Route implements \Serializable
|
||||
* @param string|string[] $methods A required HTTP method or an array of restricted methods
|
||||
* @param string $condition A condition that should evaluate to true for the route to match
|
||||
*/
|
||||
public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array(), $condition = '')
|
||||
public function __construct($path, array $defaults = [], array $requirements = [], array $options = [], $host = '', $schemes = [], $methods = [], $condition = '')
|
||||
{
|
||||
$this->setPath($path);
|
||||
$this->setDefaults($defaults);
|
||||
$this->setRequirements($requirements);
|
||||
$this->setOptions($options);
|
||||
$this->setHost($host);
|
||||
// The conditions make sure that an initial empty $schemes/$methods does not override the corresponding requirement.
|
||||
// They can be removed when the BC layer is removed.
|
||||
if ($schemes) {
|
||||
$this->setSchemes($schemes);
|
||||
}
|
||||
if ($methods) {
|
||||
$this->setMethods($methods);
|
||||
}
|
||||
$this->setSchemes($schemes);
|
||||
$this->setMethods($methods);
|
||||
$this->setCondition($condition);
|
||||
}
|
||||
|
||||
@@ -72,7 +67,7 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
return serialize([
|
||||
'path' => $this->path,
|
||||
'host' => $this->host,
|
||||
'defaults' => $this->defaults,
|
||||
@@ -82,7 +77,7 @@ class Route implements \Serializable
|
||||
'methods' => $this->methods,
|
||||
'condition' => $this->condition,
|
||||
'compiled' => $this->compiled,
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,38 +102,6 @@ class Route implements \Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern for the path.
|
||||
*
|
||||
* @return string The pattern
|
||||
*
|
||||
* @deprecated since version 2.2, to be removed in 3.0. Use getPath instead.
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.2 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pattern for the path.
|
||||
*
|
||||
* This method implements a fluent interface.
|
||||
*
|
||||
* @param string $pattern The path pattern
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 2.2, to be removed in 3.0. Use setPath instead.
|
||||
*/
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.2 and will be removed in 3.0. Use the setPath() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->setPath($pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern for the path.
|
||||
*
|
||||
@@ -219,14 +182,6 @@ class Route implements \Serializable
|
||||
public function setSchemes($schemes)
|
||||
{
|
||||
$this->schemes = array_map('strtolower', (array) $schemes);
|
||||
|
||||
// this is to keep BC and will be removed in a future version
|
||||
if ($this->schemes) {
|
||||
$this->requirements['_scheme'] = implode('|', $this->schemes);
|
||||
} else {
|
||||
unset($this->requirements['_scheme']);
|
||||
}
|
||||
|
||||
$this->compiled = null;
|
||||
|
||||
return $this;
|
||||
@@ -268,14 +223,6 @@ class Route implements \Serializable
|
||||
public function setMethods($methods)
|
||||
{
|
||||
$this->methods = array_map('strtoupper', (array) $methods);
|
||||
|
||||
// this is to keep BC and will be removed in a future version
|
||||
if ($this->methods) {
|
||||
$this->requirements['_method'] = implode('|', $this->methods);
|
||||
} else {
|
||||
unset($this->requirements['_method']);
|
||||
}
|
||||
|
||||
$this->compiled = null;
|
||||
|
||||
return $this;
|
||||
@@ -302,9 +249,9 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->options = array(
|
||||
$this->options = [
|
||||
'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
|
||||
);
|
||||
];
|
||||
|
||||
return $this->addOptions($options);
|
||||
}
|
||||
@@ -367,7 +314,7 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return array_key_exists($name, $this->options);
|
||||
return \array_key_exists($name, $this->options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,7 +338,7 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function setDefaults(array $defaults)
|
||||
{
|
||||
$this->defaults = array();
|
||||
$this->defaults = [];
|
||||
|
||||
return $this->addDefaults($defaults);
|
||||
}
|
||||
@@ -436,7 +383,7 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function hasDefault($name)
|
||||
{
|
||||
return array_key_exists($name, $this->defaults);
|
||||
return \array_key_exists($name, $this->defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,7 +423,7 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function setRequirements(array $requirements)
|
||||
{
|
||||
$this->requirements = array();
|
||||
$this->requirements = [];
|
||||
|
||||
return $this->addRequirements($requirements);
|
||||
}
|
||||
@@ -509,12 +456,6 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function getRequirement($key)
|
||||
{
|
||||
if ('_scheme' === $key) {
|
||||
@trigger_error('The "_scheme" requirement is deprecated since Symfony 2.2 and will be removed in 3.0. Use getSchemes() instead.', E_USER_DEPRECATED);
|
||||
} elseif ('_method' === $key) {
|
||||
@trigger_error('The "_method" requirement is deprecated since Symfony 2.2 and will be removed in 3.0. Use getMethods() instead.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
|
||||
}
|
||||
|
||||
@@ -527,7 +468,7 @@ class Route implements \Serializable
|
||||
*/
|
||||
public function hasRequirement($key)
|
||||
{
|
||||
return array_key_exists($key, $this->requirements);
|
||||
return \array_key_exists($key, $this->requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,17 +553,6 @@ class Route implements \Serializable
|
||||
throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
|
||||
}
|
||||
|
||||
// this is to keep BC and will be removed in a future version
|
||||
if ('_scheme' === $key) {
|
||||
@trigger_error('The "_scheme" requirement is deprecated since Symfony 2.2 and will be removed in 3.0. Use the setSchemes() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
$this->setSchemes(explode('|', $regex));
|
||||
} elseif ('_method' === $key) {
|
||||
@trigger_error('The "_method" requirement is deprecated since Symfony 2.2 and will be removed in 3.0. Use the setMethods() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
$this->setMethods(explode('|', $regex));
|
||||
}
|
||||
|
||||
return $regex;
|
||||
}
|
||||
}
|
||||
|
||||
23
vendor/symfony/routing/RouteCollection.php
vendored
23
vendor/symfony/routing/RouteCollection.php
vendored
@@ -28,12 +28,12 @@ class RouteCollection implements \IteratorAggregate, \Countable
|
||||
/**
|
||||
* @var Route[]
|
||||
*/
|
||||
private $routes = array();
|
||||
private $routes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $resources = array();
|
||||
private $resources = [];
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
@@ -126,7 +126,9 @@ class RouteCollection implements \IteratorAggregate, \Countable
|
||||
$this->routes[$name] = $route;
|
||||
}
|
||||
|
||||
$this->resources = array_merge($this->resources, $collection->getResources());
|
||||
foreach ($collection->getResources() as $resource) {
|
||||
$this->addResource($resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,7 +138,7 @@ class RouteCollection implements \IteratorAggregate, \Countable
|
||||
* @param array $defaults An array of default values
|
||||
* @param array $requirements An array of requirements
|
||||
*/
|
||||
public function addPrefix($prefix, array $defaults = array(), array $requirements = array())
|
||||
public function addPrefix($prefix, array $defaults = [], array $requirements = [])
|
||||
{
|
||||
$prefix = trim(trim($prefix), '/');
|
||||
|
||||
@@ -158,7 +160,7 @@ class RouteCollection implements \IteratorAggregate, \Countable
|
||||
* @param array $defaults An array of default values
|
||||
* @param array $requirements An array of requirements
|
||||
*/
|
||||
public function setHost($pattern, array $defaults = array(), array $requirements = array())
|
||||
public function setHost($pattern, array $defaults = [], array $requirements = [])
|
||||
{
|
||||
foreach ($this->routes as $route) {
|
||||
$route->setHost($pattern);
|
||||
@@ -260,14 +262,19 @@ class RouteCollection implements \IteratorAggregate, \Countable
|
||||
*/
|
||||
public function getResources()
|
||||
{
|
||||
return array_unique($this->resources);
|
||||
return array_values($this->resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a resource for this collection.
|
||||
* Adds a resource for this collection. If the resource already exists
|
||||
* it is not added.
|
||||
*/
|
||||
public function addResource(ResourceInterface $resource)
|
||||
{
|
||||
$this->resources[] = $resource;
|
||||
$key = (string) $resource;
|
||||
|
||||
if (!isset($this->resources[$key])) {
|
||||
$this->resources[$key] = $resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,18 +25,18 @@ class RouteCollectionBuilder
|
||||
/**
|
||||
* @var Route[]|RouteCollectionBuilder[]
|
||||
*/
|
||||
private $routes = array();
|
||||
private $routes = [];
|
||||
|
||||
private $loader;
|
||||
private $defaults = array();
|
||||
private $defaults = [];
|
||||
private $prefix;
|
||||
private $host;
|
||||
private $condition;
|
||||
private $requirements = array();
|
||||
private $options = array();
|
||||
private $requirements = [];
|
||||
private $options = [];
|
||||
private $schemes;
|
||||
private $methods;
|
||||
private $resources = array();
|
||||
private $resources = [];
|
||||
|
||||
public function __construct(LoaderInterface $loader = null)
|
||||
{
|
||||
@@ -58,17 +58,24 @@ class RouteCollectionBuilder
|
||||
*/
|
||||
public function import($resource, $prefix = '/', $type = null)
|
||||
{
|
||||
/** @var RouteCollection $collection */
|
||||
$collection = $this->load($resource, $type);
|
||||
/** @var RouteCollection[] $collection */
|
||||
$collections = $this->load($resource, $type);
|
||||
|
||||
// create a builder from the RouteCollection
|
||||
$builder = $this->createBuilder();
|
||||
foreach ($collection->all() as $name => $route) {
|
||||
$builder->addRoute($route, $name);
|
||||
}
|
||||
|
||||
foreach ($collection->getResources() as $resource) {
|
||||
$builder->addResource($resource);
|
||||
foreach ($collections as $collection) {
|
||||
if (null === $collection) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($collection->all() as $name => $route) {
|
||||
$builder->addRoute($route, $name);
|
||||
}
|
||||
|
||||
foreach ($collection->getResources() as $resource) {
|
||||
$builder->addResource($resource);
|
||||
}
|
||||
}
|
||||
|
||||
// mount into this builder
|
||||
@@ -111,7 +118,7 @@ class RouteCollectionBuilder
|
||||
* @param string $prefix
|
||||
* @param RouteCollectionBuilder $builder
|
||||
*/
|
||||
public function mount($prefix, RouteCollectionBuilder $builder)
|
||||
public function mount($prefix, self $builder)
|
||||
{
|
||||
$builder->prefix = trim(trim($prefix), '/');
|
||||
$this->routes[] = $builder;
|
||||
@@ -120,7 +127,6 @@ class RouteCollectionBuilder
|
||||
/**
|
||||
* Adds a Route object to the builder.
|
||||
*
|
||||
* @param Route $route
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return $this
|
||||
@@ -198,7 +204,7 @@ class RouteCollectionBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an opiton that will be added to all embedded routes (unless that
|
||||
* Sets an option that will be added to all embedded routes (unless that
|
||||
* option is already set).
|
||||
*
|
||||
* @param string $key
|
||||
@@ -244,8 +250,6 @@ class RouteCollectionBuilder
|
||||
/**
|
||||
* Adds a resource for this collection.
|
||||
*
|
||||
* @param ResourceInterface $resource
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function addResource(ResourceInterface $resource)
|
||||
@@ -269,7 +273,6 @@ class RouteCollectionBuilder
|
||||
$route->setDefaults(array_merge($this->defaults, $route->getDefaults()));
|
||||
$route->setOptions(array_merge($this->options, $route->getOptions()));
|
||||
|
||||
// we're extra careful here to avoid re-setting deprecated _method and _scheme
|
||||
foreach ($this->requirements as $key => $val) {
|
||||
if (!$route->hasRequirement($key)) {
|
||||
$route->setRequirement($key, $val);
|
||||
@@ -328,7 +331,7 @@ class RouteCollectionBuilder
|
||||
$methods = implode('_', $route->getMethods()).'_';
|
||||
|
||||
$routeName = $methods.$route->getPath();
|
||||
$routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName);
|
||||
$routeName = str_replace(['/', ':', '|', '-'], '_', $routeName);
|
||||
$routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName);
|
||||
|
||||
// Collapse consecutive underscores down into a single underscore.
|
||||
@@ -343,7 +346,7 @@ class RouteCollectionBuilder
|
||||
* @param mixed $resource A resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*
|
||||
* @return RouteCollection
|
||||
* @return RouteCollection[]
|
||||
*
|
||||
* @throws FileLoaderLoadException If no loader is found
|
||||
*/
|
||||
@@ -354,17 +357,21 @@ class RouteCollectionBuilder
|
||||
}
|
||||
|
||||
if ($this->loader->supports($resource, $type)) {
|
||||
return $this->loader->load($resource, $type);
|
||||
$collections = $this->loader->load($resource, $type);
|
||||
|
||||
return \is_array($collections) ? $collections : [$collections];
|
||||
}
|
||||
|
||||
if (null === $resolver = $this->loader->getResolver()) {
|
||||
throw new FileLoaderLoadException($resource);
|
||||
throw new FileLoaderLoadException($resource, null, null, null, $type);
|
||||
}
|
||||
|
||||
if (false === $loader = $resolver->resolve($resource, $type)) {
|
||||
throw new FileLoaderLoadException($resource);
|
||||
throw new FileLoaderLoadException($resource, null, null, null, $type);
|
||||
}
|
||||
|
||||
return $loader->load($resource, $type);
|
||||
$collections = $loader->load($resource, $type);
|
||||
|
||||
return \is_array($collections) ? $collections : [$collections];
|
||||
}
|
||||
}
|
||||
|
||||
121
vendor/symfony/routing/RouteCompiler.php
vendored
121
vendor/symfony/routing/RouteCompiler.php
vendored
@@ -39,16 +39,17 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \LogicException If a variable is referenced more than once
|
||||
* @throws \DomainException if a variable name starts with a digit or if it is too long to be successfully used as
|
||||
* a PCRE subpattern
|
||||
* @throws \InvalidArgumentException if a path variable is named _fragment
|
||||
* @throws \LogicException if a variable is referenced more than once
|
||||
* @throws \DomainException if a variable name starts with a digit or if it is too long to be successfully used as
|
||||
* a PCRE subpattern
|
||||
*/
|
||||
public static function compile(Route $route)
|
||||
{
|
||||
$hostVariables = array();
|
||||
$variables = array();
|
||||
$hostVariables = [];
|
||||
$variables = [];
|
||||
$hostRegex = null;
|
||||
$hostTokens = array();
|
||||
$hostTokens = [];
|
||||
|
||||
if ('' !== $host = $route->getHost()) {
|
||||
$result = self::compilePattern($route, $host, true);
|
||||
@@ -67,6 +68,13 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
$staticPrefix = $result['staticPrefix'];
|
||||
|
||||
$pathVariables = $result['variables'];
|
||||
|
||||
foreach ($pathVariables as $pathParam) {
|
||||
if ('_fragment' === $pathParam) {
|
||||
throw new \InvalidArgumentException(sprintf('Route pattern "%s" cannot contain "_fragment" as a path parameter.', $route->getPath()));
|
||||
}
|
||||
}
|
||||
|
||||
$variables = array_merge($variables, $pathVariables);
|
||||
|
||||
$tokens = $result['tokens'];
|
||||
@@ -86,11 +94,21 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
|
||||
private static function compilePattern(Route $route, $pattern, $isHost)
|
||||
{
|
||||
$tokens = array();
|
||||
$variables = array();
|
||||
$matches = array();
|
||||
$tokens = [];
|
||||
$variables = [];
|
||||
$matches = [];
|
||||
$pos = 0;
|
||||
$defaultSeparator = $isHost ? '.' : '/';
|
||||
$useUtf8 = preg_match('//u', $pattern);
|
||||
$needsUtf8 = $route->getOption('utf8');
|
||||
|
||||
if (!$needsUtf8 && $useUtf8 && preg_match('/[\x80-\xFF]/', $pattern)) {
|
||||
$needsUtf8 = true;
|
||||
@trigger_error(sprintf('Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "%s".', $pattern), E_USER_DEPRECATED);
|
||||
}
|
||||
if (!$useUtf8 && $needsUtf8) {
|
||||
throw new \LogicException(sprintf('Cannot mix UTF-8 requirements with non-UTF-8 pattern "%s".', $pattern));
|
||||
}
|
||||
|
||||
// Match all variables enclosed in "{}" and iterate over them. But we only want to match the innermost variable
|
||||
// in case of nested "{}", e.g. {foo{bar}}. This in ensured because \w does not match "{" or "}" itself.
|
||||
@@ -100,7 +118,15 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
// get all static text preceding the current variable
|
||||
$precedingText = substr($pattern, $pos, $match[0][1] - $pos);
|
||||
$pos = $match[0][1] + \strlen($match[0][0]);
|
||||
$precedingChar = \strlen($precedingText) > 0 ? substr($precedingText, -1) : '';
|
||||
|
||||
if (!\strlen($precedingText)) {
|
||||
$precedingChar = '';
|
||||
} elseif ($useUtf8) {
|
||||
preg_match('/.$/u', $precedingText, $precedingChar);
|
||||
$precedingChar = $precedingChar[0];
|
||||
} else {
|
||||
$precedingChar = substr($precedingText, -1);
|
||||
}
|
||||
$isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar);
|
||||
|
||||
// A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the
|
||||
@@ -116,10 +142,10 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));
|
||||
}
|
||||
|
||||
if ($isSeparator && \strlen($precedingText) > 1) {
|
||||
$tokens[] = array('text', substr($precedingText, 0, -1));
|
||||
if ($isSeparator && $precedingText !== $precedingChar) {
|
||||
$tokens[] = ['text', substr($precedingText, 0, -\strlen($precedingChar))];
|
||||
} elseif (!$isSeparator && \strlen($precedingText) > 0) {
|
||||
$tokens[] = array('text', $precedingText);
|
||||
$tokens[] = ['text', $precedingText];
|
||||
}
|
||||
|
||||
$regexp = $route->getRequirement($varName);
|
||||
@@ -128,11 +154,11 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
// Find the next static character after the variable that functions as a separator. By default, this separator and '/'
|
||||
// are disallowed for the variable. This default requirement makes sure that optional variables can be matched at all
|
||||
// and that the generating-matching-combination of URLs unambiguous, i.e. the params used for generating the URL are
|
||||
// the same that will be matched. Example: new Route('/{page}.{_format}', array('_format' => 'html'))
|
||||
// the same that will be matched. Example: new Route('/{page}.{_format}', ['_format' => 'html'])
|
||||
// If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything.
|
||||
// Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally
|
||||
// part of {_format} when generating the URL, e.g. _format = 'mobile.html'.
|
||||
$nextSeparator = self::findNextSeparator($followingPattern);
|
||||
$nextSeparator = self::findNextSeparator($followingPattern, $useUtf8);
|
||||
$regexp = sprintf(
|
||||
'[^%s%s]+',
|
||||
preg_quote($defaultSeparator, self::REGEX_DELIMITER),
|
||||
@@ -146,14 +172,24 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
// directly adjacent, e.g. '/{x}{y}'.
|
||||
$regexp .= '+';
|
||||
}
|
||||
} else {
|
||||
if (!preg_match('//u', $regexp)) {
|
||||
$useUtf8 = false;
|
||||
} elseif (!$needsUtf8 && preg_match('/[\x80-\xFF]|(?<!\\\\)\\\\(?:\\\\\\\\)*+(?-i:X|[pP][\{CLMNPSZ]|x\{[A-Fa-f0-9]{3})/', $regexp)) {
|
||||
$needsUtf8 = true;
|
||||
@trigger_error(sprintf('Using UTF-8 route requirements without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for variable "%s" in pattern "%s".', $varName, $pattern), E_USER_DEPRECATED);
|
||||
}
|
||||
if (!$useUtf8 && $needsUtf8) {
|
||||
throw new \LogicException(sprintf('Cannot mix UTF-8 requirement with non-UTF-8 charset for variable "%s" in pattern "%s".', $varName, $pattern));
|
||||
}
|
||||
}
|
||||
|
||||
$tokens[] = array('variable', $isSeparator ? $precedingChar : '', $regexp, $varName);
|
||||
$tokens[] = ['variable', $isSeparator ? $precedingChar : '', $regexp, $varName];
|
||||
$variables[] = $varName;
|
||||
}
|
||||
|
||||
if ($pos < \strlen($pattern)) {
|
||||
$tokens[] = array('text', substr($pattern, $pos));
|
||||
$tokens[] = ['text', substr($pattern, $pos)];
|
||||
}
|
||||
|
||||
// find the first optional token
|
||||
@@ -174,32 +210,69 @@ class RouteCompiler implements RouteCompilerInterface
|
||||
for ($i = 0, $nbToken = \count($tokens); $i < $nbToken; ++$i) {
|
||||
$regexp .= self::computeRegexp($tokens, $i, $firstOptional);
|
||||
}
|
||||
$regexp = self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'sD'.($isHost ? 'i' : '');
|
||||
|
||||
return array(
|
||||
'staticPrefix' => 'text' === $tokens[0][0] ? $tokens[0][1] : '',
|
||||
'regex' => self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'sD'.($isHost ? 'i' : ''),
|
||||
// enable Utf8 matching if really required
|
||||
if ($needsUtf8) {
|
||||
$regexp .= 'u';
|
||||
for ($i = 0, $nbToken = \count($tokens); $i < $nbToken; ++$i) {
|
||||
if ('variable' === $tokens[$i][0]) {
|
||||
$tokens[$i][] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'staticPrefix' => self::determineStaticPrefix($route, $tokens),
|
||||
'regex' => $regexp,
|
||||
'tokens' => array_reverse($tokens),
|
||||
'variables' => $variables,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the longest static prefix possible for a route.
|
||||
*
|
||||
* @return string The leading static part of a route's path
|
||||
*/
|
||||
private static function determineStaticPrefix(Route $route, array $tokens)
|
||||
{
|
||||
if ('text' !== $tokens[0][0]) {
|
||||
return ($route->hasDefault($tokens[0][3]) || '/' === $tokens[0][1]) ? '' : $tokens[0][1];
|
||||
}
|
||||
|
||||
$prefix = $tokens[0][1];
|
||||
|
||||
if (isset($tokens[1][1]) && '/' !== $tokens[1][1] && false === $route->hasDefault($tokens[1][3])) {
|
||||
$prefix .= $tokens[1][1];
|
||||
}
|
||||
|
||||
return $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next static character in the Route pattern that will serve as a separator.
|
||||
*
|
||||
* @param string $pattern The route pattern
|
||||
* @param bool $useUtf8 Whether the character is encoded in UTF-8 or not
|
||||
*
|
||||
* @return string The next static character that functions as separator (or empty string when none available)
|
||||
*/
|
||||
private static function findNextSeparator($pattern)
|
||||
private static function findNextSeparator($pattern, $useUtf8)
|
||||
{
|
||||
if ('' == $pattern) {
|
||||
// return empty string if pattern is empty or false (false which can be returned by substr)
|
||||
return '';
|
||||
}
|
||||
// first remove all placeholders from the pattern so we can find the next real static character
|
||||
$pattern = preg_replace('#\{\w+\}#', '', $pattern);
|
||||
if ('' === $pattern = preg_replace('#\{\w+\}#', '', $pattern)) {
|
||||
return '';
|
||||
}
|
||||
if ($useUtf8) {
|
||||
preg_match('/^./u', $pattern, $pattern);
|
||||
}
|
||||
|
||||
return isset($pattern[0]) && false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';
|
||||
return false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
90
vendor/symfony/routing/Router.php
vendored
90
vendor/symfony/routing/Router.php
vendored
@@ -66,7 +66,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array();
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @var LoggerInterface|null
|
||||
@@ -81,7 +81,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
*/
|
||||
private $expressionLanguageProviders = array();
|
||||
private $expressionLanguageProviders = [];
|
||||
|
||||
/**
|
||||
* @param LoaderInterface $loader A LoaderInterface instance
|
||||
@@ -90,7 +90,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
* @param RequestContext $context The context
|
||||
* @param LoggerInterface $logger A logger instance
|
||||
*/
|
||||
public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
|
||||
public function __construct(LoaderInterface $loader, $resource, array $options = [], RequestContext $context = null, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
$this->resource = $resource;
|
||||
@@ -124,7 +124,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->options = array(
|
||||
$this->options = [
|
||||
'cache_dir' => null,
|
||||
'debug' => false,
|
||||
'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
@@ -137,12 +137,12 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
'matcher_cache_class' => 'ProjectUrlMatcher',
|
||||
'resource_type' => null,
|
||||
'strict_requirements' => true,
|
||||
);
|
||||
];
|
||||
|
||||
// check option names and live merge, if errors are encountered Exception will be thrown
|
||||
$invalid = array();
|
||||
$invalid = [];
|
||||
foreach ($options as $key => $value) {
|
||||
if (array_key_exists($key, $this->options)) {
|
||||
if (\array_key_exists($key, $this->options)) {
|
||||
$this->options[$key] = $value;
|
||||
} else {
|
||||
$invalid[] = $key;
|
||||
@@ -164,7 +164,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
*/
|
||||
public function setOption($key, $value)
|
||||
{
|
||||
if (!array_key_exists($key, $this->options)) {
|
||||
if (!\array_key_exists($key, $this->options)) {
|
||||
throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
*/
|
||||
public function getOption($key)
|
||||
{
|
||||
if (!array_key_exists($key, $this->options)) {
|
||||
if (!\array_key_exists($key, $this->options)) {
|
||||
throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
return $this->getGenerator()->generate($name, $parameters, $referenceType);
|
||||
}
|
||||
@@ -263,9 +263,9 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the UrlMatcher instance associated with this Router.
|
||||
* Gets the UrlMatcher or RequestMatcher instance associated with this Router.
|
||||
*
|
||||
* @return UrlMatcherInterface A UrlMatcherInterface instance
|
||||
* @return UrlMatcherInterface|RequestMatcherInterface
|
||||
*/
|
||||
public function getMatcher()
|
||||
{
|
||||
@@ -284,32 +284,29 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
return $this->matcher;
|
||||
}
|
||||
|
||||
$class = $this->options['matcher_cache_class'];
|
||||
$baseClass = $this->options['matcher_base_class'];
|
||||
$expressionLanguageProviders = $this->expressionLanguageProviders;
|
||||
$that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
|
||||
|
||||
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
|
||||
function (ConfigCacheInterface $cache) use ($that, $class, $baseClass, $expressionLanguageProviders) {
|
||||
$dumper = $that->getMatcherDumperInstance();
|
||||
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['matcher_cache_class'].'.php',
|
||||
function (ConfigCacheInterface $cache) {
|
||||
$dumper = $this->getMatcherDumperInstance();
|
||||
if (method_exists($dumper, 'addExpressionLanguageProvider')) {
|
||||
foreach ($expressionLanguageProviders as $provider) {
|
||||
foreach ($this->expressionLanguageProviders as $provider) {
|
||||
$dumper->addExpressionLanguageProvider($provider);
|
||||
}
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'class' => $class,
|
||||
'base_class' => $baseClass,
|
||||
);
|
||||
$options = [
|
||||
'class' => $this->options['matcher_cache_class'],
|
||||
'base_class' => $this->options['matcher_base_class'],
|
||||
];
|
||||
|
||||
$cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
|
||||
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
|
||||
}
|
||||
);
|
||||
|
||||
require_once $cache->getPath();
|
||||
if (!class_exists($this->options['matcher_cache_class'], false)) {
|
||||
require_once $cache->getPath();
|
||||
}
|
||||
|
||||
return $this->matcher = new $class($this->context);
|
||||
return $this->matcher = new $this->options['matcher_cache_class']($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,25 +323,24 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
|
||||
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
|
||||
} else {
|
||||
$class = $this->options['generator_cache_class'];
|
||||
$baseClass = $this->options['generator_base_class'];
|
||||
$that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
|
||||
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
|
||||
function (ConfigCacheInterface $cache) use ($that, $class, $baseClass) {
|
||||
$dumper = $that->getGeneratorDumperInstance();
|
||||
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
|
||||
function (ConfigCacheInterface $cache) {
|
||||
$dumper = $this->getGeneratorDumperInstance();
|
||||
|
||||
$options = array(
|
||||
'class' => $class,
|
||||
'base_class' => $baseClass,
|
||||
);
|
||||
$options = [
|
||||
'class' => $this->options['generator_cache_class'],
|
||||
'base_class' => $this->options['generator_base_class'],
|
||||
];
|
||||
|
||||
$cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
|
||||
$cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
|
||||
}
|
||||
);
|
||||
|
||||
require_once $cache->getPath();
|
||||
if (!class_exists($this->options['generator_cache_class'], false)) {
|
||||
require_once $cache->getPath();
|
||||
}
|
||||
|
||||
$this->generator = new $class($this->context, $this->logger);
|
||||
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
|
||||
}
|
||||
|
||||
if ($this->generator instanceof ConfigurableRequirementsInterface) {
|
||||
@@ -360,25 +356,17 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return GeneratorDumperInterface
|
||||
*/
|
||||
public function getGeneratorDumperInstance()
|
||||
protected function getGeneratorDumperInstance()
|
||||
{
|
||||
return new $this->options['generator_dumper_class']($this->getRouteCollection());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return MatcherDumperInterface
|
||||
*/
|
||||
public function getMatcherDumperInstance()
|
||||
protected function getMatcherDumperInstance()
|
||||
{
|
||||
return new $this->options['matcher_dumper_class']($this->getRouteCollection());
|
||||
}
|
||||
|
||||
3
vendor/symfony/routing/RouterInterface.php
vendored
3
vendor/symfony/routing/RouterInterface.php
vendored
@@ -26,6 +26,9 @@ interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
|
||||
/**
|
||||
* Gets the RouteCollection instance associated with this Router.
|
||||
*
|
||||
* WARNING: This method should never be used at runtime as it is SLOW.
|
||||
* You might use it in a cache warmer though.
|
||||
*
|
||||
* @return RouteCollection A RouteCollection instance
|
||||
*/
|
||||
public function getRouteCollection();
|
||||
|
||||
20
vendor/symfony/routing/composer.json
vendored
20
vendor/symfony/routing/composer.json
vendored
@@ -16,26 +16,28 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.9"
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "~2.7|~3.0.0",
|
||||
"symfony/http-foundation": "~2.3|~3.0.0",
|
||||
"symfony/yaml": "^2.0.5|~3.0.0",
|
||||
"symfony/expression-language": "~2.4|~3.0.0",
|
||||
"symfony/config": "^3.3.1|~4.0",
|
||||
"symfony/http-foundation": "~2.8|~3.0|~4.0",
|
||||
"symfony/yaml": "~3.4|~4.0",
|
||||
"symfony/expression-language": "~2.8|~3.0|~4.0",
|
||||
"symfony/dependency-injection": "~3.3|~4.0",
|
||||
"doctrine/annotations": "~1.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/config": "<2.7"
|
||||
"symfony/config": "<3.3.1",
|
||||
"symfony/dependency-injection": "<3.3",
|
||||
"symfony/yaml": "<3.4"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/http-foundation": "For using a Symfony Request object",
|
||||
"symfony/config": "For using the all-in-one router or any loader",
|
||||
"symfony/yaml": "For using the YAML loader",
|
||||
"symfony/expression-language": "For using expression matching",
|
||||
"doctrine/annotations": "For using the annotation loader",
|
||||
"symfony/dependency-injection": "For loading routes from a service"
|
||||
"doctrine/annotations": "For using the annotation loader"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Routing\\": "" },
|
||||
@@ -46,7 +48,7 @@
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.8-dev"
|
||||
"dev-master": "3.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user