diff --git a/core/lib/Drupal/Core/Routing/MatcherDumper.php b/core/lib/Drupal/Core/Routing/MatcherDumper.php index f19b0eed8df..5b775e85808 100644 --- a/core/lib/Drupal/Core/Routing/MatcherDumper.php +++ b/core/lib/Drupal/Core/Routing/MatcherDumper.php @@ -117,7 +117,7 @@ class MatcherDumper implements MatcherDumperInterface { $names = []; foreach ($routes as $name => $route) { /** @var \Symfony\Component\Routing\Route $route */ - $route->setOption('compiler_class', '\Drupal\Core\Routing\RouteCompiler'); + $route->setOption('compiler_class', RouteCompiler::class); /** @var \Drupal\Core\Routing\CompiledRoute $compiled */ $compiled = $route->compile(); // The fit value is a binary number which has 1 at every fixed path diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php index c4175ed7c80..16fd0bbcdf8 100644 --- a/core/lib/Drupal/Core/Routing/RouteBuilder.php +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php @@ -168,6 +168,11 @@ class RouteBuilder implements RouteBuilderInterface, DestructableInterface { 'methods' => [], 'condition' => '', ]; + // Ensure routes default to using Drupal's route compiler instead of + // Symfony's. + $route_info['options'] += [ + 'compiler_class' => RouteCompiler::class, + ]; $route = new Route($route_info['path'], $route_info['defaults'], $route_info['requirements'], $route_info['options'], $route_info['host'], $route_info['schemes'], $route_info['methods'], $route_info['condition']); $collection->add($name, $route); diff --git a/core/lib/Drupal/Core/Routing/RouteCompiler.php b/core/lib/Drupal/Core/Routing/RouteCompiler.php index 9c430f6811c..da890c0152f 100644 --- a/core/lib/Drupal/Core/Routing/RouteCompiler.php +++ b/core/lib/Drupal/Core/Routing/RouteCompiler.php @@ -31,7 +31,9 @@ class RouteCompiler extends SymfonyRouteCompiler implements RouteCompilerInterfa * A CompiledRoute instance. */ public static function compile(Route $route) { - + // Symfony 4 requires that all UTF-8 route patterns have the "utf8" option + // set and Drupal does not support non UTF-8 routes. + $route->setOption('utf8', TRUE); $symfony_compiled = parent::compile($route); // The Drupal-specific compiled information. diff --git a/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php b/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php index 4145b2369e7..bf3ca96a163 100644 --- a/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php +++ b/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php @@ -3,6 +3,7 @@ namespace Drupal\KernelTests\Core\Routing; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; +use Drupal\Core\Routing\RouteCompiler; use Drupal\Core\State\State; use Drupal\KernelTests\KernelTestBase; use Symfony\Component\Routing\Route; @@ -115,7 +116,7 @@ class MatcherDumperTest extends KernelTestBase { $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); $route = new Route('/test/{my}/path'); - $route->setOption('compiler_class', 'Drupal\Core\Routing\RouteCompiler'); + $route->setOption('compiler_class', RouteCompiler::class); $collection = new RouteCollection(); $collection->add('test_route', $route); diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php index 974df439d9b..35b3fdb4aa6 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php @@ -11,6 +11,7 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Discovery\YamlDiscovery; use Drupal\Core\Routing\RouteBuilder; use Drupal\Core\Routing\RouteBuildEvent; +use Drupal\Core\Routing\RouteCompiler; use Drupal\Core\Routing\RoutingEvents; use Drupal\Tests\UnitTestCase; use Symfony\Component\Routing\Route; @@ -152,6 +153,9 @@ class RouteBuilderTest extends UnitTestCase { ->will($this->returnValue(['test_module' => $routes])); $route_collection = $routing_fixtures->sampleRouteCollection(); + foreach ($route_collection->all() as $route) { + $route->setOption('compiler_class', RouteCompiler::class); + } $route_build_event = new RouteBuildEvent($route_collection); // Ensure that the alter routes events are fired. @@ -274,6 +278,47 @@ class RouteBuilderTest extends UnitTestCase { $this->assertFalse($this->routeBuilder->rebuildIfNeeded()); } + /** + * Tests routes can use alternative compiler classes. + * + * @see \Drupal\Core\Routing\RouteBuilder::rebuild() + */ + public function testRebuildWithOverriddenRouteClass() { + $this->lock->expects($this->once()) + ->method('acquire') + ->with('router_rebuild') + ->will($this->returnValue(TRUE)); + $this->yamlDiscovery->expects($this->once()) + ->method('findAll') + ->will($this->returnValue([ + 'test_module' => [ + 'test_route.override' => [ + 'path' => '/test_route_override', + 'options' => [ + 'compiler_class' => 'Class\Does\Not\Exist', + ], + ], + 'test_route' => [ + 'path' => '/test_route', + ], + ], + ])); + + $container = new ContainerBuilder(); + $container->set('test_module.route_service', new TestRouteSubscriber()); + + // Test that routes can have alternative compiler classes. + $route_collection_filled = new RouteCollection(); + $route_collection_filled->add('test_route.override', new Route('/test_route_override', [], [], ['compiler_class' => 'Class\Does\Not\Exist'])); + $route_collection_filled->add('test_route', new Route('/test_route', [], [], ['compiler_class' => RouteCompiler::class])); + $route_build_event = new RouteBuildEvent($route_collection_filled); + $this->dispatcher->expects($this->at(0)) + ->method('dispatch') + ->with(RoutingEvents::DYNAMIC, $route_build_event); + + $this->assertTrue($this->routeBuilder->rebuild()); + } + } /** diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php index 2ddfdcaedee..0bce9a33699 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php @@ -54,7 +54,7 @@ class RouteCompilerTest extends UnitTestCase { */ public function testCompilation() { $route = new Route('/test/{something}/more'); - $route->setOption('compiler_class', 'Drupal\Core\Routing\RouteCompiler'); + $route->setOption('compiler_class', RouteCompiler::class); $compiled = $route->compile(); $this->assertEquals($compiled->getFit(), 5 /* That's 101 binary*/, 'The fit was incorrect.'); @@ -70,7 +70,7 @@ class RouteCompilerTest extends UnitTestCase { $route = new Route('/test/{something}/more/{here}', [ 'here' => 'there', ]); - $route->setOption('compiler_class', 'Drupal\Core\Routing\RouteCompiler'); + $route->setOption('compiler_class', RouteCompiler::class); $compiled = $route->compile(); $this->assertEquals($compiled->getFit(), 5 /* That's 101 binary*/, 'The fit was not correct.'); diff --git a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php index 62922fa220e..348373035a3 100644 --- a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php +++ b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php @@ -114,10 +114,6 @@ trait DeprecationListenerTrait { 'The "plugin.manager.migrate.cckfield" service is deprecated. You should use the \'plugin.manager.migrate.field\' service instead. See https://www.drupal.org/node/2751897', 'Drupal\system\Tests\Update\DbUpdatesTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\FunctionalTests\Update\DbUpdatesTrait instead. See https://www.drupal.org/node/2896640.', 'Providing settings under \'handler_settings\' is deprecated and will be removed before 9.0.0. Move the settings in the root of the configuration array. See https://www.drupal.org/node/2870971.', - 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/system-test/Ȅchȏ/meφΩ/{text}".', - 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/somewhere/{item}/over/the/קainbow".', - 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/place/meφω".', - 'Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "/PLACE/meφω".', 'The Drupal\editor\Plugin\EditorBase::settingsFormValidate method is deprecated since version 8.3.x and will be removed in 9.0.0.', 'The Drupal\migrate\Plugin\migrate\process\Migration is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use Drupal\migrate\Plugin\migrate\process\MigrationLookup', 'Drupal\system\Plugin\views\field\BulkForm is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\views\Plugin\views\field\BulkForm instead. See https://www.drupal.org/node/2916716.',