Skip to content
Snippets Groups Projects
Commit f4931ef9 authored by catch's avatar catch
Browse files

Issue #3120301 by alexpott, zestagio, Wim Leers: RoutePreloader: prevent...

Issue #3120301 by alexpott, zestagio, Wim Leers: RoutePreloader: prevent preloading of routes generated by JSON:API

(cherry picked from commit a6ef32e6)
parent 17639ae2
No related branches found
No related tags found
3 merge requests!1445Issue #2920039: Views' User Name exposed group filter validation,!1298Issue #3240993: Let layout builder render inline block translations,!774Issue #3174569: Example node template file name is incorrect
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Route;
/** /**
* Defines a class which preloads non-admin routes. * Defines a class which preloads non-admin routes.
...@@ -99,7 +100,7 @@ public function onRequest(KernelEvent $event) { ...@@ -99,7 +100,7 @@ public function onRequest(KernelEvent $event) {
public function onAlterRoutes(RouteBuildEvent $event) { public function onAlterRoutes(RouteBuildEvent $event) {
$collection = $event->getRouteCollection(); $collection = $event->getRouteCollection();
foreach ($collection->all() as $name => $route) { foreach ($collection->all() as $name => $route) {
if (strpos($route->getPath(), '/admin/') !== 0 && $route->getPath() != '/admin') { if (strpos($route->getPath(), '/admin/') !== 0 && $route->getPath() != '/admin' && static::isGetAndHtmlRoute($route)) {
$this->nonAdminRoutesOnRebuild[] = $name; $this->nonAdminRoutesOnRebuild[] = $name;
} }
} }
...@@ -130,4 +131,21 @@ public static function getSubscribedEvents() { ...@@ -130,4 +131,21 @@ public static function getSubscribedEvents() {
return $events; return $events;
} }
/**
* Determines whether the given route is a GET and HTML route.
*
* @param \Symfony\Component\Routing\Route $route
* The route to analyze.
*
* @return bool
* TRUE if GET is a valid method and HTML is a valid format for this route.
*/
protected static function isGetAndHtmlRoute(Route $route) {
$methods = $route->getMethods() ?: ['GET'];
// If a route has no explicit format, then HTML is valid.
// @see \Drupal\Core\Routing\RequestFormatRouteFilter::getAvailableFormats()
$format = $route->hasRequirement('_format') ? explode('|', $route->getRequirement('_format')) : ['html'];
return in_array('GET', $methods, TRUE) && in_array('html', $format, TRUE);
}
} }
...@@ -108,14 +108,29 @@ public function testOnAlterRoutesWithNonAdminRoutes() { ...@@ -108,14 +108,29 @@ public function testOnAlterRoutesWithNonAdminRoutes() {
$route_collection->add('test', new Route('/admin/foo', ['_controller' => 'Drupal\ExampleController'])); $route_collection->add('test', new Route('/admin/foo', ['_controller' => 'Drupal\ExampleController']));
$route_collection->add('test2', new Route('/bar', ['_controller' => 'Drupal\ExampleController'])); $route_collection->add('test2', new Route('/bar', ['_controller' => 'Drupal\ExampleController']));
// Non content routes, like ajax callbacks should be ignored. // Non content routes, like ajax callbacks should be ignored.
$route_collection->add('test3', new Route('/bar', ['_controller' => 'Drupal\ExampleController'])); $route3 = new Route('/bar', ['_controller' => 'Drupal\ExampleController']);
$route3->setMethods(['POST']);
$route_collection->add('test3', $route3);
// Routes with the option _admin_route set to TRUE will be included.
$route4 = new Route('/bar', ['_controller' => 'Drupal\ExampleController']);
$route4->setOption('_admin_route', TRUE);
$route_collection->add('test4', $route4);
// Non-HTML routes, like api_json routes should be ignored.
$route5 = new Route('/bar', ['_controller' => 'Drupal\ExampleController']);
$route5->setRequirement('_format', 'api_json');
$route_collection->add('test5', $route5);
// Routes which include HTML should be included.
$route6 = new Route('/bar', ['_controller' => 'Drupal\ExampleController']);
$route6->setRequirement('_format', 'json_api|html');
$route_collection->add('test6', $route6);
$event->expects($this->once()) $event->expects($this->once())
->method('getRouteCollection') ->method('getRouteCollection')
->will($this->returnValue($route_collection)); ->will($this->returnValue($route_collection));
$this->state->expects($this->once()) $this->state->expects($this->once())
->method('set') ->method('set')
->with('routing.non_admin_routes', ['test2', 'test3']); ->with('routing.non_admin_routes', ['test2', 'test4', 'test6']);
$this->preloader->onAlterRoutes($event); $this->preloader->onAlterRoutes($event);
$this->preloader->onFinishedRoutes(new Event()); $this->preloader->onFinishedRoutes(new Event());
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment