Mercurial > hg > isophonics-drupal-site
view core/modules/views/src/EventSubscriber/RouteSubscriber.php @ 19:fa3358dc1485 tip
Add ndrum files
author | Chris Cannam |
---|---|
date | Wed, 28 Aug 2019 13:14:47 +0100 |
parents | af1871eacc83 |
children |
line wrap: on
line source
<?php namespace Drupal\views\EventSubscriber; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Routing\RouteSubscriberBase; use Drupal\Core\Routing\RoutingEvents; use Drupal\views\Plugin\views\display\DisplayRouterInterface; use Drupal\views\ViewExecutable; use Drupal\views\Views; use Symfony\Component\Routing\RouteCollection; /** * Builds up the routes of all views. * * The general idea is to execute first all alter hooks to determine which * routes are overridden by views. This information is used to determine which * views have to be added by views in the dynamic event. * * * @see \Drupal\views\Plugin\views\display\PathPluginBase */ class RouteSubscriber extends RouteSubscriberBase { /** * Stores a list of view,display IDs which haven't be used in the alter event. * * @var array */ protected $viewsDisplayPairs; /** * The view storage. * * @var \Drupal\Core\Entity\EntityStorageInterface */ protected $viewStorage; /** * The state key value store. * * @var \Drupal\Core\State\StateInterface */ protected $state; /** * Stores an array of route names keyed by view_id.display_id. * * @var array */ protected $viewRouteNames = []; /** * Constructs a \Drupal\views\EventSubscriber\RouteSubscriber instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. * @param \Drupal\Core\State\StateInterface $state * The state key value store. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, StateInterface $state) { $this->viewStorage = $entity_type_manager->getStorage('view'); $this->state = $state; } /** * Resets the internal state of the route subscriber. */ public function reset() { $this->viewsDisplayPairs = NULL; } /** * {@inheritdoc} */ public static function getSubscribedEvents() { $events = parent::getSubscribedEvents(); $events[RoutingEvents::FINISHED] = ['routeRebuildFinished']; // Ensure to run after the entity resolver subscriber // @see \Drupal\Core\EventSubscriber\EntityRouteAlterSubscriber $events[RoutingEvents::ALTER] = ['onAlterRoutes', -175]; return $events; } /** * Gets all the views and display IDs using a route. */ protected function getViewsDisplayIDsWithRoute() { if (!isset($this->viewsDisplayPairs)) { $this->viewsDisplayPairs = []; // @todo Convert this method to some service. $views = $this->getApplicableViews(); foreach ($views as $data) { list($view_id, $display_id) = $data; $this->viewsDisplayPairs[] = $view_id . '.' . $display_id; } $this->viewsDisplayPairs = array_combine($this->viewsDisplayPairs, $this->viewsDisplayPairs); } return $this->viewsDisplayPairs; } /** * Returns a set of route objects. * * @return \Symfony\Component\Routing\RouteCollection * A route collection. */ public function routes() { $collection = new RouteCollection(); foreach ($this->getViewsDisplayIDsWithRoute() as $pair) { list($view_id, $display_id) = explode('.', $pair); $view = $this->viewStorage->load($view_id); // @todo This should have an executable factory injected. if (($view = $view->getExecutable()) && $view instanceof ViewExecutable) { if ($view->setDisplay($display_id) && $display = $view->displayHandlers->get($display_id)) { if ($display instanceof DisplayRouterInterface) { $this->viewRouteNames += (array) $display->collectRoutes($collection); } } $view->destroy(); } } $this->state->set('views.view_route_names', $this->viewRouteNames); return $collection; } /** * {@inheritdoc} */ protected function alterRoutes(RouteCollection $collection) { foreach ($this->getViewsDisplayIDsWithRoute() as $pair) { list($view_id, $display_id) = explode('.', $pair); $view = $this->viewStorage->load($view_id); // @todo This should have an executable factory injected. if (($view = $view->getExecutable()) && $view instanceof ViewExecutable) { if ($view->setDisplay($display_id) && $display = $view->displayHandlers->get($display_id)) { if ($display instanceof DisplayRouterInterface) { // If the display returns TRUE a route item was found, so it does not // have to be added. $view_route_names = $display->alterRoutes($collection); $this->viewRouteNames = $view_route_names + $this->viewRouteNames; foreach ($view_route_names as $id_display => $route_name) { $view_route_name = $this->viewsDisplayPairs[$id_display]; unset($this->viewsDisplayPairs[$id_display]); $collection->remove("views.$view_route_name"); } } } $view->destroy(); } } } /** * Stores the new route names after they have been rebuilt. * * Callback for the RoutingEvents::FINISHED event. * * @see \Drupal\views\EventSubscriber::getSubscribedEvents() */ public function routeRebuildFinished() { $this->reset(); $this->state->set('views.view_route_names', $this->viewRouteNames); } /** * Returns all views/display combinations with routes. * * @see \Drupal\views\Views::getApplicableViews() */ protected function getApplicableViews() { return Views::getApplicableViews('uses_route'); } }