update to laravel 5.7 and try getting autologin saved

This commit is contained in:
Kode
2018-10-14 20:50:32 +01:00
parent c3da17befc
commit 6501aacb1b
2402 changed files with 79064 additions and 28971 deletions

View File

@@ -12,11 +12,11 @@
namespace Symfony\Component\Routing\Loader;
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\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
/**
* AnnotationClassLoader loads routing information from a PHP class and its methods.
@@ -124,6 +124,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
if ($annot instanceof $this->routeAnnotationClass) {
$globals['path'] = '';
$globals['name'] = '';
$globals['localized_paths'] = array();
$this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
}
@@ -142,11 +143,6 @@ abstract class AnnotationClassLoader implements LoaderInterface
$name = $globals['name'].$name;
$defaults = array_replace($globals['defaults'], $annot->getDefaults());
foreach ($method->getParameters() as $param) {
if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) {
$defaults[$param->getName()] = $param->getDefaultValue();
}
}
$requirements = array_replace($globals['requirements'], $annot->getRequirements());
$options = array_replace($globals['options'], $annot->getOptions());
$schemes = array_merge($globals['schemes'], $annot->getSchemes());
@@ -162,11 +158,57 @@ abstract class AnnotationClassLoader implements LoaderInterface
$condition = $globals['condition'];
}
$route = $this->createRoute($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
$path = $annot->getLocalizedPaths() ?: $annot->getPath();
$prefix = $globals['localized_paths'] ?: $globals['path'];
$paths = array();
$this->configureRoute($route, $class, $method, $annot);
if (\is_array($path)) {
if (!\is_array($prefix)) {
foreach ($path as $locale => $localePath) {
$paths[$locale] = $prefix.$localePath;
}
} elseif ($missing = array_diff_key($prefix, $path)) {
throw new \LogicException(sprintf('Route to "%s" is missing paths for locale(s) "%s".', $class->name.'::'.$method->name, implode('", "', array_keys($missing))));
} else {
foreach ($path as $locale => $localePath) {
if (!isset($prefix[$locale])) {
throw new \LogicException(sprintf('Route to "%s" with locale "%s" is missing a corresponding prefix in class "%s".', $method->name, $locale, $class->name));
}
$collection->add($name, $route);
$paths[$locale] = $prefix[$locale].$localePath;
}
}
} elseif (\is_array($prefix)) {
foreach ($prefix as $locale => $localePrefix) {
$paths[$locale] = $localePrefix.$path;
}
} else {
$paths[] = $prefix.$path;
}
foreach ($method->getParameters() as $param) {
if (isset($defaults[$param->name]) || !$param->isDefaultValueAvailable()) {
continue;
}
foreach ($paths as $locale => $path) {
if (false !== strpos($path, sprintf('{%s}', $param->name))) {
$defaults[$param->name] = $param->getDefaultValue();
break;
}
}
}
foreach ($paths as $locale => $path) {
$route = $this->createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
$this->configureRoute($route, $class, $method, $annot);
if (0 !== $locale) {
$route->setDefault('_locale', $locale);
$route->setDefault('_canonical_route', $name);
$collection->add($name.'.'.$locale, $route);
} else {
$collection->add($name, $route);
}
}
}
/**
@@ -174,7 +216,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
*/
public function supports($resource, $type = null)
{
return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
return \is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
}
/**
@@ -213,7 +255,8 @@ abstract class AnnotationClassLoader implements LoaderInterface
protected function getGlobals(\ReflectionClass $class)
{
$globals = array(
'path' => '',
'path' => null,
'localized_paths' => array(),
'requirements' => array(),
'options' => array(),
'defaults' => array(),
@@ -233,6 +276,8 @@ abstract class AnnotationClassLoader implements LoaderInterface
$globals['path'] = $annot->getPath();
}
$globals['localized_paths'] = $annot->getLocalizedPaths();
if (null !== $annot->getRequirements()) {
$globals['requirements'] = $annot->getRequirements();
}

View File

@@ -11,8 +11,8 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Routing\RouteCollection;
/**
* AnnotationDirectoryLoader loads routing information from annotations set
@@ -80,7 +80,7 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
return true;
}
if ($type || !is_string($resource)) {
if ($type || !\is_string($resource)) {
return false;
}

View File

@@ -11,10 +11,10 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\RouteCollection;
/**
* AnnotationFileLoader loads routing information from annotations set
@@ -31,7 +31,7 @@ class AnnotationFileLoader extends FileLoader
*/
public function __construct(FileLocatorInterface $locator, AnnotationClassLoader $loader)
{
if (!function_exists('token_get_all')) {
if (!\function_exists('token_get_all')) {
throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
}
@@ -59,10 +59,9 @@ class AnnotationFileLoader extends FileLoader
$collection->addResource(new FileResource($path));
$collection->addCollection($this->loader->load($class, $type));
}
if (\PHP_VERSION_ID >= 70000) {
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
gc_mem_caches();
}
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
gc_mem_caches();
return $collection;
}
@@ -72,7 +71,7 @@ class AnnotationFileLoader extends FileLoader
*/
public function supports($resource, $type = null)
{
return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
return \is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
}
/**
@@ -88,7 +87,7 @@ class AnnotationFileLoader extends FileLoader
$namespace = false;
$tokens = token_get_all(file_get_contents($file));
if (1 === count($tokens) && T_INLINE_HTML === $tokens[0][0]) {
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));
}
@@ -105,7 +104,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], array(T_NS_SEPARATOR, T_STRING))) {
$namespace .= $tokens[$i][1];
}
$token = $tokens[$i];
@@ -122,7 +121,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], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
break;
}
}

View File

@@ -24,37 +24,27 @@ class CollectionConfigurator
private $parent;
private $parentConfigurator;
private $parentPrefixes;
public function __construct(RouteCollection $parent, $name, self $parentConfigurator = null)
public function __construct(RouteCollection $parent, string $name, self $parentConfigurator = null, array $parentPrefixes = null)
{
$this->parent = $parent;
$this->name = $name;
$this->collection = new RouteCollection();
$this->route = new Route('');
$this->parentConfigurator = $parentConfigurator; // for GC control
$this->parentPrefixes = $parentPrefixes;
}
public function __destruct()
{
$this->collection->addPrefix(rtrim($this->route->getPath(), '/'));
if (null === $this->prefixes) {
$this->collection->addPrefix($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.
*
@@ -62,20 +52,44 @@ class CollectionConfigurator
*/
final public function collection($name = '')
{
return new self($this->collection, $this->name.$name, $this);
return new self($this->collection, $this->name.$name, $this, $this->prefixes);
}
/**
* Sets the prefix to add to the path of all child routes.
*
* @param string $prefix
* @param string|array $prefix the prefix, or the localized prefixes
*
* @return $this
*/
final public function prefix($prefix)
{
$this->route->setPath($prefix);
if (\is_array($prefix)) {
if (null === $this->parentPrefixes) {
// no-op
} elseif ($missing = array_diff_key($this->parentPrefixes, $prefix)) {
throw new \LogicException(sprintf('Collection "%s" is missing prefixes for locale(s) "%s".', $this->name, implode('", "', array_keys($missing))));
} else {
foreach ($prefix as $locale => $localePrefix) {
if (!isset($this->parentPrefixes[$locale])) {
throw new \LogicException(sprintf('Collection "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $this->name, $locale));
}
$prefix[$locale] = $this->parentPrefixes[$locale].$localePrefix;
}
}
$this->prefixes = $prefix;
$this->route->setPath('/');
} else {
$this->prefixes = null;
$this->route->setPath($prefix);
}
return $this;
}
private function createRoute($path): Route
{
return (clone $this->route)->setPath($path);
}
}

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
@@ -36,13 +37,56 @@ class ImportConfigurator
/**
* Sets the prefix to add to the path of all child routes.
*
* @param string $prefix
* @param string|array $prefix the prefix, or the localized prefixes
*
* @return $this
*/
final public function prefix($prefix)
final public function prefix($prefix, bool $trailingSlashOnRoot = true)
{
$this->route->addPrefix($prefix);
if (!\is_array($prefix)) {
$this->route->addPrefix($prefix);
if (!$trailingSlashOnRoot) {
$rootPath = (new Route(trim(trim($prefix), '/').'/'))->getPath();
foreach ($this->route->all() as $route) {
if ($route->getPath() === $rootPath) {
$route->setPath(rtrim($rootPath, '/'));
}
}
}
} else {
foreach ($prefix as $locale => $localePrefix) {
$prefix[$locale] = trim(trim($localePrefix), '/');
}
foreach ($this->route->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) {
$this->route->remove($name);
foreach ($prefix as $locale => $localePrefix) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$this->route->add($name.'.'.$locale, $localizedRoute);
}
} elseif (!isset($prefix[$locale])) {
throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale));
} else {
$route->setPath($prefix[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$this->route->add($name, $route);
}
}
}
return $this;
}
/**
* Sets the prefix to add to the name of all child routes.
*
* @return $this
*/
final public function namePrefix(string $namePrefix)
{
$this->route->addNamePrefix($namePrefix);
return $this;
}

View File

@@ -11,7 +11,6 @@
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
@@ -24,11 +23,12 @@ class RouteConfigurator
private $parentConfigurator;
public function __construct(RouteCollection $collection, Route $route, $name = '', CollectionConfigurator $parentConfigurator = null)
public function __construct(RouteCollection $collection, $route, string $name = '', CollectionConfigurator $parentConfigurator = null, array $prefixes = null)
{
$this->collection = $collection;
$this->route = $route;
$this->name = $name;
$this->parentConfigurator = $parentConfigurator; // for GC control
$this->prefixes = $prefixes;
}
}

View File

@@ -25,7 +25,7 @@ class RoutingConfigurator
private $path;
private $file;
public function __construct(RouteCollection $collection, PhpFileLoader $loader, $path, $file)
public function __construct(RouteCollection $collection, PhpFileLoader $loader, string $path, string $file)
{
$this->collection = $collection;
$this->loader = $loader;
@@ -38,9 +38,9 @@ class RoutingConfigurator
*/
final public function import($resource, $type = null, $ignoreErrors = false)
{
$this->loader->setCurrentDir(dirname($this->path));
$this->loader->setCurrentDir(\dirname($this->path));
$imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file);
if (!is_array($imported)) {
if (!\is_array($imported)) {
return new ImportConfigurator($this->collection, $imported);
}

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\Routing\Loader\Configurator\Traits;
use Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
@@ -24,32 +25,66 @@ trait AddTrait
private $name = '';
private $prefixes;
/**
* Adds a route.
*
* @param string $name
* @param string $path
*
* @return RouteConfigurator
* @param string|array $path the path, or the localized paths of the route
*/
final public function add($name, $path)
final public function add(string $name, $path): RouteConfigurator
{
$parentConfigurator = $this instanceof RouteConfigurator ? $this->parentConfigurator : null;
$this->collection->add($this->name.$name, $route = new Route($path));
$paths = array();
$parentConfigurator = $this instanceof CollectionConfigurator ? $this : ($this instanceof RouteConfigurator ? $this->parentConfigurator : null);
return new RouteConfigurator($this->collection, $route, '', $parentConfigurator);
if (\is_array($path)) {
if (null === $this->prefixes) {
$paths = $path;
} elseif ($missing = array_diff_key($this->prefixes, $path)) {
throw new \LogicException(sprintf('Route "%s" is missing routes for locale(s) "%s".', $name, implode('", "', array_keys($missing))));
} else {
foreach ($path as $locale => $localePath) {
if (!isset($this->prefixes[$locale])) {
throw new \LogicException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale));
}
$paths[$locale] = $this->prefixes[$locale].$localePath;
}
}
} elseif (null !== $this->prefixes) {
foreach ($this->prefixes as $locale => $prefix) {
$paths[$locale] = $prefix.$path;
}
} else {
$this->collection->add($this->name.$name, $route = $this->createRoute($path));
return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes);
}
$routes = new RouteCollection();
foreach ($paths as $locale => $path) {
$routes->add($name.'.'.$locale, $route = $this->createRoute($path));
$this->collection->add($this->name.$name.'.'.$locale, $route);
$route->setDefault('_locale', $locale);
$route->setDefault('_canonical_route', $this->name.$name);
}
return new RouteConfigurator($this->collection, $routes, $this->name, $parentConfigurator, $this->prefixes);
}
/**
* Adds a route.
*
* @param string $name
* @param string $path
*
* @return RouteConfigurator
* @param string|array $path the path, or the localized paths of the route
*/
final public function __invoke($name, $path)
final public function __invoke(string $name, $path): RouteConfigurator
{
return $this->add($name, $path);
}
private function createRoute($path): Route
{
return new Route($path);
}
}

View File

@@ -60,11 +60,9 @@ trait RouteTrait
/**
* Sets the condition.
*
* @param string $condition
*
* @return $this
*/
final public function condition($condition)
final public function condition(string $condition)
{
$this->route->setCondition($condition);
@@ -74,11 +72,9 @@ trait RouteTrait
/**
* Sets the pattern for the host.
*
* @param string $pattern
*
* @return $this
*/
final public function host($pattern)
final public function host(string $pattern)
{
$this->route->setHost($pattern);

View File

@@ -12,8 +12,8 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Routing\RouteCollection;
class DirectoryLoader extends FileLoader
{

View File

@@ -44,9 +44,14 @@ abstract class ObjectRouteLoader extends Loader
*/
public function load($resource, $type = null)
{
$parts = explode(':', $resource);
if (2 != count($parts)) {
throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the "service" route loader: use the format "service_name:methodName"', $resource));
if (1 === substr_count($resource, ':')) {
$resource = str_replace(':', '::', $resource);
@trigger_error(sprintf('Referencing service route loaders with a single colon is deprecated since Symfony 4.1. Use %s instead.', $resource), E_USER_DEPRECATED);
}
$parts = explode('::', $resource);
if (2 != \count($parts)) {
throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the "service" route loader: use the format "service::method"', $resource));
}
$serviceString = $parts[0];
@@ -54,20 +59,20 @@ abstract class ObjectRouteLoader extends Loader
$loaderObject = $this->getServiceObject($serviceString);
if (!is_object($loaderObject)) {
throw new \LogicException(sprintf('%s:getServiceObject() must return an object: %s returned', get_class($this), gettype($loaderObject)));
if (!\is_object($loaderObject)) {
throw new \LogicException(sprintf('%s:getServiceObject() must return an object: %s returned', \get_class($this), \gettype($loaderObject)));
}
if (!method_exists($loaderObject, $method)) {
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, get_class($loaderObject), $resource));
if (!\is_callable(array($loaderObject, $method))) {
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(array($loaderObject, $method), $this);
if (!$routeCollection instanceof RouteCollection) {
$type = is_object($routeCollection) ? get_class($routeCollection) : gettype($routeCollection);
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', get_class($loaderObject), $method, $type));
throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', \get_class($loaderObject), $method, $type));
}
// make the service file tracked so that if it changes, the cache rebuilds

View File

@@ -36,7 +36,7 @@ class PhpFileLoader extends FileLoader
public function load($file, $type = null)
{
$path = $this->locator->locate($file);
$this->setCurrentDir(dirname($path));
$this->setCurrentDir(\dirname($path));
// the closure forbids access to the private scope in the included file
$loader = $this;
@@ -46,7 +46,7 @@ class PhpFileLoader extends FileLoader
$result = $load($path);
if ($result instanceof \Closure) {
if (\is_object($result) && \is_callable($result)) {
$collection = new RouteCollection();
$result(new RoutingConfigurator($collection, $this, $path, $file), $this);
} else {
@@ -63,7 +63,7 @@ class PhpFileLoader extends FileLoader
*/
public function supports($resource, $type = null)
{
return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
return \is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
}
}

View File

@@ -11,11 +11,11 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* XmlFileLoader loads XML routing files.
@@ -93,7 +93,7 @@ class XmlFileLoader extends FileLoader
*/
public function supports($resource, $type = null)
{
return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type);
return \is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type);
}
/**
@@ -107,17 +107,34 @@ class XmlFileLoader extends FileLoader
*/
protected function parseRoute(RouteCollection $collection, \DOMElement $node, $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 ('' === $id = $node->getAttribute('id')) {
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" attribute.', $path));
}
$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);
list($defaults, $requirements, $options, $condition, $paths) = $this->parseConfigs($node, $path);
$route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
$collection->add($id, $route);
if (!$paths && '' === $node->getAttribute('path')) {
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have a "path" attribute or <path> child nodes.', $path));
}
if ($paths && '' !== $node->getAttribute('path')) {
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must not have both a "path" attribute and <path> child nodes.', $path));
}
if (!$paths) {
$route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
$collection->add($id, $route);
} else {
foreach ($paths as $locale => $p) {
$defaults['_locale'] = $locale;
$defaults['_canonical_route'] = $id;
$route = new Route($p, $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
$collection->add($id.'.'.$locale, $route);
}
}
}
/**
@@ -141,20 +158,57 @@ class XmlFileLoader extends FileLoader
$host = $node->hasAttribute('host') ? $node->getAttribute('host') : null;
$schemes = $node->hasAttribute('schemes') ? preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY) : null;
$methods = $node->hasAttribute('methods') ? preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY) : null;
$trailingSlashOnRoot = $node->hasAttribute('trailing-slash-on-root') ? XmlUtils::phpize($node->getAttribute('trailing-slash-on-root')) : true;
list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
list($defaults, $requirements, $options, $condition, /* $paths */, $prefixes) = $this->parseConfigs($node, $path);
$this->setCurrentDir(dirname($path));
if ('' !== $prefix && $prefixes) {
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must not have both a "prefix" attribute and <prefix> child nodes.', $path));
}
$this->setCurrentDir(\dirname($path));
$imported = $this->import($resource, ('' !== $type ? $type : null), false, $file);
if (!is_array($imported)) {
if (!\is_array($imported)) {
$imported = array($imported);
}
foreach ($imported as $subCollection) {
/* @var $subCollection RouteCollection */
$subCollection->addPrefix($prefix);
if ('' !== $prefix || !$prefixes) {
$subCollection->addPrefix($prefix);
if (!$trailingSlashOnRoot) {
$rootPath = (new Route(trim(trim($prefix), '/').'/'))->getPath();
foreach ($subCollection->all() as $route) {
if ($route->getPath() === $rootPath) {
$route->setPath(rtrim($rootPath, '/'));
}
}
}
} else {
foreach ($prefixes as $locale => $localePrefix) {
$prefixes[$locale] = trim(trim($localePrefix), '/');
}
foreach ($subCollection->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) {
$subCollection->remove($name);
foreach ($prefixes as $locale => $localePrefix) {
$localizedRoute = clone $route;
$localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$subCollection->add($name.'.'.$locale, $localizedRoute);
}
} elseif (!isset($prefixes[$locale])) {
throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix when imported in "%s".', $name, $locale, $path));
} else {
$route->setPath($prefixes[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$subCollection->add($name, $route);
}
}
}
if (null !== $host) {
$subCollection->setHost($host);
}
@@ -171,6 +225,10 @@ class XmlFileLoader extends FileLoader
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
if ($namePrefix = $node->getAttribute('name-prefix')) {
$subCollection->addNamePrefix($namePrefix);
}
$collection->addCollection($subCollection);
}
}
@@ -207,6 +265,8 @@ class XmlFileLoader extends FileLoader
$requirements = array();
$options = array();
$condition = null;
$prefixes = array();
$paths = array();
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
if ($node !== $n->parentNode) {
@@ -214,6 +274,12 @@ class XmlFileLoader extends FileLoader
}
switch ($n->localName) {
case 'path':
$paths[$n->getAttribute('locale')] = trim($n->textContent);
break;
case 'prefix':
$prefixes[$n->getAttribute('locale')] = trim($n->textContent);
break;
case 'default':
if ($this->isElementValueNull($n)) {
$defaults[$n->getAttribute('key')] = null;
@@ -246,7 +312,7 @@ class XmlFileLoader extends FileLoader
$defaults['_controller'] = $controller;
}
return array($defaults, $requirements, $options, $condition);
return array($defaults, $requirements, $options, $condition, $paths, $prefixes);
}
/**

View File

@@ -11,12 +11,13 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser as YamlParser;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Yaml\Yaml;
/**
* YamlFileLoader loads Yaml routing files.
@@ -27,7 +28,7 @@ use Symfony\Component\Config\Loader\FileLoader;
class YamlFileLoader extends FileLoader
{
private static $availableKeys = array(
'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller',
'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller', 'name_prefix', 'trailing_slash_on_root',
);
private $yamlParser;
@@ -57,18 +58,10 @@ 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->parseFile($path);
$parsedConfig = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT);
} 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();
@@ -80,7 +73,7 @@ class YamlFileLoader extends FileLoader
}
// not an array
if (!is_array($parsedConfig)) {
if (!\is_array($parsedConfig)) {
throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
}
@@ -102,7 +95,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), array('yml', 'yaml'), true) && (!$type || 'yaml' === $type);
}
/**
@@ -127,9 +120,20 @@ class YamlFileLoader extends FileLoader
$defaults['_controller'] = $config['controller'];
}
$route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
if (\is_array($config['path'])) {
$route = new Route('', $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
$collection->add($name, $route);
foreach ($config['path'] as $locale => $path) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($path);
$collection->add($name.'.'.$locale, $localizedRoute);
}
} else {
$route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
$collection->add($name, $route);
}
}
/**
@@ -151,22 +155,55 @@ class YamlFileLoader extends FileLoader
$condition = isset($config['condition']) ? $config['condition'] : null;
$schemes = isset($config['schemes']) ? $config['schemes'] : null;
$methods = isset($config['methods']) ? $config['methods'] : null;
$trailingSlashOnRoot = $config['trailing_slash_on_root'] ?? true;
if (isset($config['controller'])) {
$defaults['_controller'] = $config['controller'];
}
$this->setCurrentDir(dirname($path));
$this->setCurrentDir(\dirname($path));
$imported = $this->import($config['resource'], $type, false, $file);
if (!is_array($imported)) {
if (!\is_array($imported)) {
$imported = array($imported);
}
foreach ($imported as $subCollection) {
/* @var $subCollection RouteCollection */
$subCollection->addPrefix($prefix);
if (!\is_array($prefix)) {
$subCollection->addPrefix($prefix);
if (!$trailingSlashOnRoot) {
$rootPath = (new Route(trim(trim($prefix), '/').'/'))->getPath();
foreach ($subCollection->all() as $route) {
if ($route->getPath() === $rootPath) {
$route->setPath(rtrim($rootPath, '/'));
}
}
}
} else {
foreach ($prefix as $locale => $localePrefix) {
$prefix[$locale] = trim(trim($localePrefix), '/');
}
foreach ($subCollection->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) {
$subCollection->remove($name);
foreach ($prefix as $locale => $localePrefix) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$subCollection->add($name.'.'.$locale, $localizedRoute);
}
} elseif (!isset($prefix[$locale])) {
throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix when imported in "%s".', $name, $locale, $file));
} else {
$route->setPath($prefix[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$subCollection->add($name, $route);
}
}
}
if (null !== $host) {
$subCollection->setHost($host);
}
@@ -183,6 +220,10 @@ class YamlFileLoader extends FileLoader
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
if (isset($config['name_prefix'])) {
$subCollection->addNamePrefix($config['name_prefix']);
}
$collection->addCollection($subCollection);
}
}
@@ -199,32 +240,20 @@ class YamlFileLoader extends FileLoader
*/
protected function validate($config, $name, $path)
{
if (!is_array($config)) {
if (!\is_array($config)) {
throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
}
if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) {
throw new \InvalidArgumentException(sprintf(
'The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".',
$path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)
));
throw new \InvalidArgumentException(sprintf('The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".', $path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)));
}
if (isset($config['resource']) && isset($config['path'])) {
throw new \InvalidArgumentException(sprintf(
'The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.',
$path, $name
));
throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.', $path, $name));
}
if (!isset($config['resource']) && isset($config['type'])) {
throw new \InvalidArgumentException(sprintf(
'The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.',
$name, $path
));
throw new \InvalidArgumentException(sprintf('The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.', $name, $path));
}
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
));
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));

View File

@@ -24,6 +24,14 @@
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="localized-path">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="locale" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:group name="configs">
<xsd:choice>
<xsd:element name="default" nillable="true" type="default" />
@@ -34,10 +42,12 @@
</xsd:group>
<xsd:complexType name="route">
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:sequence>
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="path" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required" />
<xsd:attribute name="path" type="xsd:string" use="required" />
<xsd:attribute name="path" type="xsd:string" />
<xsd:attribute name="host" type="xsd:string" />
<xsd:attribute name="schemes" type="xsd:string" />
<xsd:attribute name="methods" type="xsd:string" />
@@ -45,15 +55,19 @@
</xsd:complexType>
<xsd:complexType name="import">
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:sequence maxOccurs="unbounded" minOccurs="0">
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="prefix" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="resource" type="xsd:string" use="required" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="prefix" type="xsd:string" />
<xsd:attribute name="name-prefix" type="xsd:string" />
<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:attribute name="trailing-slash-on-root" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="default" mixed="true">