Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
75.00% |
6 / 8 |
CRAP | |
89.13% |
41 / 46 |
| RouteSubscriber | |
0.00% |
0 / 1 |
|
75.00% |
6 / 8 |
23.68 | |
89.13% |
41 / 46 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| reset | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| getSubscribedEvents | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
| getViewsDisplayIDsWithRoute | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
| routes | |
100.00% |
1 / 1 |
7 | |
100.00% |
11 / 11 |
|||
| alterRoutes | |
100.00% |
1 / 1 |
8 | |
100.00% |
14 / 14 |
|||
| routeRebuildFinished | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| getApplicableViews | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\views\EventSubscriber\RouteSubscriber. | |
| */ | |
| namespace Drupal\views\EventSubscriber; | |
| use Drupal\Core\Entity\EntityManagerInterface; | |
| 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 = array(); | |
| /** | |
| * Constructs a \Drupal\views\EventSubscriber\RouteSubscriber instance. | |
| * | |
| * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager | |
| * The entity manager. | |
| * @param \Drupal\Core\State\StateInterface $state | |
| * The state key value store. | |
| */ | |
| public function __construct(EntityManagerInterface $entity_manager, StateInterface $state) { | |
| $this->viewStorage = $entity_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] = array('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 = array(); | |
| // @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(); | |
| } | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| 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'); | |
| } | |
| } |