From 3f56402e79ca0d775cad97c6cb2fc5777c03f50f Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org> Date: Mon, 25 Jul 2016 13:43:54 +0100 Subject: [PATCH] Issue #2767853 by tstoeckler: Provide a route for collections of entities --- .../Routing/DefaultHtmlRouteProvider.php | 32 ++++++++++++ .../Routing/DefaultHtmlRouteProviderTest.php | 49 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php b/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php index b1f6abd234c2..1ac54bb277aa 100644 --- a/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php +++ b/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php @@ -23,6 +23,7 @@ * - add-form * - edit-form * - delete-form + * - collection * * @see \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider. * @@ -95,6 +96,10 @@ public function getRoutes(EntityTypeInterface $entity_type) { $collection->add("entity.{$entity_type_id}.delete_form", $delete_route); } + if ($collection_route = $this->getCollectionRoute($entity_type)) { + $collection->add("entity.{$entity_type_id}.collection", $collection_route); + } + return $collection; } @@ -298,6 +303,33 @@ protected function getDeleteFormRoute(EntityTypeInterface $entity_type) { } } + /** + * Gets the collection route. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * The entity type. + * + * @return \Symfony\Component\Routing\Route|null + * The generated route, if available. + */ + protected function getCollectionRoute(EntityTypeInterface $entity_type) { + // If the entity type does not provide an admin permission, there is no way + // to control access, so we cannot provide a route in a sensible way. + if ($entity_type->hasLinkTemplate('collection') && $entity_type->hasListBuilderClass() && ($admin_permission = $entity_type->getAdminPermission())) { + $route = new Route($entity_type->getLinkTemplate('collection')); + $route + ->addDefaults([ + '_entity_list' => $entity_type->id(), + // @todo Improve this in https://www.drupal.org/node/2767025 + '_title' => '@label entities', + '_title_arguments' => ['@label' => $entity_type->getLabel()], + ]) + ->setRequirement('_permission', $admin_permission); + + return $route; + } + } + /** * Gets the type of the ID key for a given entity type. * diff --git a/core/tests/Drupal/Tests/Core/Entity/Routing/DefaultHtmlRouteProviderTest.php b/core/tests/Drupal/Tests/Core/Entity/Routing/DefaultHtmlRouteProviderTest.php index 71966527602c..a97f29308f4b 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Routing/DefaultHtmlRouteProviderTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Routing/DefaultHtmlRouteProviderTest.php @@ -252,6 +252,52 @@ public function providerTestGetCanonicalRoute() { return $data; } + /** + * @covers ::getCanonicalRoute + * @dataProvider providerTestGetCollectionRoute + */ + public function testGetCollectionRoute(Route $expected = NULL, EntityTypeInterface $entity_type) { + $route = $this->routeProvider->getCollectionRoute($entity_type); + $this->assertEquals($expected, $route); + } + + public function providerTestGetCollectionRoute() { + $data = []; + + $entity_type1 = $this->getEntityType(); + $entity_type1->hasLinkTemplate('collection')->willReturn(FALSE); + $data['no_collection_link_template'] = [NULL, $entity_type1->reveal()]; + + $entity_type2 = $this->getEntityType(); + $entity_type2->hasLinkTemplate('collection')->willReturn(TRUE); + $entity_type2->hasListBuilderClass()->willReturn(FALSE); + $data['no_list_builder'] = [NULL, $entity_type2->reveal()]; + + $entity_type3 = $this->getEntityType($entity_type2); + $entity_type3->hasListBuilderClass()->willReturn(TRUE); + $entity_type3->getAdminPermission()->willReturn(FALSE); + $data['no_admin_permission'] = [NULL, $entity_type3->reveal()]; + + $entity_type4 = $this->getEntityType($entity_type3); + $entity_type4->getAdminPermission()->willReturn('administer the entity type'); + $entity_type4->id()->willReturn('the_entity_type_id'); + $entity_type4->getLabel()->willReturn('The entity type'); + $entity_type4->getLinkTemplate('collection')->willReturn('/the/collection/link/template'); + $entity_type4->isSubclassOf(FieldableEntityInterface::class)->willReturn(FALSE); + $route = (new Route('/the/collection/link/template')) + ->setDefaults([ + '_entity_list' => 'the_entity_type_id', + '_title' => '@label entities', + '_title_arguments' => ['@label' => 'The entity type'], + ]) + ->setRequirements([ + '_permission' => 'administer the entity type', + ]); + $data['collection_route'] = [clone $route, $entity_type4->reveal()]; + + return $data; + } + /** * @covers ::getEntityTypeIdKeyType */ @@ -313,5 +359,8 @@ public function getAddFormRoute(EntityTypeInterface $entity_type) { public function getCanonicalRoute(EntityTypeInterface $entity_type) { return parent::getCanonicalRoute($entity_type); } + public function getCollectionRoute(EntityTypeInterface $entity_type) { + return parent::getCollectionRoute($entity_type); + } } -- GitLab