[Routing] Implement i18n routing
This commit is contained in:
parent
a1b241473d
commit
e32c414b04
@ -22,6 +22,7 @@ namespace Symfony\Component\Routing\Annotation;
|
||||
class Route
|
||||
{
|
||||
private $path;
|
||||
private $locales = array();
|
||||
private $name;
|
||||
private $requirements = array();
|
||||
private $options = array();
|
||||
@ -38,11 +39,20 @@ class Route
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
if (isset($data['locales'])) {
|
||||
throw new \BadMethodCallException(sprintf('Unknown property "locales" on annotation "%s".', get_class($this)));
|
||||
}
|
||||
|
||||
if (isset($data['value'])) {
|
||||
$data['path'] = $data['value'];
|
||||
$data[is_array($data['value']) ? 'locales' : 'path'] = $data['value'];
|
||||
unset($data['value']);
|
||||
}
|
||||
|
||||
if (isset($data['path']) && is_array($data['path'])) {
|
||||
$data['locales'] = $data['path'];
|
||||
unset($data['path']);
|
||||
}
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$method = 'set'.str_replace('_', '', $key);
|
||||
if (!method_exists($this, $method)) {
|
||||
@ -62,6 +72,16 @@ class Route
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function setLocales(array $locales)
|
||||
{
|
||||
$this->locales = $locales;
|
||||
}
|
||||
|
||||
public function getLocales(): array
|
||||
{
|
||||
return $this->locales;
|
||||
}
|
||||
|
||||
public function setHost($pattern)
|
||||
{
|
||||
$this->host = $pattern;
|
||||
|
@ -54,11 +54,13 @@ use Psr\Log\LoggerInterface;
|
||||
class {$options['class']} extends {$options['base_class']}
|
||||
{
|
||||
private static \$declaredRoutes;
|
||||
private \$defaultLocale;
|
||||
|
||||
public function __construct(RequestContext \$context, LoggerInterface \$logger = null)
|
||||
public function __construct(RequestContext \$context, LoggerInterface \$logger = null, string \$defaultLocale = null)
|
||||
{
|
||||
\$this->context = \$context;
|
||||
\$this->logger = \$logger;
|
||||
\$this->defaultLocale = \$defaultLocale;
|
||||
if (null === self::\$declaredRoutes) {
|
||||
self::\$declaredRoutes = {$this->generateDeclaredRoutes()};
|
||||
}
|
||||
@ -107,7 +109,14 @@ EOF;
|
||||
return <<<'EOF'
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (!isset(self::$declaredRoutes[$name])) {
|
||||
$locale = $parameters['_locale']
|
||||
?? $this->context->getParameter('_locale')
|
||||
?: $this->defaultLocale;
|
||||
|
||||
if (null !== $locale && isset(self::$declaredRoutes[$name.'.'.$locale])) {
|
||||
unset($parameters['_locale']);
|
||||
$name = $name.'.'.$locale;
|
||||
} elseif (!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));
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
|
||||
protected $logger;
|
||||
|
||||
private $defaultLocale;
|
||||
|
||||
/**
|
||||
* This array defines the characters (besides alphanumeric ones) that will not be percent-encoded in the path segment of the generated URL.
|
||||
*
|
||||
@ -65,11 +67,12 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
'%7C' => '|',
|
||||
);
|
||||
|
||||
public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null)
|
||||
public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null, string $defaultLocale = null)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
$this->context = $context;
|
||||
$this->logger = $logger;
|
||||
$this->defaultLocale = $defaultLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +112,13 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (null === $route = $this->routes->get($name)) {
|
||||
$locale = $parameters['_locale']
|
||||
?? $this->context->getParameter('_locale')
|
||||
?: $this->defaultLocale;
|
||||
|
||||
if (null !== $locale && null !== $route = $this->routes->get($name.'.'.$locale)) {
|
||||
unset($parameters['_locale']);
|
||||
} elseif (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));
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Routing\Loader;
|
||||
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Routing\Annotation\Route as RouteAnnotation;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
@ -119,9 +120,11 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
}
|
||||
}
|
||||
|
||||
/** @var $annot RouteAnnotation */
|
||||
if (0 === $collection->count() && $class->hasMethod('__invoke') && $annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
|
||||
$globals['path'] = '';
|
||||
$globals['path'] = null;
|
||||
$globals['name'] = '';
|
||||
$globals['locales'] = array();
|
||||
$this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
|
||||
}
|
||||
|
||||
@ -137,11 +140,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());
|
||||
@ -157,11 +155,56 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
$condition = $globals['condition'];
|
||||
}
|
||||
|
||||
$route = $this->createRoute($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
|
||||
$path = $annot->getLocales() ?: $annot->getPath();
|
||||
$prefix = $globals['locales'] ?: $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);
|
||||
$collection->add($name.'.'.$locale, $route);
|
||||
} else {
|
||||
$collection->add($name, $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,7 +251,8 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
protected function getGlobals(\ReflectionClass $class)
|
||||
{
|
||||
$globals = array(
|
||||
'path' => '',
|
||||
'path' => null,
|
||||
'locales' => array(),
|
||||
'requirements' => array(),
|
||||
'options' => array(),
|
||||
'defaults' => array(),
|
||||
@ -228,6 +272,8 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
||||
$globals['path'] = $annot->getPath();
|
||||
}
|
||||
|
||||
$globals['locales'] = $annot->getLocales();
|
||||
|
||||
if (null !== $annot->getRequirements()) {
|
||||
$globals['requirements'] = $annot->getRequirements();
|
||||
}
|
||||
|
@ -24,32 +24,27 @@ class CollectionConfigurator
|
||||
|
||||
private $parent;
|
||||
private $parentConfigurator;
|
||||
private $parentPrefixes;
|
||||
|
||||
public function __construct(RouteCollection $parent, string $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.
|
||||
*/
|
||||
final public function add(string $name, string $path): RouteConfigurator
|
||||
{
|
||||
$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.
|
||||
*
|
||||
@ -57,18 +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|array $prefix the prefix, or the localized prefixes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function prefix(string $prefix)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -36,11 +36,35 @@ class ImportConfigurator
|
||||
/**
|
||||
* Sets the prefix to add to the path of all child routes.
|
||||
*
|
||||
* @param string|array $prefix the prefix, or the localized prefixes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function prefix(string $prefix)
|
||||
final public function prefix($prefix)
|
||||
{
|
||||
$this->route->addPrefix($prefix);
|
||||
if (!\is_array($prefix)) {
|
||||
$this->route->addPrefix($prefix);
|
||||
} 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->setPath($localePrefix.$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].$route->getPath());
|
||||
$this->route->add($name, $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -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, string $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;
|
||||
}
|
||||
}
|
||||
|
@ -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,22 +25,65 @@ trait AddTrait
|
||||
|
||||
private $name = '';
|
||||
|
||||
private $prefixes;
|
||||
|
||||
/**
|
||||
* Adds a route.
|
||||
*
|
||||
* @param string|array $path the path, or the localized paths of the route
|
||||
*/
|
||||
final public function add(string $name, string $path): RouteConfigurator
|
||||
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);
|
||||
}
|
||||
|
||||
return new RouteConfigurator($this->collection, $routes, $this->name, $parentConfigurator, $this->prefixes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a route.
|
||||
*
|
||||
* @param string|array $path the path, or the localized paths of the route
|
||||
*/
|
||||
final public function __invoke(string $name, string $path): RouteConfigurator
|
||||
final public function __invoke(string $name, $path): RouteConfigurator
|
||||
{
|
||||
return $this->add($name, $path);
|
||||
}
|
||||
|
||||
private function createRoute($path): Route
|
||||
{
|
||||
return new Route($path);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
$routeName = $id.'.'.$locale;
|
||||
$route = new Route($p, $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
|
||||
$collection->add($routeName, $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,13 +159,41 @@ class XmlFileLoader extends FileLoader
|
||||
$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;
|
||||
|
||||
list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
|
||||
list($defaults, $requirements, $options, $condition, /* $paths */, $prefixes) = $this->parseConfigs($node, $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));
|
||||
|
||||
$subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file);
|
||||
/* @var $subCollection RouteCollection */
|
||||
$subCollection->addPrefix($prefix);
|
||||
$subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file);
|
||||
|
||||
if ('' !== $prefix || !$prefixes) {
|
||||
$subCollection->addPrefix($prefix);
|
||||
} 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.$route->getPath());
|
||||
$localizedRoute->setDefault('_locale', $locale);
|
||||
$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].$route->getPath());
|
||||
$subCollection->add($name, $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $host) {
|
||||
$subCollection->setHost($host);
|
||||
}
|
||||
@ -204,6 +249,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) {
|
||||
@ -211,6 +258,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;
|
||||
@ -243,7 +296,7 @@ class XmlFileLoader extends FileLoader
|
||||
$defaults['_controller'] = $controller;
|
||||
}
|
||||
|
||||
return array($defaults, $requirements, $options, $condition);
|
||||
return array($defaults, $requirements, $options, $condition, $paths, $prefixes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,9 +120,19 @@ 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->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,9 +161,33 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
$this->setCurrentDir(dirname($path));
|
||||
|
||||
/** @var RouteCollection $subCollection */
|
||||
$subCollection = $this->import($config['resource'], $type, false, $file);
|
||||
/* @var $subCollection RouteCollection */
|
||||
$subCollection->addPrefix($prefix);
|
||||
|
||||
if (!\is_array($prefix)) {
|
||||
$subCollection->addPrefix($prefix);
|
||||
} 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->setPath($localePrefix.$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].$route->getPath());
|
||||
$subCollection->add($name, $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $host) {
|
||||
$subCollection->setHost($host);
|
||||
}
|
||||
|
@ -24,6 +24,14 @@
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="localised-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="localised-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,8 +55,10 @@
|
||||
</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="localised-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" />
|
||||
|
@ -24,6 +24,14 @@ class RouteTest extends TestCase
|
||||
$route = new Route(array('foo' => 'bar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \BadMethodCallException
|
||||
*/
|
||||
public function testTryingToSetLocalesDirectly()
|
||||
{
|
||||
$route = new Route(array('locales' => array('nl' => 'bar')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidParameters
|
||||
*/
|
||||
@ -45,6 +53,7 @@ class RouteTest extends TestCase
|
||||
array('methods', array('GET', 'POST'), 'getMethods'),
|
||||
array('host', '{locale}.example.com', 'getHost'),
|
||||
array('condition', 'context.getMethod() == "GET"', 'getCondition'),
|
||||
array('value', array('nl' => '/hier', 'en' => '/here'), 'getLocales'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
abstract class AbstractClassController
|
||||
{
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class ActionPathController
|
||||
{
|
||||
/**
|
||||
* @Route("/path", name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class DefaultValueController
|
||||
{
|
||||
/**
|
||||
* @Route("/{default}/path", name="action")
|
||||
*/
|
||||
public function action($default = 'value')
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class ExplicitLocalizedActionPathController
|
||||
{
|
||||
/**
|
||||
* @Route(path={"en": "/path", "nl": "/pad"}, name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/here", name="lol")
|
||||
*/
|
||||
class InvokableController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route(path={"nl": "/hier", "en": "/here"}, name="action")
|
||||
*/
|
||||
class InvokableLocalizedController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class LocalizedActionPathController
|
||||
{
|
||||
/**
|
||||
* @Route(path={"en": "/path", "nl": "/pad"}, name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route(path={"en": "/the/path", "nl": "/het/pad"})
|
||||
*/
|
||||
class LocalizedMethodActionControllers
|
||||
{
|
||||
/**
|
||||
* @Route(name="post", methods={"POST"})
|
||||
*/
|
||||
public function post()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(name="put", methods={"PUT"})
|
||||
*/
|
||||
public function put()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route(path={"nl": "/nl", "en": "/en"})
|
||||
*/
|
||||
class LocalizedPrefixLocalizedActionController
|
||||
{
|
||||
/**
|
||||
* @Route(path={"nl": "/actie", "en": "/action"}, name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route(path={"nl": "/nl"})
|
||||
*/
|
||||
class LocalizedPrefixMissingLocaleActionController
|
||||
{
|
||||
/**
|
||||
* @Route(path={"nl": "/actie", "en": "/action"}, name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route(path={"nl": "/nl", "en": "/en"})
|
||||
*/
|
||||
class LocalizedPrefixMissingRouteLocaleActionController
|
||||
{
|
||||
/**
|
||||
* @Route(path={"nl": "/actie"}, name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route(path={"en": "/en", "nl": "/nl"})
|
||||
*/
|
||||
class LocalizedPrefixWithRouteWithoutLocale
|
||||
{
|
||||
/**
|
||||
* @Route("/suffix", name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/the/path")
|
||||
*/
|
||||
class MethodActionControllers
|
||||
{
|
||||
/**
|
||||
* @Route(name="post", methods={"POST"})
|
||||
*/
|
||||
public function post()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(name="put", methods={"PUT"})
|
||||
*/
|
||||
public function put()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class MissingRouteNameController
|
||||
{
|
||||
/**
|
||||
* @Route("/path")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class NothingButNameController
|
||||
{
|
||||
/**
|
||||
* @Route(name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/prefix")
|
||||
*/
|
||||
class PrefixedActionLocalizedRouteController
|
||||
{
|
||||
/**
|
||||
* @Route(path={"en": "/path", "nl": "/pad"}, name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/prefix", host="frankdejonge.nl", condition="lol=fun")
|
||||
*/
|
||||
class PrefixedActionPathController
|
||||
{
|
||||
/**
|
||||
* @Route("/path", name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/prefix")
|
||||
*/
|
||||
class RouteWithPrefixController
|
||||
{
|
||||
/**
|
||||
* @Route("/path", name="action")
|
||||
*/
|
||||
public function action()
|
||||
{
|
||||
}
|
||||
}
|
13
src/Symfony/Component/Routing/Tests/Fixtures/localised.xml
Normal file
13
src/Symfony/Component/Routing/Tests/Fixtures/localised.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
|
||||
<route id="localised">
|
||||
<default key="_controller">MyBundle:Blog:show</default>
|
||||
<path locale="en">/path</path>
|
||||
<path locale="fr">/route</path>
|
||||
</route>
|
||||
|
||||
</routes>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing
|
||||
http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
<route id="imported" path="/suffix">
|
||||
<default key="_controller">MyBundle:Blog:show</default>
|
||||
</route>
|
||||
</routes>
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
imported:
|
||||
controller: ImportedController::someAction
|
||||
path: /imported
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing
|
||||
http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
<route id="imported">
|
||||
<default key="_controller">MyBundle:Blog:show</default>
|
||||
<path locale="en">/suffix</path>
|
||||
<path locale="fr">/le-suffix</path>
|
||||
</route>
|
||||
</routes>
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
imported:
|
||||
controller: ImportedController::someAction
|
||||
path:
|
||||
nl: /voorbeeld
|
||||
en: /example
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
i_need:
|
||||
defaults:
|
||||
_controller: DefaultController::defaultAction
|
||||
resource: ./localized-route.yml
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing
|
||||
http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
<import resource="./imported-with-locale-but-not-localized.xml">
|
||||
<prefix locale="fr">/le-prefix</prefix>
|
||||
<prefix locale="en">/the-prefix</prefix>
|
||||
</import>
|
||||
</routes>
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
i_need:
|
||||
resource: ./imported-with-locale-but-not-localized.yml
|
||||
prefix:
|
||||
nl: /nl
|
||||
en: /en
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing
|
||||
http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
<import resource="./imported-with-locale.xml">
|
||||
<prefix locale="fr">/le-prefix</prefix>
|
||||
<prefix locale="en">/the-prefix</prefix>
|
||||
</import>
|
||||
</routes>
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
i_need:
|
||||
resource: ./imported-with-locale.yml
|
||||
prefix:
|
||||
nl: /nl
|
||||
en: /en
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
i_need:
|
||||
resource: ./localized-route.yml
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
home:
|
||||
path:
|
||||
nl: /nl
|
||||
en: /en
|
||||
|
||||
not_localized:
|
||||
controller: HomeController::otherAction
|
||||
path: /here
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
importing_with_missing_prefix:
|
||||
resource: ./localized-route.yml
|
||||
prefix:
|
||||
nl: /prefix
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
not_localized:
|
||||
controller: string
|
||||
path: /here
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
official:
|
||||
controller: HomeController::someAction
|
||||
path:
|
||||
fr.UTF-8: /omelette-au-fromage
|
||||
pt-PT: /eu-não-sou-espanhol
|
||||
pt_BR: /churrasco
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
routename:
|
||||
controller: Here::here
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator;
|
||||
|
||||
return function (RoutingConfigurator $routes) {
|
||||
$routes
|
||||
->collection()
|
||||
->prefix(array('en' => '/glish'))
|
||||
->add('foo', '/foo')
|
||||
->add('bar', array('en' => '/bar'));
|
||||
|
||||
$routes
|
||||
->add('baz', array('en' => '/baz'));
|
||||
|
||||
$routes->import('php_dsl_sub_i18n.php')
|
||||
->prefix(array('fr' => '/ench'));
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Loader\Configurator;
|
||||
|
||||
return function (RoutingConfigurator $routes) {
|
||||
$add = $routes->collection('c_')
|
||||
->prefix('pub');
|
||||
|
||||
$add('foo', array('fr' => '/foo'));
|
||||
$add('bar', array('fr' => '/bar'));
|
||||
};
|
@ -84,6 +84,33 @@ class PhpGeneratorDumperTest extends TestCase
|
||||
$this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
|
||||
}
|
||||
|
||||
public function testDumpWithLocalizedRoutes()
|
||||
{
|
||||
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en'));
|
||||
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl'));
|
||||
|
||||
$code = $this->generatorDumper->dump([
|
||||
'class' => 'LocalizedProjectUrlGenerator',
|
||||
]);
|
||||
file_put_contents($this->testTmpFilepath, $code);
|
||||
include $this->testTmpFilepath;
|
||||
|
||||
$context = new RequestContext('/app.php');
|
||||
$projectUrlGenerator = new \LocalizedProjectUrlGenerator($context, null, 'en');
|
||||
|
||||
$urlWithDefaultLocale = $projectUrlGenerator->generate('test');
|
||||
$urlWithSpecifiedLocale = $projectUrlGenerator->generate('test', ['_locale' => 'nl']);
|
||||
$context->setParameter('_locale', 'en');
|
||||
$urlWithEnglishContext = $projectUrlGenerator->generate('test');
|
||||
$context->setParameter('_locale', 'nl');
|
||||
$urlWithDutchContext = $projectUrlGenerator->generate('test');
|
||||
|
||||
$this->assertEquals('/app.php/testing/is/fun', $urlWithDefaultLocale);
|
||||
$this->assertEquals('/app.php/testen/is/leuk', $urlWithSpecifiedLocale);
|
||||
$this->assertEquals('/app.php/testing/is/fun', $urlWithEnglishContext);
|
||||
$this->assertEquals('/app.php/testen/is/leuk', $urlWithDutchContext);
|
||||
}
|
||||
|
||||
public function testDumpWithTooManyRoutes()
|
||||
{
|
||||
$this->routeCollection->add('Test', new Route('/testing/{foo}'));
|
||||
|
@ -11,35 +11,44 @@
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Loader;
|
||||
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Routing\Loader\AnnotationClassLoader;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\AbstractClassController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\ActionPathController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\DefaultValueController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\ExplicitLocalizedActionPathController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\InvokableController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\InvokableLocalizedController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\LocalizedActionPathController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\LocalizedMethodActionControllers;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\LocalizedPrefixLocalizedActionController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\LocalizedPrefixMissingLocaleActionController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\LocalizedPrefixMissingRouteLocaleActionController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\LocalizedPrefixWithRouteWithoutLocale;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\MethodActionControllers;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\MissingRouteNameController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\NothingButNameController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\PrefixedActionLocalizedRouteController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\PrefixedActionPathController;
|
||||
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\RouteWithPrefixController;
|
||||
|
||||
class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
|
||||
class AnnotationClassLoaderTest extends TestCase
|
||||
{
|
||||
protected $loader;
|
||||
private $reader;
|
||||
/**
|
||||
* @var AnnotationClassLoader
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->reader = $this->getReader();
|
||||
$this->loader = $this->getClassLoader($this->reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testLoadMissingClass()
|
||||
{
|
||||
$this->loader->load('MissingClass');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testLoadAbstractClass()
|
||||
{
|
||||
$this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\AbstractClass');
|
||||
$reader = new AnnotationReader();
|
||||
$this->loader = new class($reader) extends AnnotationClassLoader {
|
||||
protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot) {}
|
||||
};
|
||||
AnnotationRegistry::registerLoader('class_exists');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,187 +78,144 @@ class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
|
||||
$this->assertFalse($this->loader->supports('class', 'foo'), '->supports() checks the resource type if specified');
|
||||
}
|
||||
|
||||
public function getLoadTests()
|
||||
public function testSimplePathRoute()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
||||
array('name' => 'route1', 'path' => '/path'),
|
||||
array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
|
||||
),
|
||||
array(
|
||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
||||
array('defaults' => array('arg2' => 'foo'), 'requirements' => array('arg3' => '\w+')),
|
||||
array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
|
||||
),
|
||||
array(
|
||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
||||
array('options' => array('foo' => 'bar')),
|
||||
array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
|
||||
),
|
||||
array(
|
||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
||||
array('schemes' => array('https'), 'methods' => array('GET')),
|
||||
array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
|
||||
),
|
||||
array(
|
||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
||||
array('condition' => 'context.getMethod() == "GET"'),
|
||||
array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
|
||||
),
|
||||
);
|
||||
$routes = $this->loader->load(ActionPathController::class);
|
||||
$this->assertCount(1, $routes);
|
||||
$this->assertEquals('/path', $routes->get('action')->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadTests
|
||||
*/
|
||||
public function testLoad($className, $routeData = array(), $methodArgs = array())
|
||||
public function testInvokableControllerLoader()
|
||||
{
|
||||
$routeData = array_replace(array(
|
||||
'name' => 'route',
|
||||
'path' => '/',
|
||||
'requirements' => array(),
|
||||
'options' => array(),
|
||||
'defaults' => array(),
|
||||
'schemes' => array(),
|
||||
'methods' => array(),
|
||||
'condition' => '',
|
||||
), $routeData);
|
||||
|
||||
$this->reader
|
||||
->expects($this->once())
|
||||
->method('getMethodAnnotations')
|
||||
->will($this->returnValue(array($this->getAnnotatedRoute($routeData))))
|
||||
;
|
||||
|
||||
$routeCollection = $this->loader->load($className);
|
||||
$route = $routeCollection->get($routeData['name']);
|
||||
|
||||
$this->assertSame($routeData['path'], $route->getPath(), '->load preserves path annotation');
|
||||
$this->assertCount(
|
||||
count($routeData['requirements']),
|
||||
array_intersect_assoc($routeData['requirements'], $route->getRequirements()),
|
||||
'->load preserves requirements annotation'
|
||||
);
|
||||
$this->assertCount(
|
||||
count($routeData['options']),
|
||||
array_intersect_assoc($routeData['options'], $route->getOptions()),
|
||||
'->load preserves options annotation'
|
||||
);
|
||||
$this->assertCount(
|
||||
count($routeData['defaults']),
|
||||
$route->getDefaults(),
|
||||
'->load preserves defaults annotation'
|
||||
);
|
||||
$this->assertEquals($routeData['schemes'], $route->getSchemes(), '->load preserves schemes annotation');
|
||||
$this->assertEquals($routeData['methods'], $route->getMethods(), '->load preserves methods annotation');
|
||||
$this->assertSame($routeData['condition'], $route->getCondition(), '->load preserves condition annotation');
|
||||
$routes = $this->loader->load(InvokableController::class);
|
||||
$this->assertCount(1, $routes);
|
||||
$this->assertEquals('/here', $routes->get('lol')->getPath());
|
||||
}
|
||||
|
||||
public function testClassRouteLoad()
|
||||
public function testInvokableLocalizedControllerLoading()
|
||||
{
|
||||
$classRouteData = array(
|
||||
'name' => 'prefix_',
|
||||
'path' => '/prefix',
|
||||
'schemes' => array('https'),
|
||||
'methods' => array('GET'),
|
||||
);
|
||||
|
||||
$methodRouteData = array(
|
||||
'name' => 'route1',
|
||||
'path' => '/path',
|
||||
'schemes' => array('http'),
|
||||
'methods' => array('POST', 'PUT'),
|
||||
);
|
||||
|
||||
$this->reader
|
||||
->expects($this->once())
|
||||
->method('getClassAnnotation')
|
||||
->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
|
||||
;
|
||||
$this->reader
|
||||
->expects($this->once())
|
||||
->method('getMethodAnnotations')
|
||||
->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
|
||||
;
|
||||
|
||||
$routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass');
|
||||
$route = $routeCollection->get($classRouteData['name'].$methodRouteData['name']);
|
||||
|
||||
$this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
|
||||
$this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
|
||||
$this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
|
||||
$routes = $this->loader->load(InvokableLocalizedController::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/here', $routes->get('action.en')->getPath());
|
||||
$this->assertEquals('/hier', $routes->get('action.nl')->getPath());
|
||||
}
|
||||
|
||||
public function testInvokableClassRouteLoad()
|
||||
public function testLocalizedPathRoutes()
|
||||
{
|
||||
$classRouteData = array(
|
||||
'name' => 'route1',
|
||||
'path' => '/',
|
||||
'schemes' => array('https'),
|
||||
'methods' => array('GET'),
|
||||
);
|
||||
|
||||
$this->reader
|
||||
->expects($this->exactly(2))
|
||||
->method('getClassAnnotation')
|
||||
->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
|
||||
;
|
||||
$this->reader
|
||||
->expects($this->once())
|
||||
->method('getMethodAnnotations')
|
||||
->will($this->returnValue(array()))
|
||||
;
|
||||
|
||||
$routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
|
||||
$route = $routeCollection->get($classRouteData['name']);
|
||||
|
||||
$this->assertSame($classRouteData['path'], $route->getPath(), '->load preserves class route path');
|
||||
$this->assertEquals(array_merge($classRouteData['schemes'], $classRouteData['schemes']), $route->getSchemes(), '->load preserves class route schemes');
|
||||
$this->assertEquals(array_merge($classRouteData['methods'], $classRouteData['methods']), $route->getMethods(), '->load preserves class route methods');
|
||||
$routes = $this->loader->load(LocalizedActionPathController::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/path', $routes->get('action.en')->getPath());
|
||||
$this->assertEquals('/pad', $routes->get('action.nl')->getPath());
|
||||
}
|
||||
|
||||
public function testInvokableClassWithMethodRouteLoad()
|
||||
public function testLocalizedPathRoutesWithExplicitPathPropety()
|
||||
{
|
||||
$classRouteData = array(
|
||||
'name' => 'route1',
|
||||
'path' => '/prefix',
|
||||
'schemes' => array('https'),
|
||||
'methods' => array('GET'),
|
||||
);
|
||||
|
||||
$methodRouteData = array(
|
||||
'name' => 'route2',
|
||||
'path' => '/path',
|
||||
'schemes' => array('http'),
|
||||
'methods' => array('POST', 'PUT'),
|
||||
);
|
||||
|
||||
$this->reader
|
||||
->expects($this->once())
|
||||
->method('getClassAnnotation')
|
||||
->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
|
||||
;
|
||||
$this->reader
|
||||
->expects($this->once())
|
||||
->method('getMethodAnnotations')
|
||||
->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
|
||||
;
|
||||
|
||||
$routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
|
||||
$route = $routeCollection->get($classRouteData['name']);
|
||||
|
||||
$this->assertNull($route, '->load ignores class route');
|
||||
|
||||
$route = $routeCollection->get($classRouteData['name'].$methodRouteData['name']);
|
||||
|
||||
$this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
|
||||
$this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
|
||||
$this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
|
||||
$routes = $this->loader->load(ExplicitLocalizedActionPathController::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/path', $routes->get('action.en')->getPath());
|
||||
$this->assertEquals('/pad', $routes->get('action.nl')->getPath());
|
||||
}
|
||||
|
||||
private function getAnnotatedRoute($data)
|
||||
public function testDefaultValuesForMethods()
|
||||
{
|
||||
return new Route($data);
|
||||
$routes = $this->loader->load(DefaultValueController::class);
|
||||
$this->assertCount(1, $routes);
|
||||
$this->assertEquals('/{default}/path', $routes->get('action')->getPath());
|
||||
$this->assertEquals('value', $routes->get('action')->getDefault('default'));
|
||||
}
|
||||
|
||||
public function testMethodActionControllers()
|
||||
{
|
||||
$routes = $this->loader->load(MethodActionControllers::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/the/path', $routes->get('put')->getPath());
|
||||
$this->assertEquals('/the/path', $routes->get('post')->getPath());
|
||||
}
|
||||
|
||||
public function testLocalizedMethodActionControllers()
|
||||
{
|
||||
$routes = $this->loader->load(LocalizedMethodActionControllers::class);
|
||||
$this->assertCount(4, $routes);
|
||||
$this->assertEquals('/the/path', $routes->get('put.en')->getPath());
|
||||
$this->assertEquals('/the/path', $routes->get('post.en')->getPath());
|
||||
}
|
||||
|
||||
public function testRouteWithPathWithPrefix()
|
||||
{
|
||||
$routes = $this->loader->load(PrefixedActionPathController::class);
|
||||
$this->assertCount(1, $routes);
|
||||
$route = $routes->get('action');
|
||||
$this->assertEquals('/prefix/path', $route->getPath());
|
||||
$this->assertEquals('lol=fun', $route->getCondition());
|
||||
$this->assertEquals('frankdejonge.nl', $route->getHost());
|
||||
}
|
||||
|
||||
public function testLocalizedRouteWithPathWithPrefix()
|
||||
{
|
||||
$routes = $this->loader->load(PrefixedActionLocalizedRouteController::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/prefix/path', $routes->get('action.en')->getPath());
|
||||
$this->assertEquals('/prefix/pad', $routes->get('action.nl')->getPath());
|
||||
}
|
||||
|
||||
public function testLocalizedPrefixLocalizedRoute()
|
||||
{
|
||||
$routes = $this->loader->load(LocalizedPrefixLocalizedActionController::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/nl/actie', $routes->get('action.nl')->getPath());
|
||||
$this->assertEquals('/en/action', $routes->get('action.en')->getPath());
|
||||
}
|
||||
|
||||
public function testMissingPrefixLocale()
|
||||
{
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->loader->load(LocalizedPrefixMissingLocaleActionController::class);
|
||||
}
|
||||
|
||||
public function testMissingRouteLocale()
|
||||
{
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->loader->load(LocalizedPrefixMissingRouteLocaleActionController::class);
|
||||
}
|
||||
|
||||
public function testRouteWithoutName()
|
||||
{
|
||||
$routes = $this->loader->load(MissingRouteNameController::class)->all();
|
||||
$this->assertCount(1, $routes);
|
||||
$this->assertEquals('/path', reset($routes)->getPath());
|
||||
}
|
||||
|
||||
public function testNothingButName()
|
||||
{
|
||||
$routes = $this->loader->load(NothingButNameController::class)->all();
|
||||
$this->assertCount(1, $routes);
|
||||
$this->assertEquals('/', reset($routes)->getPath());
|
||||
}
|
||||
|
||||
public function testNonExistingClass()
|
||||
{
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->loader->load('ClassThatDoesNotExist');
|
||||
}
|
||||
|
||||
public function testLoadingAbstractClass()
|
||||
{
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->loader->load(AbstractClassController::class);
|
||||
}
|
||||
|
||||
public function testLocalizedPrefixWithoutRouteLocale()
|
||||
{
|
||||
$routes = $this->loader->load(LocalizedPrefixWithRouteWithoutLocale::class);
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/en/suffix', $routes->get('action.en')->getPath());
|
||||
$this->assertEquals('/nl/suffix', $routes->get('action.nl')->getPath());
|
||||
}
|
||||
|
||||
public function testLoadingRouteWithPrefix()
|
||||
{
|
||||
$routes = $this->loader->load(RouteWithPrefixController::class);
|
||||
$this->assertCount(1, $routes);
|
||||
$this->assertEquals('/prefix/path', $routes->get('action')->getPath());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Routing\Tests\Loader;
|
||||
|
||||
use Symfony\Component\Config\FileLocatorInterface;
|
||||
|
||||
class FileLocatorStub implements FileLocatorInterface
|
||||
{
|
||||
public function locate($name, $currentPath = null, $first = true)
|
||||
{
|
||||
if (0 === strpos($name, 'http')) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return rtrim($currentPath, '/').'/'.$name;
|
||||
}
|
||||
}
|
@ -117,4 +117,24 @@ class PhpFileLoaderTest extends TestCase
|
||||
|
||||
$this->assertEquals($expectedCollection, $routeCollection);
|
||||
}
|
||||
|
||||
public function testRoutingI18nConfigurator()
|
||||
{
|
||||
$locator = new FileLocator(array(__DIR__.'/../Fixtures'));
|
||||
$loader = new PhpFileLoader($locator);
|
||||
$routeCollection = $loader->load('php_dsl_i18n.php');
|
||||
|
||||
$expectedCollection = new RouteCollection();
|
||||
|
||||
$expectedCollection->add('foo.en', (new Route('/glish/foo'))->setDefaults(array('_locale' => 'en')));
|
||||
$expectedCollection->add('bar.en', (new Route('/glish/bar'))->setDefaults(array('_locale' => 'en')));
|
||||
$expectedCollection->add('baz.en', (new Route('/baz'))->setDefaults(array('_locale' => 'en')));
|
||||
$expectedCollection->add('c_foo.fr', (new Route('/ench/pub/foo'))->setDefaults(array('_locale' => 'fr')));
|
||||
$expectedCollection->add('c_bar.fr', (new Route('/ench/pub/bar'))->setDefaults(array('_locale' => 'fr')));
|
||||
|
||||
$expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub_i18n.php')));
|
||||
$expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_i18n.php')));
|
||||
|
||||
$this->assertEquals($expectedCollection, $routeCollection);
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,45 @@ class XmlFileLoaderTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testLoadLocalized()
|
||||
{
|
||||
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
|
||||
$routeCollection = $loader->load('localised.xml');
|
||||
$routes = $routeCollection->all();
|
||||
|
||||
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||
|
||||
$this->assertEquals('/route', $routeCollection->get('localised.fr')->getPath());
|
||||
$this->assertEquals('/path', $routeCollection->get('localised.en')->getPath());
|
||||
}
|
||||
|
||||
public function testLocalisedImports()
|
||||
{
|
||||
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routeCollection = $loader->load('importer-with-locale.xml');
|
||||
$routes = $routeCollection->all();
|
||||
|
||||
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||
|
||||
$this->assertEquals('/le-prefix/le-suffix', $routeCollection->get('imported.fr')->getPath());
|
||||
$this->assertEquals('/the-prefix/suffix', $routeCollection->get('imported.en')->getPath());
|
||||
}
|
||||
|
||||
public function testLocalisedImportsOfNotLocalizedRoutes()
|
||||
{
|
||||
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routeCollection = $loader->load('importer-with-locale-imports-non-localized-route.xml');
|
||||
$routes = $routeCollection->all();
|
||||
|
||||
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||
|
||||
$this->assertEquals('/le-prefix/suffix', $routeCollection->get('imported.fr')->getPath());
|
||||
$this->assertEquals('/the-prefix/suffix', $routeCollection->get('imported.en')->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @dataProvider getPathsToInvalidFiles
|
||||
|
@ -193,4 +193,86 @@ class YamlFileLoaderTest extends TestCase
|
||||
$this->assertNotNull($routeCollection->get('api_app_blog'));
|
||||
$this->assertEquals('/api/blog', $routeCollection->get('api_app_blog')->getPath());
|
||||
}
|
||||
|
||||
public function testRemoteSourcesAreNotAccepted()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocatorStub());
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$loader->load('http://remote.com/here.yml');
|
||||
}
|
||||
|
||||
public function testLoadingLocalizedRoute()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routes = $loader->load('localized-route.yml');
|
||||
|
||||
$this->assertCount(3, $routes);
|
||||
}
|
||||
|
||||
|
||||
public function testImportingRoutesFromDefinition()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routes = $loader->load('importing-localized-route.yml');
|
||||
|
||||
$this->assertCount(3, $routes);
|
||||
$this->assertEquals('/nl', $routes->get('home.nl')->getPath());
|
||||
$this->assertEquals('/en', $routes->get('home.en')->getPath());
|
||||
$this->assertEquals('/here', $routes->get('not_localized')->getPath());
|
||||
}
|
||||
|
||||
public function testImportingRoutesWithLocales()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routes = $loader->load('importer-with-locale.yml');
|
||||
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/nl/voorbeeld', $routes->get('imported.nl')->getPath());
|
||||
$this->assertEquals('/en/example', $routes->get('imported.en')->getPath());
|
||||
}
|
||||
|
||||
public function testImportingNonLocalizedRoutesWithLocales()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routes = $loader->load('importer-with-locale-imports-non-localized-route.yml');
|
||||
|
||||
$this->assertCount(2, $routes);
|
||||
$this->assertEquals('/nl/imported', $routes->get('imported.nl')->getPath());
|
||||
$this->assertEquals('/en/imported', $routes->get('imported.en')->getPath());
|
||||
}
|
||||
|
||||
public function testImportingRoutesWithOfficialLocales()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routes = $loader->load('officially_formatted_locales.yml');
|
||||
|
||||
$this->assertCount(3, $routes);
|
||||
$this->assertEquals('/omelette-au-fromage', $routes->get('official.fr.UTF-8')->getPath());
|
||||
$this->assertEquals('/eu-não-sou-espanhol', $routes->get('official.pt-PT')->getPath());
|
||||
$this->assertEquals('/churrasco', $routes->get('official.pt_BR')->getPath());
|
||||
}
|
||||
|
||||
public function testImportingRoutesFromDefinitionMissingLocalePrefix()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$loader->load('missing-locale-in-importer.yml');
|
||||
}
|
||||
|
||||
public function testImportingRouteWithoutPathOrLocales()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$loader->load('route-without-path-or-locales.yml');
|
||||
}
|
||||
|
||||
public function testImportingWithControllerDefault()
|
||||
{
|
||||
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/localized')));
|
||||
$routes = $loader->load('importer-with-controller-default.yml');
|
||||
$this->assertCount(3, $routes);
|
||||
$this->assertEquals('DefaultController::defaultAction', $routes->get('home.en')->getDefault('_controller'));
|
||||
$this->assertEquals('DefaultController::defaultAction', $routes->get('home.nl')->getDefault('_controller'));
|
||||
$this->assertEquals('DefaultController::defaultAction', $routes->get('not_localized')->getDefault('_controller'));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user