diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php index 7e6f4e5c2ff8..b56473be737b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php @@ -49,7 +49,7 @@ public function warmUp($cacheDir) return; } - @trigger_error(sprintf('Passing a %s without implementing %s is deprecated since Symfony 4.1.', RouterInterface::class, WarmableInterface::class), \E_USER_DEPRECATED); + throw new \LogicException(sprintf('The router %s cannot be warmed up because it does not implement %s.', \get_class($router), WarmableInterface::class)); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 9fcc111b0667..995b1ca9f4ee 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -21,7 +21,6 @@ use Symfony\Bridge\Twig\Extension\CsrfExtension; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader; -use Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher; use Symfony\Bundle\FullStack; use Symfony\Component\Asset\PackageInterface; use Symfony\Component\BrowserKit\AbstractBrowser; @@ -88,12 +87,8 @@ use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface; use Symfony\Component\PropertyInfo\PropertyListExtractorInterface; use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; -use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; -use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader; use Symfony\Component\Routing\Loader\AnnotationFileLoader; -use Symfony\Component\Routing\Matcher\CompiledUrlMatcher; -use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; use Symfony\Component\Serializer\Encoder\DecoderInterface; @@ -789,19 +784,12 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co } $container->setParameter('router.resource', $config['resource']); - $container->setParameter('router.cache_class_prefix', $container->getParameter('kernel.container_class')); // deprecated $router = $container->findDefinition('router.default'); $argument = $router->getArgument(2); $argument['strict_requirements'] = $config['strict_requirements']; if (isset($config['type'])) { $argument['resource_type'] = $config['type']; } - if (!class_exists(CompiledUrlMatcher::class)) { - $argument['matcher_class'] = $argument['matcher_base_class'] = $argument['matcher_base_class'] ?? RedirectableUrlMatcher::class; - $argument['matcher_dumper_class'] = PhpMatcherDumper::class; - $argument['generator_class'] = $argument['generator_base_class'] = $argument['generator_base_class'] ?? UrlGenerator::class; - $argument['generator_dumper_class'] = PhpGeneratorDumper::class; - } $router->replaceArgument(2, $argument); $container->setParameter('request_listener.http_port', $config['http_port']); diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php b/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php deleted file mode 100644 index 13ad12dccf86..000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Routing; - -@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3.', RedirectableUrlMatcher::class), E_USER_DEPRECATED); - -use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher; - -/** - * @author Fabien Potencier - * - * @deprecated since Symfony 4.3 - */ -class RedirectableUrlMatcher extends BaseMatcher -{ - /** - * Redirects the user to another URL. - * - * @param string $path The path info to redirect to - * @param string $route The route that matched - * @param string $scheme The URL scheme (null to keep the current one) - * - * @return array An array of parameters - */ - public function redirect($path, $route, $scheme = null) - { - return [ - '_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction', - 'path' => $path, - 'permanent' => true, - 'scheme' => $scheme, - 'httpPort' => $this->context->getHttpPort(), - 'httpsPort' => $this->context->getHttpsPort(), - '_route' => $route, - ]; - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/RouterCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/RouterCacheWarmerTest.php index 93dbd1a69e22..43e8a8123bd4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/RouterCacheWarmerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/RouterCacheWarmerTest.php @@ -32,10 +32,6 @@ public function testWarmUpWithWarmebleInterface() $this->addToAssertionCount(1); } - /** - * @expectedDeprecation Passing a Symfony\Component\Routing\RouterInterface without implementing Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface is deprecated since Symfony 4.1. - * @group legacy - */ public function testWarmUpWithoutWarmebleInterface() { $containerMock = $this->getMockBuilder(ContainerInterface::class)->setMethods(['get', 'has'])->getMock(); @@ -43,6 +39,8 @@ public function testWarmUpWithoutWarmebleInterface() $routerMock = $this->getMockBuilder(testRouterInterfaceWithoutWarmebleInterface::class)->setMethods(['match', 'generate', 'getContext', 'setContext', 'getRouteCollection'])->getMock(); $containerMock->expects($this->any())->method('get')->with('router')->willReturn($routerMock); $routerCacheWarmer = new RouterCacheWarmer($containerMock); + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('cannot be warmed up because it does not implement Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface'); $routerCacheWarmer->warmUp('/tmp'); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php deleted file mode 100644 index 1c11cf9e0902..000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Tests\Routing; - -use PHPUnit\Framework\TestCase; -use Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouteCollection; - -/** - * @group legacy - */ -class RedirectableUrlMatcherTest extends TestCase -{ - public function testRedirectWhenNoSlash() - { - $coll = new RouteCollection(); - $coll->add('foo', new Route('/foo/')); - - $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); - - $this->assertEquals([ - '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', - 'path' => '/foo/', - 'permanent' => true, - 'scheme' => null, - 'httpPort' => $context->getHttpPort(), - 'httpsPort' => $context->getHttpsPort(), - '_route' => 'foo', - ], - $matcher->match('/foo') - ); - } - - public function testSchemeRedirect() - { - $coll = new RouteCollection(); - $coll->add('foo', new Route('/foo', [], [], [], '', ['https'])); - - $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); - - $this->assertEquals([ - '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', - 'path' => '/foo', - 'permanent' => true, - 'scheme' => 'https', - 'httpPort' => $context->getHttpPort(), - 'httpsPort' => $context->getHttpsPort(), - '_route' => 'foo', - ], - $matcher->match('/foo') - ); - } -} diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md index 05ae44b5f110..082f6a94bf84 100644 --- a/src/Symfony/Component/Routing/CHANGELOG.md +++ b/src/Symfony/Component/Routing/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +5.0.0 +----- + + * removed `PhpGeneratorDumper` and `PhpMatcherDumper` + * removed `generator_base_class`, `generator_cache_class`, `matcher_base_class` and `matcher_cache_class` router options + * `Serializable` implementing methods for `Route` and `CompiledRoute` are final + * removed referencing service route loaders with a single colon + 4.3.0 ----- diff --git a/src/Symfony/Component/Routing/CompiledRoute.php b/src/Symfony/Component/Routing/CompiledRoute.php index 87278e702a89..d46a4de632b3 100644 --- a/src/Symfony/Component/Routing/CompiledRoute.php +++ b/src/Symfony/Component/Routing/CompiledRoute.php @@ -64,10 +64,9 @@ public function __serialize(): array } /** - * @internal since Symfony 4.3 - * @final since Symfony 4.3 + * @internal */ - public function serialize() + final public function serialize() { return serialize($this->__serialize()); } @@ -85,10 +84,9 @@ public function __unserialize(array $data): void } /** - * @internal since Symfony 4.3 - * @final since Symfony 4.3 + * @internal */ - public function unserialize($serialized) + final public function unserialize($serialized) { $this->__unserialize(unserialize($serialized, ['allowed_classes' => false])); } diff --git a/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php b/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php deleted file mode 100644 index 3869ffda4eeb..000000000000 --- a/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php +++ /dev/null @@ -1,140 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Generator\Dumper; - -@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "CompiledUrlGeneratorDumper" instead.', PhpGeneratorDumper::class), E_USER_DEPRECATED); - -use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper; - -/** - * PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes. - * - * @author Fabien Potencier - * @author Tobias Schultze - * - * @deprecated since Symfony 4.3, use CompiledUrlGeneratorDumper instead. - */ -class PhpGeneratorDumper extends GeneratorDumper -{ - /** - * Dumps a set of routes to a PHP class. - * - * Available options: - * - * * class: The class name - * * base_class: The base class name - * - * @param array $options An array of options - * - * @return string A PHP class representing the generator class - */ - public function dump(array $options = []) - { - $options = array_merge([ - 'class' => 'ProjectUrlGenerator', - 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', - ], $options); - - return <<context = \$context; - \$this->logger = \$logger; - \$this->defaultLocale = \$defaultLocale; - if (null === self::\$declaredRoutes) { - self::\$declaredRoutes = {$this->generateDeclaredRoutes()}; - } - } - -{$this->generateGenerateMethod()} -} - -EOF; - } - - /** - * Generates PHP code representing an array of defined routes - * together with the routes properties (e.g. requirements). - * - * @return string PHP code - */ - private function generateDeclaredRoutes() - { - $routes = "[\n"; - foreach ($this->getRoutes()->all() as $name => $route) { - $compiledRoute = $route->compile(); - - $properties = []; - $properties[] = $compiledRoute->getVariables(); - $properties[] = $route->getDefaults(); - $properties[] = $route->getRequirements(); - $properties[] = $compiledRoute->getTokens(); - $properties[] = $compiledRoute->getHostTokens(); - $properties[] = $route->getSchemes(); - - $routes .= sprintf(" '%s' => %s,\n", $name, CompiledUrlMatcherDumper::export($properties)); - } - $routes .= ' ]'; - - return $routes; - } - - /** - * Generates PHP code representing the `generate` method that implements the UrlGeneratorInterface. - * - * @return string PHP code - */ - private function generateGenerateMethod() - { - return <<<'EOF' - public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) - { - $locale = $parameters['_locale'] - ?? $this->context->getParameter('_locale') - ?: $this->defaultLocale; - - if (null !== $locale && null !== $name) { - do { - if ((self::$declaredRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) { - unset($parameters['_locale']); - $name .= '.'.$locale; - break; - } - } while (false !== $locale = strstr($locale, '_', true)); - } - - if (!isset(self::$declaredRoutes[$name])) { - throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name)); - } - - list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = self::$declaredRoutes[$name]; - - return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes); - } -EOF; - } -} diff --git a/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php b/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php index 8f0680f02aa5..2486536b25a6 100644 --- a/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php +++ b/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php @@ -48,11 +48,6 @@ public function load($resource, $type = null) throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the "service" route loader: use the format "service::method" or "service" if your service has an "__invoke" method.', $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); $serviceString = $parts[0]; $method = $parts[1] ?? '__invoke'; diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php deleted file mode 100644 index 2177180f4d5c..000000000000 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Matcher\Dumper; - -@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2, use "CompiledUrlMatcherDumper" instead.', PhpMatcherDumper::class), E_USER_DEPRECATED); - -/** - * PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes. - * - * @author Fabien Potencier - * @author Tobias Schultze - * @author Arnaud Le Blanc - * @author Nicolas Grekas - * - * @deprecated since Symfony 4.2, use CompiledUrlMatcherDumper instead. - */ -class PhpMatcherDumper extends CompiledUrlMatcherDumper -{ - /** - * Dumps a set of routes to a PHP class. - * - * Available options: - * - * * class: The class name - * * base_class: The base class name - * - * @param array $options An array of options - * - * @return string A PHP class representing the matcher class - */ - public function dump(array $options = []) - { - $options = array_replace([ - 'class' => 'ProjectUrlMatcher', - 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', - ], $options); - - $code = parent::dump(); - $code = preg_replace('#\n ([^ ].*?) // \$(\w++)$#m', "\n \$this->$2 = $1", $code); - $code = str_replace(",\n $", ";\n $", $code); - $code = substr($code, strpos($code, '$this') - 4, -5).";\n"; - $code = preg_replace('/^ \$this->\w++ = (?:null|false|\[\n \]);\n/m', '', $code); - $code = str_replace("\n ", "\n ", "\n".$code); - - return <<context = \$context;{$code} } -} - -EOF; - } -} diff --git a/src/Symfony/Component/Routing/Route.php b/src/Symfony/Component/Routing/Route.php index 90d8e617c4e9..8fc95410d0ce 100644 --- a/src/Symfony/Component/Routing/Route.php +++ b/src/Symfony/Component/Routing/Route.php @@ -78,10 +78,9 @@ public function __serialize(): array } /** - * @internal since Symfony 4.3 - * @final since Symfony 4.3 + * @internal */ - public function serialize() + final public function serialize() { return serialize($this->__serialize()); } @@ -105,10 +104,9 @@ public function __unserialize(array $data): void } /** - * @internal since Symfony 4.3 - * @final since Symfony 4.3 + * @internal */ - public function unserialize($serialized) + final public function unserialize($serialized) { $this->__unserialize(unserialize($serialized)); } diff --git a/src/Symfony/Component/Routing/Router.php b/src/Symfony/Component/Routing/Router.php index 91cc4e590eec..63c802d03e0d 100644 --- a/src/Symfony/Component/Routing/Router.php +++ b/src/Symfony/Component/Routing/Router.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Routing; use Psr\Log\LoggerInterface; -use Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher; use Symfony\Component\Config\ConfigCacheFactory; use Symfony\Component\Config\ConfigCacheFactoryInterface; use Symfony\Component\Config\ConfigCacheInterface; @@ -23,13 +22,11 @@ use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface; use Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper; use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface; -use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Matcher\CompiledUrlMatcher; use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper; use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; -use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; /** @@ -137,13 +134,9 @@ public function setOptions(array $options) 'cache_dir' => null, 'debug' => false, 'generator_class' => CompiledUrlGenerator::class, - 'generator_base_class' => UrlGenerator::class, // deprecated 'generator_dumper_class' => CompiledUrlGeneratorDumper::class, - 'generator_cache_class' => 'UrlGenerator', // deprecated 'matcher_class' => CompiledUrlMatcher::class, - 'matcher_base_class' => UrlMatcher::class, // deprecated 'matcher_dumper_class' => CompiledUrlMatcherDumper::class, - 'matcher_cache_class' => 'UrlMatcher', // deprecated 'resource_type' => null, 'strict_requirements' => true, ]; @@ -151,7 +144,6 @@ public function setOptions(array $options) // check option names and live merge, if errors are encountered Exception will be thrown $invalid = []; foreach ($options as $key => $value) { - $this->checkDeprecatedOption($key); if (\array_key_exists($key, $this->options)) { $this->options[$key] = $value; } else { @@ -178,8 +170,6 @@ public function setOption($key, $value) throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); } - $this->checkDeprecatedOption($key); - $this->options[$key] = $value; } @@ -198,8 +188,6 @@ public function getOption($key) throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); } - $this->checkDeprecatedOption($key); - return $this->options[$key]; } @@ -287,10 +275,9 @@ public function getMatcher() return $this->matcher; } - $compiled = is_a($this->options['matcher_class'], CompiledUrlMatcher::class, true) && (UrlMatcher::class === $this->options['matcher_base_class'] || RedirectableUrlMatcher::class === $this->options['matcher_base_class']); - - if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) { + if (null === $this->options['cache_dir']) { $routes = $this->getRouteCollection(); + $compiled = is_a($this->options['matcher_class'], CompiledUrlMatcher::class, true); if ($compiled) { $routes = (new CompiledUrlMatcherDumper($routes))->getCompiledRoutes(); } @@ -304,7 +291,7 @@ public function getMatcher() return $this->matcher; } - $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['matcher_cache_class'].'.php', + $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/url_matching_routes.php', function (ConfigCacheInterface $cache) { $dumper = $this->getMatcherDumperInstance(); if (method_exists($dumper, 'addExpressionLanguageProvider')) { @@ -313,24 +300,11 @@ function (ConfigCacheInterface $cache) { } } - $options = [ - 'class' => $this->options['matcher_cache_class'], - 'base_class' => $this->options['matcher_base_class'], - ]; - - $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); + $cache->write($dumper->dump(), $this->getRouteCollection()->getResources()); } ); - if ($compiled) { - return $this->matcher = new $this->options['matcher_class'](require $cache->getPath(), $this->context); - } - - if (!class_exists($this->options['matcher_cache_class'], false)) { - require_once $cache->getPath(); - } - - return $this->matcher = new $this->options['matcher_cache_class']($this->context); + return $this->matcher = new $this->options['matcher_class'](require $cache->getPath(), $this->context); } /** @@ -344,37 +318,23 @@ public function getGenerator() return $this->generator; } - $compiled = is_a($this->options['generator_class'], CompiledUrlGenerator::class, true) && UrlGenerator::class === $this->options['generator_base_class']; - - if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) { + if (null === $this->options['cache_dir']) { $routes = $this->getRouteCollection(); + $compiled = is_a($this->options['generator_class'], CompiledUrlGenerator::class, true); if ($compiled) { $routes = (new CompiledUrlGeneratorDumper($routes))->getCompiledRoutes(); } $this->generator = new $this->options['generator_class']($routes, $this->context, $this->logger, $this->defaultLocale); } else { - $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php', + $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/url_generating_routes.php', function (ConfigCacheInterface $cache) { $dumper = $this->getGeneratorDumperInstance(); - $options = [ - 'class' => $this->options['generator_cache_class'], - 'base_class' => $this->options['generator_base_class'], - ]; - - $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); + $cache->write($dumper->dump(), $this->getRouteCollection()->getResources()); } ); - if ($compiled) { - $this->generator = new $this->options['generator_class'](require $cache->getPath(), $this->context, $this->logger); - } else { - if (!class_exists($this->options['generator_cache_class'], false)) { - require_once $cache->getPath(); - } - - $this->generator = new $this->options['generator_cache_class']($this->context, $this->logger, $this->defaultLocale); - } + $this->generator = new $this->options['generator_class'](require $cache->getPath(), $this->context, $this->logger); } if ($this->generator instanceof ConfigurableRequirementsInterface) { @@ -419,15 +379,4 @@ private function getConfigCacheFactory() return $this->configCacheFactory; } - - private function checkDeprecatedOption($key) - { - switch ($key) { - case 'generator_base_class': - case 'generator_cache_class': - case 'matcher_base_class': - case 'matcher_cache_class': - @trigger_error(sprintf('Option "%s" given to router %s is deprecated since Symfony 4.3.', $key, static::class), E_USER_DEPRECATED); - } - } } diff --git a/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php b/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php deleted file mode 100644 index 0dcf2e863538..000000000000 --- a/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php +++ /dev/null @@ -1,259 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Tests\Generator\Dumper; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouteCollection; - -/** - * @group legacy - */ -class PhpGeneratorDumperTest extends TestCase -{ - /** - * @var RouteCollection - */ - private $routeCollection; - - /** - * @var PhpGeneratorDumper - */ - private $generatorDumper; - - /** - * @var string - */ - private $testTmpFilepath; - - /** - * @var string - */ - private $largeTestTmpFilepath; - - protected function setUp() - { - parent::setUp(); - - $this->routeCollection = new RouteCollection(); - $this->generatorDumper = new PhpGeneratorDumper($this->routeCollection); - $this->testTmpFilepath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.php'; - $this->largeTestTmpFilepath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.large.php'; - @unlink($this->testTmpFilepath); - @unlink($this->largeTestTmpFilepath); - } - - protected function tearDown() - { - parent::tearDown(); - - @unlink($this->testTmpFilepath); - - $this->routeCollection = null; - $this->generatorDumper = null; - $this->testTmpFilepath = null; - } - - public function testDumpWithRoutes() - { - $this->routeCollection->add('Test', new Route('/testing/{foo}')); - $this->routeCollection->add('Test2', new Route('/testing2')); - - file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump()); - include $this->testTmpFilepath; - - $projectUrlGenerator = new \ProjectUrlGenerator(new RequestContext('/app.php')); - - $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL); - $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_URL); - $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH); - $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_PATH); - - $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter); - $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter); - $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter); - $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter); - } - - public function testDumpWithSimpleLocalizedRoutes() - { - $this->routeCollection->add('test', (new Route('/foo'))); - $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test')); - $this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl')->setDefault('_canonical_route', 'test')); - - $code = $this->generatorDumper->dump([ - 'class' => 'SimpleLocalizedProjectUrlGenerator', - ]); - file_put_contents($this->testTmpFilepath, $code); - include $this->testTmpFilepath; - - $context = new RequestContext('/app.php'); - $projectUrlGenerator = new \SimpleLocalizedProjectUrlGenerator($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); - - // test with full route name - $this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test.en')); - - $context->setParameter('_locale', 'de_DE'); - // test that it fall backs to another route when there is no matching localized route - $this->assertEquals('/app.php/foo', $projectUrlGenerator->generate('test')); - } - - /** - * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException - * @expectedExceptionMessage Unable to generate a URL for the named route "test" as such route does not exist. - */ - public function testDumpWithRouteNotFoundLocalizedRoutes() - { - $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test')); - - $code = $this->generatorDumper->dump([ - 'class' => 'RouteNotFoundLocalizedProjectUrlGenerator', - ]); - file_put_contents($this->testTmpFilepath, $code); - include $this->testTmpFilepath; - - $projectUrlGenerator = new \RouteNotFoundLocalizedProjectUrlGenerator(new RequestContext('/app.php'), null, 'pl_PL'); - $projectUrlGenerator->generate('test'); - } - - public function testDumpWithFallbackLocaleLocalizedRoutes() - { - $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_canonical_route', 'test')); - $this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_canonical_route', 'test')); - $this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_canonical_route', 'test')); - - $code = $this->generatorDumper->dump([ - 'class' => 'FallbackLocaleLocalizedProjectUrlGenerator', - ]); - file_put_contents($this->testTmpFilepath, $code); - include $this->testTmpFilepath; - - $context = new RequestContext('/app.php'); - $context->setParameter('_locale', 'en_GB'); - $projectUrlGenerator = new \FallbackLocaleLocalizedProjectUrlGenerator($context, null, null); - - // test with context _locale - $this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test')); - // test with parameters _locale - $this->assertEquals('/app.php/testen/is/leuk', $projectUrlGenerator->generate('test', ['_locale' => 'nl_BE'])); - - $projectUrlGenerator = new \FallbackLocaleLocalizedProjectUrlGenerator(new RequestContext('/app.php'), null, 'fr_CA'); - // test with default locale - $this->assertEquals('/app.php/tester/est/amusant', $projectUrlGenerator->generate('test')); - } - - public function testDumpWithTooManyRoutes() - { - $this->routeCollection->add('Test', new Route('/testing/{foo}')); - for ($i = 0; $i < 32769; ++$i) { - $this->routeCollection->add('route_'.$i, new Route('/route_'.$i)); - } - $this->routeCollection->add('Test2', new Route('/testing2')); - - file_put_contents($this->largeTestTmpFilepath, $this->generatorDumper->dump([ - 'class' => 'ProjectLargeUrlGenerator', - ])); - $this->routeCollection = $this->generatorDumper = null; - include $this->largeTestTmpFilepath; - - $projectUrlGenerator = new \ProjectLargeUrlGenerator(new RequestContext('/app.php')); - - $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL); - $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_URL); - $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH); - $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_PATH); - - $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter); - $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter); - $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter); - $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testDumpWithoutRoutes() - { - file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(['class' => 'WithoutRoutesUrlGenerator'])); - include $this->testTmpFilepath; - - $projectUrlGenerator = new \WithoutRoutesUrlGenerator(new RequestContext('/app.php')); - - $projectUrlGenerator->generate('Test', []); - } - - /** - * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException - */ - public function testGenerateNonExistingRoute() - { - $this->routeCollection->add('Test', new Route('/test')); - - file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(['class' => 'NonExistingRoutesUrlGenerator'])); - include $this->testTmpFilepath; - - $projectUrlGenerator = new \NonExistingRoutesUrlGenerator(new RequestContext()); - $url = $projectUrlGenerator->generate('NonExisting', []); - } - - public function testDumpForRouteWithDefaults() - { - $this->routeCollection->add('Test', new Route('/testing/{foo}', ['foo' => 'bar'])); - - file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(['class' => 'DefaultRoutesUrlGenerator'])); - include $this->testTmpFilepath; - - $projectUrlGenerator = new \DefaultRoutesUrlGenerator(new RequestContext()); - $url = $projectUrlGenerator->generate('Test', []); - - $this->assertEquals('/testing', $url); - } - - public function testDumpWithSchemeRequirement() - { - $this->routeCollection->add('Test1', new Route('/testing', [], [], [], '', ['ftp', 'https'])); - - file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(['class' => 'SchemeUrlGenerator'])); - include $this->testTmpFilepath; - - $projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php')); - - $absoluteUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_URL); - $relativeUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_PATH); - - $this->assertEquals('ftp://localhost/app.php/testing', $absoluteUrl); - $this->assertEquals('ftp://localhost/app.php/testing', $relativeUrl); - - $projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php', 'GET', 'localhost', 'https')); - - $absoluteUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_URL); - $relativeUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_PATH); - - $this->assertEquals('https://localhost/app.php/testing', $absoluteUrl); - $this->assertEquals('/app.php/testing', $relativeUrl); - } -} diff --git a/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php index a286436de5c0..290ec8fd56d0 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php @@ -18,32 +18,6 @@ class ObjectRouteLoaderTest extends TestCase { - /** - * @group legacy - * @expectedDeprecation Referencing service route loaders with a single colon is deprecated since Symfony 4.1. Use my_route_provider_service::loadRoutes instead. - */ - public function testLoadCallsServiceAndReturnsCollectionWithLegacyNotation() - { - $loader = new ObjectRouteLoaderForTest(); - - // create a basic collection that will be returned - $collection = new RouteCollection(); - $collection->add('foo', new Route('/foo')); - - $loader->loaderMap = [ - 'my_route_provider_service' => new RouteService($collection), - ]; - - $actualRoutes = $loader->load( - 'my_route_provider_service:loadRoutes', - 'service' - ); - - $this->assertSame($collection, $actualRoutes); - // the service file should be listed as a resource - $this->assertNotEmpty($actualRoutes->getResources()); - } - public function testLoadCallsServiceAndReturnsCollection() { $loader = new ObjectRouteLoaderForTest(); diff --git a/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php deleted file mode 100644 index aed006f710c0..000000000000 --- a/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Tests\Matcher; - -use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; -use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; -use Symfony\Component\Routing\Matcher\UrlMatcher; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\RouteCollection; - -/** - * @group legacy - */ -class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest -{ - protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) - { - static $i = 0; - - $class = 'DumpedRedirectableUrlMatcher'.++$i; - $dumper = new PhpMatcherDumper($routes); - eval('?>'.$dumper->dump(['class' => $class, 'base_class' => 'Symfony\Component\Routing\Tests\Matcher\TestDumpedRedirectableUrlMatcher'])); - - return $this->getMockBuilder($class) - ->setConstructorArgs([$context ?: new RequestContext()]) - ->setMethods(['redirect']) - ->getMock(); - } -} - -class TestDumpedRedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface -{ - public function redirect($path, $route, $scheme = null) - { - return []; - } -} diff --git a/src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php deleted file mode 100644 index 1766c04d7ed1..000000000000 --- a/src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Tests\Matcher; - -use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\RouteCollection; - -/** - * @group legacy - */ -class DumpedUrlMatcherTest extends UrlMatcherTest -{ - protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) - { - static $i = 0; - - $class = 'DumpedUrlMatcher'.++$i; - $dumper = new PhpMatcherDumper($routes); - eval('?>'.$dumper->dump(['class' => $class])); - - return new $class($context ?: new RequestContext()); - } -} diff --git a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php deleted file mode 100644 index 93d34edbb701..000000000000 --- a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php +++ /dev/null @@ -1,513 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Tests\Matcher\Dumper; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; -use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; -use Symfony\Component\Routing\Matcher\UrlMatcher; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouteCollection; - -/** - * @group legacy - */ -class PhpMatcherDumperTest extends TestCase -{ - /** - * @var string - */ - private $matcherClass; - - /** - * @var string - */ - private $dumpPath; - - protected function setUp() - { - parent::setUp(); - - $this->matcherClass = uniqid('ProjectUrlMatcher'); - $this->dumpPath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_matcher.'.$this->matcherClass.'.php'; - } - - protected function tearDown() - { - parent::tearDown(); - - @unlink($this->dumpPath); - } - - public function testRedirectPreservesUrlEncoding() - { - $collection = new RouteCollection(); - $collection->add('foo', new Route('/foo:bar/')); - - $class = $this->generateDumpedMatcher($collection, true); - - $matcher = $this->getMockBuilder($class) - ->setMethods(['redirect']) - ->setConstructorArgs([new RequestContext()]) - ->getMock(); - - $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/', 'foo')->willReturn([]); - - $matcher->match('/foo%3Abar'); - } - - /** - * @dataProvider getRouteCollections - */ - public function testDump(RouteCollection $collection, $fixture, $options = []) - { - $basePath = __DIR__.'/../../Fixtures/dumper/'; - - $dumper = new PhpMatcherDumper($collection); - $this->assertStringEqualsFile($basePath.$fixture, $dumper->dump($options), '->dump() correctly dumps routes as optimized PHP code.'); - } - - public function getRouteCollections() - { - /* test case 1 */ - - $collection = new RouteCollection(); - - $collection->add('overridden', new Route('/overridden')); - - // defaults and requirements - $collection->add('foo', new Route( - '/foo/{bar}', - ['def' => 'test'], - ['bar' => 'baz|symfony'] - )); - // method requirement - $collection->add('bar', new Route( - '/bar/{foo}', - [], - [], - [], - '', - [], - ['GET', 'head'] - )); - // GET method requirement automatically adds HEAD as valid - $collection->add('barhead', new Route( - '/barhead/{foo}', - [], - [], - [], - '', - [], - ['GET'] - )); - // simple - $collection->add('baz', new Route( - '/test/baz' - )); - // simple with extension - $collection->add('baz2', new Route( - '/test/baz.html' - )); - // trailing slash - $collection->add('baz3', new Route( - '/test/baz3/' - )); - // trailing slash with variable - $collection->add('baz4', new Route( - '/test/{foo}/' - )); - // trailing slash and method - $collection->add('baz5', new Route( - '/test/{foo}/', - [], - [], - [], - '', - [], - ['post'] - )); - // complex name - $collection->add('baz.baz6', new Route( - '/test/{foo}/', - [], - [], - [], - '', - [], - ['put'] - )); - // defaults without variable - $collection->add('foofoo', new Route( - '/foofoo', - ['def' => 'test'] - )); - // pattern with quotes - $collection->add('quoter', new Route( - '/{quoter}', - [], - ['quoter' => '[\']+'] - )); - // space in pattern - $collection->add('space', new Route( - '/spa ce' - )); - - // prefixes - $collection1 = new RouteCollection(); - $collection1->add('overridden', new Route('/overridden1')); - $collection1->add('foo1', (new Route('/{foo}'))->setMethods('PUT')); - $collection1->add('bar1', new Route('/{bar}')); - $collection1->addPrefix('/b\'b'); - $collection2 = new RouteCollection(); - $collection2->addCollection($collection1); - $collection2->add('overridden', new Route('/{var}', [], ['var' => '.*'])); - $collection1 = new RouteCollection(); - $collection1->add('foo2', new Route('/{foo1}')); - $collection1->add('bar2', new Route('/{bar1}')); - $collection1->addPrefix('/b\'b'); - $collection2->addCollection($collection1); - $collection2->addPrefix('/a'); - $collection->addCollection($collection2); - - // overridden through addCollection() and multiple sub-collections with no own prefix - $collection1 = new RouteCollection(); - $collection1->add('overridden2', new Route('/old')); - $collection1->add('helloWorld', new Route('/hello/{who}', ['who' => 'World!'])); - $collection2 = new RouteCollection(); - $collection3 = new RouteCollection(); - $collection3->add('overridden2', new Route('/new')); - $collection3->add('hey', new Route('/hey/')); - $collection2->addCollection($collection3); - $collection1->addCollection($collection2); - $collection1->addPrefix('/multi'); - $collection->addCollection($collection1); - - // "dynamic" prefix - $collection1 = new RouteCollection(); - $collection1->add('foo3', new Route('/{foo}')); - $collection1->add('bar3', new Route('/{bar}')); - $collection1->addPrefix('/b'); - $collection1->addPrefix('{_locale}'); - $collection->addCollection($collection1); - - // route between collections - $collection->add('ababa', new Route('/ababa')); - - // collection with static prefix but only one route - $collection1 = new RouteCollection(); - $collection1->add('foo4', new Route('/{foo}')); - $collection1->addPrefix('/aba'); - $collection->addCollection($collection1); - - // prefix and host - - $collection1 = new RouteCollection(); - - $route1 = new Route('/route1', [], [], [], 'a.example.com'); - $collection1->add('route1', $route1); - - $route2 = new Route('/c2/route2', [], [], [], 'a.example.com'); - $collection1->add('route2', $route2); - - $route3 = new Route('/c2/route3', [], [], [], 'b.example.com'); - $collection1->add('route3', $route3); - - $route4 = new Route('/route4', [], [], [], 'a.example.com'); - $collection1->add('route4', $route4); - - $route5 = new Route('/route5', [], [], [], 'c.example.com'); - $collection1->add('route5', $route5); - - $route6 = new Route('/route6', [], [], [], null); - $collection1->add('route6', $route6); - - $collection->addCollection($collection1); - - // host and variables - - $collection1 = new RouteCollection(); - - $route11 = new Route('/route11', [], [], [], '{var1}.example.com'); - $collection1->add('route11', $route11); - - $route12 = new Route('/route12', ['var1' => 'val'], [], [], '{var1}.example.com'); - $collection1->add('route12', $route12); - - $route13 = new Route('/route13/{name}', [], [], [], '{var1}.example.com'); - $collection1->add('route13', $route13); - - $route14 = new Route('/route14/{name}', ['var1' => 'val'], [], [], '{var1}.example.com'); - $collection1->add('route14', $route14); - - $route15 = new Route('/route15/{name}', [], [], [], 'c.example.com'); - $collection1->add('route15', $route15); - - $route16 = new Route('/route16/{name}', ['var1' => 'val'], [], [], null); - $collection1->add('route16', $route16); - - $route17 = new Route('/route17', [], [], [], null); - $collection1->add('route17', $route17); - - $collection->addCollection($collection1); - - // multiple sub-collections with a single route and a prefix each - $collection1 = new RouteCollection(); - $collection1->add('a', new Route('/a...')); - $collection2 = new RouteCollection(); - $collection2->add('b', new Route('/{var}')); - $collection3 = new RouteCollection(); - $collection3->add('c', new Route('/{var}')); - $collection3->addPrefix('/c'); - $collection2->addCollection($collection3); - $collection2->addPrefix('/b'); - $collection1->addCollection($collection2); - $collection1->addPrefix('/a'); - $collection->addCollection($collection1); - - /* test case 2 */ - - $redirectCollection = clone $collection; - - // force HTTPS redirection - $redirectCollection->add('secure', new Route( - '/secure', - [], - [], - [], - '', - ['https'] - )); - - // force HTTP redirection - $redirectCollection->add('nonsecure', new Route( - '/nonsecure', - [], - [], - [], - '', - ['http'] - )); - - /* test case 3 */ - - $rootprefixCollection = new RouteCollection(); - $rootprefixCollection->add('static', new Route('/test')); - $rootprefixCollection->add('dynamic', new Route('/{var}')); - $rootprefixCollection->addPrefix('rootprefix'); - $route = new Route('/with-condition'); - $route->setCondition('context.getMethod() == "GET"'); - $rootprefixCollection->add('with-condition', $route); - - /* test case 4 */ - $headMatchCasesCollection = new RouteCollection(); - $headMatchCasesCollection->add('just_head', new Route( - '/just_head', - [], - [], - [], - '', - [], - ['HEAD'] - )); - $headMatchCasesCollection->add('head_and_get', new Route( - '/head_and_get', - [], - [], - [], - '', - [], - ['HEAD', 'GET'] - )); - $headMatchCasesCollection->add('get_and_head', new Route( - '/get_and_head', - [], - [], - [], - '', - [], - ['GET', 'HEAD'] - )); - $headMatchCasesCollection->add('post_and_head', new Route( - '/post_and_head', - [], - [], - [], - '', - [], - ['POST', 'HEAD'] - )); - $headMatchCasesCollection->add('put_and_post', new Route( - '/put_and_post', - [], - [], - [], - '', - [], - ['PUT', 'POST'] - )); - $headMatchCasesCollection->add('put_and_get_and_head', new Route( - '/put_and_post', - [], - [], - [], - '', - [], - ['PUT', 'GET', 'HEAD'] - )); - - /* test case 5 */ - $groupOptimisedCollection = new RouteCollection(); - $groupOptimisedCollection->add('a_first', new Route('/a/11')); - $groupOptimisedCollection->add('a_second', new Route('/a/22')); - $groupOptimisedCollection->add('a_third', new Route('/a/333')); - $groupOptimisedCollection->add('a_wildcard', new Route('/{param}')); - $groupOptimisedCollection->add('a_fourth', new Route('/a/44/')); - $groupOptimisedCollection->add('a_fifth', new Route('/a/55/')); - $groupOptimisedCollection->add('a_sixth', new Route('/a/66/')); - $groupOptimisedCollection->add('nested_wildcard', new Route('/nested/{param}')); - $groupOptimisedCollection->add('nested_a', new Route('/nested/group/a/')); - $groupOptimisedCollection->add('nested_b', new Route('/nested/group/b/')); - $groupOptimisedCollection->add('nested_c', new Route('/nested/group/c/')); - - $groupOptimisedCollection->add('slashed_a', new Route('/slashed/group/')); - $groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/')); - $groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/')); - - /* test case 6 & 7 */ - $trailingSlashCollection = new RouteCollection(); - $trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', [], [], [], '', [], [])); - $trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', [], [], [], '', [], ['GET'])); - $trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', [], [], [], '', [], ['HEAD'])); - $trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', [], [], [], '', [], ['POST'])); - $trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', [], [], [], '', [], [])); - $trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', [], [], [], '', [], ['GET'])); - $trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', [], [], [], '', [], ['HEAD'])); - $trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', [], [], [], '', [], ['POST'])); - - $trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', [], [], [], '', [], [])); - $trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', [], [], [], '', [], ['GET'])); - $trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', [], [], [], '', [], ['HEAD'])); - $trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', [], [], [], '', [], ['POST'])); - $trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', [], [], [], '', [], [])); - $trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', [], [], [], '', [], ['GET'])); - $trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', [], [], [], '', [], ['HEAD'])); - $trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', [], [], [], '', [], ['POST'])); - - /* test case 8 */ - $unicodeCollection = new RouteCollection(); - $unicodeCollection->add('a', new Route('/{a}', [], ['a' => 'a'], ['utf8' => false])); - $unicodeCollection->add('b', new Route('/{a}', [], ['a' => '.'], ['utf8' => true])); - $unicodeCollection->add('c', new Route('/{a}', [], ['a' => '.'], ['utf8' => false])); - - /* test case 9 */ - $hostTreeCollection = new RouteCollection(); - $hostTreeCollection->add('a', (new Route('/'))->setHost('{d}.e.c.b.a')); - $hostTreeCollection->add('b', (new Route('/'))->setHost('d.c.b.a')); - $hostTreeCollection->add('c', (new Route('/'))->setHost('{e}.e.c.b.a')); - - /* test case 10 */ - $chunkedCollection = new RouteCollection(); - for ($i = 0; $i < 1000; ++$i) { - $h = substr(md5($i), 0, 6); - $chunkedCollection->add('_'.$i, new Route('/'.$h.'/{a}/{b}/{c}/'.$h)); - } - - /* test case 11 */ - $demoCollection = new RouteCollection(); - $demoCollection->add('a', new Route('/admin/post/')); - $demoCollection->add('b', new Route('/admin/post/new')); - $demoCollection->add('c', (new Route('/admin/post/{id}'))->setRequirements(['id' => '\d+'])); - $demoCollection->add('d', (new Route('/admin/post/{id}/edit'))->setRequirements(['id' => '\d+'])); - $demoCollection->add('e', (new Route('/admin/post/{id}/delete'))->setRequirements(['id' => '\d+'])); - $demoCollection->add('f', new Route('/blog/')); - $demoCollection->add('g', new Route('/blog/rss.xml')); - $demoCollection->add('h', (new Route('/blog/page/{page}'))->setRequirements(['id' => '\d+'])); - $demoCollection->add('i', (new Route('/blog/posts/{page}'))->setRequirements(['id' => '\d+'])); - $demoCollection->add('j', (new Route('/blog/comments/{id}/new'))->setRequirements(['id' => '\d+'])); - $demoCollection->add('k', new Route('/blog/search')); - $demoCollection->add('l', new Route('/login')); - $demoCollection->add('m', new Route('/logout')); - $demoCollection->addPrefix('/{_locale}'); - $demoCollection->add('n', new Route('/{_locale}')); - $demoCollection->addRequirements(['_locale' => 'en|fr']); - $demoCollection->addDefaults(['_locale' => 'en']); - - /* test case 12 */ - $suffixCollection = new RouteCollection(); - $suffixCollection->add('r1', new Route('abc{foo}/1')); - $suffixCollection->add('r2', new Route('abc{foo}/2')); - $suffixCollection->add('r10', new Route('abc{foo}/10')); - $suffixCollection->add('r20', new Route('abc{foo}/20')); - $suffixCollection->add('r100', new Route('abc{foo}/100')); - $suffixCollection->add('r200', new Route('abc{foo}/200')); - - /* test case 13 */ - $hostCollection = new RouteCollection(); - $hostCollection->add('r1', (new Route('abc{foo}'))->setHost('{foo}.exampple.com')); - $hostCollection->add('r2', (new Route('abc{foo}'))->setHost('{foo}.exampple.com')); - - return [ - [new RouteCollection(), 'url_matcher0.php', []], - [$collection, 'url_matcher1.php', []], - [$redirectCollection, 'url_matcher2.php', ['base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher']], - [$rootprefixCollection, 'url_matcher3.php', []], - [$headMatchCasesCollection, 'url_matcher4.php', []], - [$groupOptimisedCollection, 'url_matcher5.php', ['base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher']], - [$trailingSlashCollection, 'url_matcher6.php', []], - [$trailingSlashCollection, 'url_matcher7.php', ['base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher']], - [$unicodeCollection, 'url_matcher8.php', []], - [$hostTreeCollection, 'url_matcher9.php', []], - [$chunkedCollection, 'url_matcher10.php', []], - [$demoCollection, 'url_matcher11.php', ['base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher']], - [$suffixCollection, 'url_matcher12.php', []], - [$hostCollection, 'url_matcher13.php', []], - ]; - } - - private function generateDumpedMatcher(RouteCollection $collection, $redirectableStub = false) - { - $options = ['class' => $this->matcherClass]; - - if ($redirectableStub) { - $options['base_class'] = '\Symfony\Component\Routing\Tests\Matcher\Dumper\RedirectableUrlMatcherStub'; - } - - $dumper = new PhpMatcherDumper($collection); - $code = $dumper->dump($options); - - file_put_contents($this->dumpPath, $code); - include $this->dumpPath; - - return $this->matcherClass; - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Symfony\Component\Routing\Route cannot contain objects - */ - public function testGenerateDumperMatcherWithObject() - { - $routeCollection = new RouteCollection(); - $routeCollection->add('_', new Route('/', [new \stdClass()])); - $dumper = new PhpMatcherDumper($routeCollection); - $dumper->dump(); - } -} - -abstract class RedirectableUrlMatcherStub extends UrlMatcher implements RedirectableUrlMatcherInterface -{ - public function redirect($path, $route, $scheme = null) - { - } -}