class RouteSubscriber

Same name in this branch
  1. 11.x core/modules/media/tests/modules/media_test_embed/src/Routing/RouteSubscriber.php \Drupal\media_test_embed\Routing\RouteSubscriber
  2. 11.x core/modules/config_translation/src/Routing/RouteSubscriber.php \Drupal\config_translation\Routing\RouteSubscriber
  3. 11.x core/modules/media_library/src/Routing/RouteSubscriber.php \Drupal\media_library\Routing\RouteSubscriber
  4. 11.x core/modules/node/src/Routing/RouteSubscriber.php \Drupal\node\Routing\RouteSubscriber
  5. 11.x core/modules/field_ui/src/Routing/RouteSubscriber.php \Drupal\field_ui\Routing\RouteSubscriber
  6. 11.x core/modules/block_content/src/Routing/RouteSubscriber.php \Drupal\block_content\Routing\RouteSubscriber
  7. 11.x core/modules/serialization/tests/modules/user_route_alter_test/src/Routing/RouteSubscriber.php \Drupal\user_route_alter_test\Routing\RouteSubscriber
Same name in other branches
  1. 9 core/modules/media/tests/modules/media_test_embed/src/Routing/RouteSubscriber.php \Drupal\media_test_embed\Routing\RouteSubscriber
  2. 9 core/modules/config_translation/src/Routing/RouteSubscriber.php \Drupal\config_translation\Routing\RouteSubscriber
  3. 9 core/modules/media_library/src/Routing/RouteSubscriber.php \Drupal\media_library\Routing\RouteSubscriber
  4. 9 core/modules/node/src/Routing/RouteSubscriber.php \Drupal\node\Routing\RouteSubscriber
  5. 9 core/modules/views/src/EventSubscriber/RouteSubscriber.php \Drupal\views\EventSubscriber\RouteSubscriber
  6. 9 core/modules/field_ui/src/Routing/RouteSubscriber.php \Drupal\field_ui\Routing\RouteSubscriber
  7. 8.9.x core/modules/media/tests/modules/media_test_ckeditor/src/Routing/RouteSubscriber.php \Drupal\media_test_ckeditor\Routing\RouteSubscriber
  8. 8.9.x core/modules/config_translation/src/Routing/RouteSubscriber.php \Drupal\config_translation\Routing\RouteSubscriber
  9. 8.9.x core/modules/media_library/src/Routing/RouteSubscriber.php \Drupal\media_library\Routing\RouteSubscriber
  10. 8.9.x core/modules/node/src/Routing/RouteSubscriber.php \Drupal\node\Routing\RouteSubscriber
  11. 8.9.x core/modules/views/src/EventSubscriber/RouteSubscriber.php \Drupal\views\EventSubscriber\RouteSubscriber
  12. 8.9.x core/modules/field_ui/src/Routing/RouteSubscriber.php \Drupal\field_ui\Routing\RouteSubscriber
  13. 8.9.x core/modules/path/src/Routing/RouteSubscriber.php \Drupal\path\Routing\RouteSubscriber
  14. 10 core/modules/media/tests/modules/media_test_embed/src/Routing/RouteSubscriber.php \Drupal\media_test_embed\Routing\RouteSubscriber
  15. 10 core/modules/config_translation/src/Routing/RouteSubscriber.php \Drupal\config_translation\Routing\RouteSubscriber
  16. 10 core/modules/media_library/src/Routing/RouteSubscriber.php \Drupal\media_library\Routing\RouteSubscriber
  17. 10 core/modules/node/src/Routing/RouteSubscriber.php \Drupal\node\Routing\RouteSubscriber
  18. 10 core/modules/views/src/EventSubscriber/RouteSubscriber.php \Drupal\views\EventSubscriber\RouteSubscriber
  19. 10 core/modules/field_ui/src/Routing/RouteSubscriber.php \Drupal\field_ui\Routing\RouteSubscriber
  20. 10 core/modules/block_content/src/Routing/RouteSubscriber.php \Drupal\block_content\Routing\RouteSubscriber
  21. 10 core/modules/serialization/tests/modules/user_route_alter_test/src/Routing/RouteSubscriber.php \Drupal\user_route_alter_test\Routing\RouteSubscriber

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.

Hierarchy

  • class \Drupal\Core\Routing\RouteSubscriberBase implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
    • class \Drupal\views\EventSubscriber\RouteSubscriber extends \Drupal\Core\Routing\RouteSubscriberBase

Expanded class hierarchy of RouteSubscriber

See also

\Drupal\views\Plugin\views\display\PathPluginBase

1 file declares its use of RouteSubscriber
RouteSubscriberTest.php in core/modules/views/tests/src/Unit/EventSubscriber/RouteSubscriberTest.php
1 string reference to 'RouteSubscriber'
views.services.yml in core/modules/views/views.services.yml
core/modules/views/views.services.yml
1 service uses RouteSubscriber
views.route_subscriber in core/modules/views/views.services.yml
Drupal\views\EventSubscriber\RouteSubscriber

File

core/modules/views/src/EventSubscriber/RouteSubscriber.php, line 24

Namespace

Drupal\views\EventSubscriber
View source
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() : array {
        $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) {
                [
                    $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) {
            [
                $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) {
            [
                $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');
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
RouteSubscriber::$state protected property The state key value store.
RouteSubscriber::$viewRouteNames protected property Stores an array of route names keyed by view_id.display_id.
RouteSubscriber::$viewsDisplayPairs protected property Stores a list of view,display IDs which haven't be used in the alter event.
RouteSubscriber::$viewStorage protected property The view storage.
RouteSubscriber::alterRoutes protected function Alters existing routes for a specific collection. Overrides RouteSubscriberBase::alterRoutes
RouteSubscriber::getApplicableViews protected function Returns all views/display combinations with routes. 1
RouteSubscriber::getSubscribedEvents public static function Overrides RouteSubscriberBase::getSubscribedEvents
RouteSubscriber::getViewsDisplayIDsWithRoute protected function Gets all the views and display IDs using a route.
RouteSubscriber::reset public function Resets the internal state of the route subscriber.
RouteSubscriber::routeRebuildFinished public function Stores the new route names after they have been rebuilt.
RouteSubscriber::routes public function Returns a set of route objects.
RouteSubscriber::__construct public function Constructs a \Drupal\views\EventSubscriber\RouteSubscriber instance.
RouteSubscriberBase::onAlterRoutes public function Delegates the route altering to self::alterRoutes(). 1

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.