diff --git a/core/core.services.yml b/core/core.services.yml index b6decf3..9598def 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -238,6 +238,11 @@ services: entity.form_builder: class: Drupal\Core\Entity\EntityFormBuilder arguments: ['@entity.manager', '@form_builder'] + entity.route_subscriber: + class: Drupal\Core\Entity\EntityRouteBuilderSubscriber + arguments: ['@entity.manager'] + tags: + - { name: event_subscriber } plugin.manager.field.field_type: class: Drupal\Core\Field\FieldTypePluginManager arguments: ['@container.namespaces', '@cache.discovery', '@language_manager', '@module_handler'] diff --git a/core/lib/Drupal/Core/Entity/EntityRouteBuilder.php b/core/lib/Drupal/Core/Entity/EntityRouteBuilder.php new file mode 100644 index 0000000..57a096e --- /dev/null +++ b/core/lib/Drupal/Core/Entity/EntityRouteBuilder.php @@ -0,0 +1,58 @@ +addCanonicalRoute($path, $entity_type, $collection); + } + if ($link_name == 'delete-form') { + $this->deleteCanonicalRoute($path, $entity_type, $collection); + } + } + + protected function addCanonicalRoute($path, EntityType $entity_type, RouteCollection $collection) { + $route_name = $entity_type->id() . '.view'; + if ($entity_type->getAdminPermission() === TRUE) { + $requirements = array('_access' => 'TRUE'); + } + else { + $requirements = array('_entity_access' => $entity_type->id() . '.full'); + } + $route = new Route($path, + // @TODO we don't have a generic title callback yet. + array('_entity_view' => $entity_type->id() . '.full'), + $requirements + ); + $collection->add($route_name, $route); + } + + protected function deleteCanonicalRoute($path, EntityType $entity_type, RouteCollection $collection) { + $route_name = $entity_type->id() . '..delete'; + if ($entity_type->getAdminPermission() === TRUE) { + $requirements = array('_access' => 'TRUE'); + } + else { + $requirements = array('_entity_access' => $entity_type->id() . '.delete'); + } + $route = new Route($path, + // @TODO we don't have a generic title callback yet. + array('_entity_form' => $entity_type->id() . '.delete'), + $requirements + ); + $collection->add($route_name, $route); + } + +} + diff --git a/core/lib/Drupal/Core/Entity/EntityRouteBuilderSubscriber.php b/core/lib/Drupal/Core/Entity/EntityRouteBuilderSubscriber.php new file mode 100644 index 0000000..0a9fbfc --- /dev/null +++ b/core/lib/Drupal/Core/Entity/EntityRouteBuilderSubscriber.php @@ -0,0 +1,49 @@ +entityManager = $entity_manager; + } + + /** + * Builds entity routes upon paths defined in the entity annotation. + */ + public function buildEntityRoutes(RouteBuildEvent $event) { + foreach ($this->entityManager->getDefinitions() as $entity_type) { + foreach ($entity_type->getLinkTemplates() as $name => $link_template) { + // @todo Just require to always use paths. + // We distinct between route names and paths using "/". + if (strpos($link_template, '/') !== FALSE) { + /** @var \Drupal\Core\Entity\EntityRouteBuilder $route_builder */ + if ($route_builder = $this->entityManager->getController($entity_type->id(), 'route_builder')) { + $route_builder->addRoutes($name, $link_template, $entity_type, $event->getRouteCollection()); + } + } + } + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::DYNAMIC] = 'buildEntityRoutes'; + + return $events; + } + + +} + diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php index 4382665..b5d4cb3 100644 --- a/core/lib/Drupal/Core/Entity/EntityType.php +++ b/core/lib/Drupal/Core/Entity/EntityType.php @@ -318,6 +318,7 @@ public function isSubclassOf($class) { public function getControllerClasses() { return $this->controllers + array( 'access' => 'Drupal\Core\Entity\EntityAccessController', + 'route_builder' => 'Drupal\Core\Entity\EntityRouteBuilder', ); } diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml index 38b0c44..6d3ca93 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml +++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml @@ -1,18 +1,3 @@ -entity_test.render: - path: '/entity_test/{entity_test}' - defaults: - _entity_view: 'entity_test.full' - _title: 'Test full view mode' - requirements: - _access: 'TRUE' - -entity_test.delete_entity_test: - path: '/entity_test/delete/entity_test/{entity_test}' - defaults: - _entity_form: entity_test.delete - requirements: - _access: 'TRUE' - entity_test.delete_entity_test_mul: path: '/entity_test/delete/entity_test_mul/{entity_test_mul}' defaults: diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php index 01e6872..02762ed 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php @@ -39,10 +39,11 @@ * "bundle" = "type", * "label" = "name" * }, + * admin_permission = TRUE, * links = { - * "canonical" = "entity_test.render", + * "canonical" = "/entity_test/{entity_test}", * "edit-form" = "entity_test.edit_entity_test", - * "delete-form" = "entity_test.delete_entity_test", + * "delete-form" = "/entity_test/delete/entity_test/{entity_test}", * "admin-form" = "entity_test.admin_entity_test" * } * )