diff --git a/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php b/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php index 0ff9d42..ccc5d5f 100644 --- a/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php +++ b/core/modules/views/lib/Drupal/views/EventSubscriber/RouteSubscriber.php @@ -7,7 +7,9 @@ namespace Drupal\views\EventSubscriber; +use Drupal\Core\DestructableInterface; use Drupal\Core\Entity\EntityManager; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\Routing\RouteBuildEvent; use Drupal\Core\Routing\RoutingEvents; use Drupal\views\Plugin\views\display\DisplayRouterInterface; @@ -21,7 +23,7 @@ * * @see \Drupal\views\Plugin\views\display\PathPluginBase */ -class RouteSubscriber implements EventSubscriberInterface { +class RouteSubscriber implements EventSubscriberInterface, DestructableInterface { /** * Stores a list of view,display IDs containing routes and still has to be @@ -39,13 +41,30 @@ class RouteSubscriber implements EventSubscriberInterface { protected $viewStorageController; /** + * The state key value store. + * + * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface + */ + 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\EntityManager $entity_manager * The entity manager. + * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state + * The state key value store. */ - public function __construct(EntityManager $entity_manager) { + public function __construct(EntityManager $entity_manager, KeyValueStoreInterface $state) { $this->viewStorageController = $entity_manager->getStorageController('view'); + $this->state = $state; } /** @@ -98,7 +117,9 @@ public function dynamicRoutes(RouteBuildEvent $event) { if (($view = $view->getExecutable()) && $view instanceof ViewExecutable) { if ($view->setDisplay($display_id) && $display = $view->displayHandlers->get($display_id)) { if ($display instanceof DisplayRouterInterface) { - $display->collectRoutes($collection); + $view_route_names = (array) $display->collectRoutes($collection); + + $this->viewRouteNames += $view_route_names; } } $view->destroy(); @@ -122,8 +143,9 @@ public function alterRoutes(RouteBuildEvent $event) { if ($display instanceof DisplayRouterInterface) { // If the display returns TRUE a route item was found, so it does not // have to be added. - $result = $display->alterRoutes($event->getRouteCollection()); - foreach ($result as $id_display) { + $view_route_names = $display->alterRoutes($event->getRouteCollection()); + $this->viewRouteNames += $view_route_names; + foreach ($view_route_names as $id_display => $route_name) { unset($this->viewsDisplayPairs[$id_display]); } } @@ -134,6 +156,13 @@ public function alterRoutes(RouteBuildEvent $event) { } /** + * {@inheritdoc} + */ + public function destruct() { + $this->state->set('views.view_route_names', $this->viewRouteNames); + } + + /** * Returns all views/display combinations with routes. * * @see views_get_applicable_views() diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php index 7038d29..2b0ff9b 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php @@ -7,6 +7,7 @@ namespace Drupal\views\Plugin\views\display; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\Routing\RouteCompiler; use Drupal\Core\Routing\RouteProviderInterface; use Drupal\views\Views; @@ -32,6 +33,13 @@ protected $routeProvider; /** + * The state key value store. + * + * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface + */ + protected $state; + + /** * Constructs a PathPluginBase object. * * @param array $configuration @@ -42,11 +50,14 @@ * The plugin implementation definition. * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider * The route provider. + * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state + * The state key value store. */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, RouteProviderInterface $route_provider) { + public function __construct(array $configuration, $plugin_id, array $plugin_definition, RouteProviderInterface $route_provider, KeyValueStoreInterface $state) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->routeProvider = $route_provider; + $this->state = $state; } /** @@ -57,7 +68,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('router.route_provider') + $container->get('router.route_provider'), + $container->get('state') ); } @@ -186,13 +198,14 @@ public function collectRoutes(RouteCollection $collection) { $route = $this->getRoute($view_id, $display_id); $collection->add("view.$view_id.$display_id", $route); + return array("$view_id.$display_id" => "view.$view_id.$display_id"); } /** * {@inheritdoc} */ public function alterRoutes(RouteCollection $collection) { - $altered_views = array(); + $view_route_names = array(); $view_path = $this->getPath(); foreach ($collection->all() as $name => $route) { // Find all paths which match the path of the current display.. @@ -211,11 +224,11 @@ public function alterRoutes(RouteCollection $collection) { $display_id = $this->display['id']; $route = $this->getRoute($view_id, $display_id); $collection->add($name, $route); - $altered_views[] = $view_id . '.' . $display_id; + $view_route_names[$view_id . '.' . $display_id] = $name; } } - return $altered_views; + return $view_route_names; } /** diff --git a/core/modules/views/tests/Drupal/views/Tests/EventSubscriber/RouteSubscriberTest.php b/core/modules/views/tests/Drupal/views/Tests/EventSubscriber/RouteSubscriberTest.php index dd22adb..5053ad1 100644 --- a/core/modules/views/tests/Drupal/views/Tests/EventSubscriber/RouteSubscriberTest.php +++ b/core/modules/views/tests/Drupal/views/Tests/EventSubscriber/RouteSubscriberTest.php @@ -41,6 +41,13 @@ class RouteSubscriberTest extends UnitTestCase { */ protected $routeSubscriber; + /** + * The mocked key value storage. + * + * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $state; + public static function getInfo() { return array( 'name' => 'Views route subscriber', @@ -60,7 +67,8 @@ protected function setUp() { ->method('getStorageController') ->with('view') ->will($this->returnValue($this->viewStorageController)); - $this->routeSubscriber = new TestRouteSubscriber($this->entityManager); + $this->state = $this->getMock('\Drupal\Core\KeyValueStore\KeyValueStoreInterface'); + $this->routeSubscriber = new TestRouteSubscriber($this->entityManager, $this->state); } /** @@ -75,11 +83,18 @@ public function testDynamicRoutes() { list($view, $executable, $display_1, $display_2) = $this->setupMocks(); $display_1->expects($this->once()) - ->method('collectRoutes'); + ->method('collectRoutes') + ->will($this->returnValue(array('test_id.page_1' => 'views.test_id.page_1'))); $display_2->expects($this->once()) - ->method('collectRoutes'); + ->method('collectRoutes') + ->will($this->returnValue(array('test_id.page_2' => 'views.test_id.page_2'))); $this->assertNull($this->routeSubscriber->dynamicRoutes($route_event)); + + $this->state->expects($this->once()) + ->method('set') + ->with('views.view_route_names', array('test_id.page_1' => 'views.test_id.page_1', 'test_id.page_2' => 'views.test_id.page_2')); + $this->routeSubscriber->destruct(); } /** @@ -101,7 +116,7 @@ public function testAlterRoutes() { // should only call the second display. $display_1->expects($this->once()) ->method('alterRoutes') - ->will($this->returnValue(array('test_id.page_1'))); + ->will($this->returnValue(array('test_id.page_1' => 'test_route'))); $display_1->expects($this->never()) ->method('collectRoutes'); @@ -109,7 +124,8 @@ public function testAlterRoutes() { ->method('alterRoutes') ->will($this->returnValue(array())); $display_2->expects($this->once()) - ->method('collectRoutes'); + ->method('collectRoutes') + ->will($this->returnValue(array('test_id.page_2' => 'views.test_id.page_2'))); $this->assertNull($this->routeSubscriber->alterRoutes($route_event)); @@ -117,6 +133,11 @@ public function testAlterRoutes() { // once (not for page_1 anymore). $this->assertNull($this->routeSubscriber->dynamicRoutes($route_event)); + + $this->state->expects($this->once()) + ->method('set') + ->with('views.view_route_names', array('test_id.page_1' => 'test_route', 'test_id.page_2' => 'views.test_id.page_2')); + $this->routeSubscriber->destruct(); } protected function setupMocks() { diff --git a/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php b/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php index b030d08..d636baa 100644 --- a/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php +++ b/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php @@ -91,7 +91,8 @@ public function testCollectRoutes() { $this->pathPlugin->initDisplay($view, $display); $collection = new RouteCollection(); - $this->pathPlugin->collectRoutes($collection); + $result = $this->pathPlugin->collectRoutes($collection); + $this->assertEquals(array('test_id.page_1' => 'view.test_id.page_1'), $result); $route = $collection->get('view.test_id.page_1'); $this->assertTrue($route instanceof Route); @@ -119,8 +120,8 @@ public function testAlterRoute() { ); $this->pathPlugin->initDisplay($view, $display); - $found_views = $this->pathPlugin->alterRoutes($collection); - $this->assertEquals(array('test_id.page_1'), $found_views); + $view_route_names = $this->pathPlugin->alterRoutes($collection); + $this->assertEquals(array('test_id.page_1' => 'test_route'), $view_route_names); // Ensure that the test_route is overridden. $route = $collection->get('test_route'); diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml index ee1b500..201780b 100644 --- a/core/modules/views/views.services.yml +++ b/core/modules/views/views.services.yml @@ -83,9 +83,10 @@ services: arguments: [views_results] views.route_subscriber: class: Drupal\views\EventSubscriber\RouteSubscriber - arguments: ['@entity.manager'] + arguments: ['@entity.manager', '@state'] tags: - { name: 'event_subscriber' } + - { name: 'needs_destruction' } views.route_access_check: class: Drupal\views\ViewsAccessCheck tags: