diff --git a/core/core.services.yml b/core/core.services.yml index 20b8651..b333112 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -253,6 +253,11 @@ services: router.route_provider: class: Drupal\Core\Routing\RouteProvider arguments: ['@database'] + router.route_preloader: + class: Drupal\Core\Routing\AdminRoutesPreloader + arguments: ['@router.route_provider', '@state', '@content_negotiation'] + tags: + - { name: 'event_subscriber' } router.matcher.final_matcher: class: Drupal\Core\Routing\UrlMatcher router.matcher: diff --git a/core/lib/Drupal/Core/Routing/AdminRoutesPreloader.php b/core/lib/Drupal/Core/Routing/AdminRoutesPreloader.php new file mode 100644 index 0000000..2edddf4 --- /dev/null +++ b/core/lib/Drupal/Core/Routing/AdminRoutesPreloader.php @@ -0,0 +1,133 @@ +routeProvider = $route_provider; + $this->state = $state; + $this->negotiation = $negotiation; + } + + /** + * Gets the admin routes. + * + * @return array + */ + protected function getAdminRoutes() { + if (!isset($this->adminRoutes)) { + $this->adminRoutes = $this->state->get('routing.admin_routes', array()); + } + return $this->adminRoutes; + } + + /** + * Load all the admin routes right before the actual page is rendered. + * + * @param \Symfony\Component\HttpKernel\Event\KernelEvent $event + * The Event to process. + */ + public function onRequest(KernelEvent $event) { + $this->loadAdminRoutes(); + } + + /** + * Load all the admin routes at once. + */ + protected function loadAdminRoutes() { + if ($routes = $this->getAdminRoutes()) { + $this->routeProvider->getRoutesByNames($routes); + } + } + + /** + * Alters existing routes for a specific collection. + * + * @param \Drupal\Core\Routing\RouteBuildEvent $event + * The route build event. + */ + public function onAlterRoutes(RouteBuildEvent $event) { + $collection = $event->getRouteCollection(); + foreach ($collection->all() as $name => $route) { + // Just preload non admin and _content routes, as they are the ones + // that appear on menu links and co. + if (strpos($route->getPath(), '/admin') !== 0 && $route->hasDefault('_content')) { + $this->adminRoutesOnRebuild[] = $name; + } + } + $this->adminRoutesOnRebuild = array_unique($this->adminRoutesOnRebuild); + $this->state->set('routing.admin_routes', $this->adminRoutesOnRebuild); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::ALTER] = array('onAlterRoutes', -1024); + // Come before the HtmlViewSubscriber. + $events[KernelEvents::REQUEST][] = array('onRequest'); + return $events; + } + +}