Skip to content

Commit

Permalink
[FrameworkBundle] Fix freshness checks with boolean parameters on routes
Browse files Browse the repository at this point in the history
  • Loading branch information
HypeMC authored and nicolas-grekas committed Feb 10, 2021
1 parent 08cf386 commit a6079f7
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
14 changes: 8 additions & 6 deletions Routing/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,16 @@ private function resolve($value)

$resolved = ($this->paramFetcher)($match[1]);

if (\is_bool($resolved)) {
$resolved = (string) (int) $resolved;
}

if (\is_string($resolved) || is_numeric($resolved)) {
if (is_scalar($resolved)) {
$this->collectedParameters[$match[1]] = $resolved;

return (string) $this->resolve($resolved);
if (\is_string($resolved)) {
$resolved = $this->resolve($resolved);
}

if (is_scalar($resolved)) {
return false === $resolved ? '0' : (string) $resolved;
}
}

throw new RuntimeException(sprintf('The container parameter "%s", used in the route configuration value "%s", must be a string or numeric, but it is of type "%s".', $match[1], $value, \gettype($resolved)));
Expand Down
3 changes: 3 additions & 0 deletions Tests/Routing/Fixtures/with_condition.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
foo:
path: /foo
condition: '%parameter.condition%'
50 changes: 50 additions & 0 deletions Tests/Routing/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\ResourceCheckerConfigCache;
use Symfony\Component\Config\ResourceCheckerConfigCacheFactory;
use Symfony\Component\DependencyInjection\Config\ContainerParametersResource;
use Symfony\Component\DependencyInjection\Config\ContainerParametersResourceChecker;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

Expand Down Expand Up @@ -503,6 +508,51 @@ public function getNonStringValues()
return [[null], [false], [true], [new \stdClass()], [['foo', 'bar']], [[[]]]];
}

/**
* @dataProvider getContainerParameterForRoute
*/
public function testCacheValiditiyWithContainerParameters($parameter)
{
$cacheDir = sys_get_temp_dir().\DIRECTORY_SEPARATOR.uniqid('router_', true);

try {
$container = new Container();
$container->set('routing.loader', new YamlFileLoader(new FileLocator(__DIR__.'/Fixtures')));

$container->setParameter('parameter.condition', $parameter);

$router = new Router($container, 'with_condition.yaml', [
'debug' => true,
'cache_dir' => $cacheDir,
]);

$resourceCheckers = [
new ContainerParametersResourceChecker($container),
];

$router->setConfigCacheFactory(new ResourceCheckerConfigCacheFactory($resourceCheckers));

$router->getMatcher(); // trigger cache build

$cache = new ResourceCheckerConfigCache($cacheDir.\DIRECTORY_SEPARATOR.'UrlMatcher.php', $resourceCheckers);

$this->assertTrue($cache->isFresh());
} finally {
if (is_dir($cacheDir)) {
array_map('unlink', glob($cacheDir.\DIRECTORY_SEPARATOR.'*'));
rmdir($cacheDir);
}
}
}

public function getContainerParameterForRoute()
{
yield 'String' => ['"foo"'];
yield 'Integer' => [0];
yield 'Boolean true' => [true];
yield 'Boolean false' => [false];
}

private function getServiceContainer(RouteCollection $routes): Container
{
$loader = $this->createMock(LoaderInterface::class);
Expand Down

0 comments on commit a6079f7

Please sign in to comment.