[Routing] Fix route URL generation in CLI context

This commit is contained in:
Antonio Pauletich 2019-04-08 20:40:53 +02:00 committed by Fabien Potencier
parent c248646e59
commit 4a1ad4a5d6
6 changed files with 141 additions and 7 deletions

View File

@ -71,6 +71,7 @@
<argument type="service" id="router.request_context" on-invalid="ignore" />
<argument type="service" id="parameter_bag" on-invalid="ignore" />
<argument type="service" id="logger" on-invalid="ignore" />
<argument>%kernel.default_locale%</argument>
<call method="setConfigCacheFactory">
<argument type="service" id="config_cache_factory" />
</call>

View File

@ -43,7 +43,7 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI
* @param ContainerInterface|null $parameters A ContainerInterface instance allowing to fetch parameters
* @param LoggerInterface|null $logger
*/
public function __construct(ContainerInterface $container, $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null)
public function __construct(ContainerInterface $container, $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null, string $defaultLocale = null)
{
$this->container = $container;
$this->resource = $resource;
@ -58,6 +58,8 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI
} else {
throw new \LogicException(sprintf('You should either pass a "%s" instance or provide the $parameters argument of the "%s" method.', SymfonyContainerInterface::class, __METHOD__));
}
$this->defaultLocale = $defaultLocale;
}
/**

View File

@ -82,6 +82,32 @@ class RouterTest extends TestCase
$this->assertSame('"bar" == "bar"', $router->getRouteCollection()->get('foo')->getCondition());
}
public function testGenerateWithDefaultLocale()
{
$routes = new RouteCollection();
$route = new Route('');
$name = 'testFoo';
foreach (['hr' => '/test-hr', 'en' => '/test-en'] as $locale => $path) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($path);
$routes->add($name.'.'.$locale, $localizedRoute);
}
$sc = $this->getServiceContainer($routes);
$router = new Router($sc, '', [], null, null, null, 'hr');
$this->assertSame('/test-hr', $router->generate($name));
$this->assertSame('/test-en', $router->generate($name, ['_locale' => 'en']));
$this->assertSame('/test-hr', $router->generate($name, ['_locale' => 'hr']));
}
public function testDefaultsPlaceholders()
{
$routes = new RouteCollection();

View File

@ -28,7 +28,7 @@
"symfony/polyfill-mbstring": "~1.0",
"symfony/filesystem": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
"symfony/routing": "^4.1"
"symfony/routing": "^4.2.6"
},
"require-dev": {
"doctrine/cache": "~1.0",

View File

@ -73,6 +73,11 @@ class Router implements RouterInterface, RequestMatcherInterface
*/
protected $logger;
/**
* @var string|null
*/
protected $defaultLocale;
/**
* @var ConfigCacheFactoryInterface|null
*/
@ -90,13 +95,14 @@ class Router implements RouterInterface, RequestMatcherInterface
* @param RequestContext $context The context
* @param LoggerInterface $logger A logger instance
*/
public function __construct(LoaderInterface $loader, $resource, array $options = [], RequestContext $context = null, LoggerInterface $logger = null)
public function __construct(LoaderInterface $loader, $resource, array $options = [], RequestContext $context = null, LoggerInterface $logger = null, string $defaultLocale = null)
{
$this->loader = $loader;
$this->resource = $resource;
$this->logger = $logger;
$this->context = $context ?: new RequestContext();
$this->setOptions($options);
$this->defaultLocale = $defaultLocale;
}
/**
@ -321,7 +327,7 @@ class Router implements RouterInterface, RequestMatcherInterface
}
if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger, $this->defaultLocale);
} else {
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
function (ConfigCacheInterface $cache) {
@ -340,7 +346,7 @@ class Router implements RouterInterface, RequestMatcherInterface
require_once $cache->getPath();
}
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger, $this->defaultLocale);
}
if ($this->generator instanceof ConfigurableRequirementsInterface) {

View File

@ -162,6 +162,82 @@ class UrlGeneratorTest extends TestCase
$this->assertSame('/app.php/de', $url);
}
public function testGenerateWithDefaultLocale()
{
$routes = new RouteCollection();
$route = new Route('');
$name = 'test';
foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($path);
$routes->add($name.'.'.$locale, $localizedRoute);
}
$generator = $this->getGenerator($routes, [], null, 'hr');
$this->assertSame(
'http://localhost/app.php/foo',
$generator->generate($name, [], UrlGeneratorInterface::ABSOLUTE_URL)
);
}
public function testGenerateWithOverriddenParameterLocale()
{
$routes = new RouteCollection();
$route = new Route('');
$name = 'test';
foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($path);
$routes->add($name.'.'.$locale, $localizedRoute);
}
$generator = $this->getGenerator($routes, [], null, 'hr');
$this->assertSame(
'http://localhost/app.php/bar',
$generator->generate($name, ['_locale' => 'en'], UrlGeneratorInterface::ABSOLUTE_URL)
);
}
public function testGenerateWithOverriddenParameterLocaleFromRequestContext()
{
$routes = new RouteCollection();
$route = new Route('');
$name = 'test';
foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($path);
$routes->add($name.'.'.$locale, $localizedRoute);
}
$generator = $this->getGenerator($routes, [], null, 'hr');
$context = new RequestContext('/app.php');
$context->setParameter('_locale', 'en');
$generator->setContext($context);
$this->assertSame(
'http://localhost/app.php/bar',
$generator->generate($name, [], UrlGeneratorInterface::ABSOLUTE_URL)
);
}
/**
* @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
*/
@ -171,6 +247,29 @@ class UrlGeneratorTest extends TestCase
$this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);
}
/**
* @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
*/
public function testGenerateWithInvalidLocale()
{
$routes = new RouteCollection();
$route = new Route('');
$name = 'test';
foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($path);
$routes->add($name.'.'.$locale, $localizedRoute);
}
$generator = $this->getGenerator($routes, [], null, 'fr');
$generator->generate($name);
}
/**
* @expectedException \Symfony\Component\Routing\Exception\MissingMandatoryParametersException
*/
@ -720,7 +819,7 @@ class UrlGeneratorTest extends TestCase
yield ['/app.php/bar/a/b/bam/c/d/e', '/bar/{foo}/bam/{baz}', '(?<!^).+'];
}
protected function getGenerator(RouteCollection $routes, array $parameters = [], $logger = null)
protected function getGenerator(RouteCollection $routes, array $parameters = [], $logger = null, string $defaultLocale = null)
{
$context = new RequestContext('/app.php');
foreach ($parameters as $key => $value) {
@ -728,7 +827,7 @@ class UrlGeneratorTest extends TestCase
$context->$method($value);
}
return new UrlGenerator($routes, $context, $logger);
return new UrlGenerator($routes, $context, $logger, $defaultLocale);
}
protected function getRoutes($name, Route $route)