.../Entity/Controller/EntityViewController.php | 24 ++++++++++++++++++++++ core/lib/Drupal/Core/Entity/Entity.php | 4 ++-- .../Entity/Routing/DefaultHtmlRouteProvider.php | 10 ++++----- core/modules/node/src/Entity/NodeRouteProvider.php | 13 ++++++------ core/modules/taxonomy/taxonomy.routing.yml | 14 +++++++------ core/modules/user/src/Entity/UserRouteProvider.php | 13 ++++++------ 6 files changed, 52 insertions(+), 26 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php index 983eec8..3a8a20c 100644 --- a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php +++ b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php @@ -7,6 +7,8 @@ use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Render\RendererInterface; +use Drupal\Core\Routing\LocalRedirectResponse; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -120,4 +122,26 @@ public function viewRevision(EntityInterface $_entity_revision, $view_mode = 'fu return $this->view($_entity_revision, $view_mode); } + /** + * Redirects UUID entity links to the canonical URL. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object identified by the UUID URL. + * + * @return \Symfony\Component\HttpFoundation\RedirectResponse + * Redirects to canonical entity URL. + */ + public function redirectUUidToCanonical(EntityInterface $entity) { + $entity_type_id = $entity->getEntityTypeId(); + $canonical_url = Url::fromRoute("entity.$entity_type_id.canonical") + ->setRouteParameter($entity_type_id, $entity->id()) + ->setAbsolute(TRUE) + ->toString(TRUE); + + $redirect = new LocalRedirectResponse($canonical_url->getGeneratedUrl()); + $redirect->addCacheableDependency($canonical_url); + + return $redirect; + } + } diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php index b3c865e..74fd155 100644 --- a/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -304,7 +304,7 @@ public function url($rel = 'canonical', $options = array()) { protected function urlRouteParameters($rel) { $uri_route_parameters = []; - if (!in_array($rel, ['collection', 'add-page', 'add-form'], TRUE)) { + if (!in_array($rel, ['collection', 'add-page', 'add-form', 'uuid'], TRUE)) { // The entity ID is needed as a route parameter. $uri_route_parameters[$this->getEntityTypeId()] = $this->id(); } @@ -316,7 +316,7 @@ protected function urlRouteParameters($rel) { $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId(); } if ($rel === 'uuid') { - $uri_route_parameters[$this->getEntityTypeId()] = $this->uuid(); + $uri_route_parameters['entity'] = $this->uuid(); } return $uri_route_parameters; diff --git a/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php b/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php index d24035b..daac768 100644 --- a/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php +++ b/core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php @@ -5,6 +5,7 @@ use Drupal\Component\Uuid\Uuid; use Drupal\Core\Config\Entity\ConfigEntityTypeInterface; use Drupal\Core\Entity\Controller\EntityController; +use Drupal\Core\Entity\Controller\EntityViewController; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Entity\EntityTypeInterface; @@ -256,16 +257,13 @@ protected function getUuidRoute(EntityTypeInterface $entity_type) { $entity_type_id = $entity_type->id(); $route = new Route($entity_type->getLinkTemplate('uuid')); $route - ->addDefaults([ - '_entity_view' => $entity_type_id . '.full', - '_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::title', - ]) - ->setRequirement('_entity_access', $entity_type_id . '.view') + ->setDefault('_controller', EntityViewController::class . '::redirectUUidToCanonical') + ->setRequirement('_access', 'TRUE') ->setOption('parameters', [ $entity_type_id => ['type' => 'entity:' . $entity_type_id], ]) // Set requirement for UUID pattern. - ->setRequirement($entity_type_id, '^' . Uuid::VALID_PATTERN . '$'); + ->setRequirement('entity', '^' . Uuid::VALID_PATTERN . '$'); return $route; } } diff --git a/core/modules/node/src/Entity/NodeRouteProvider.php b/core/modules/node/src/Entity/NodeRouteProvider.php index b46b09d..fd158cc 100644 --- a/core/modules/node/src/Entity/NodeRouteProvider.php +++ b/core/modules/node/src/Entity/NodeRouteProvider.php @@ -3,6 +3,7 @@ namespace Drupal\node\Entity; use Drupal\Component\Uuid\Uuid; +use Drupal\Core\Entity\Controller\EntityViewController; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Routing\EntityRouteProviderInterface; use Symfony\Component\Routing\Route; @@ -19,14 +20,14 @@ class NodeRouteProvider implements EntityRouteProviderInterface { public function getRoutes( EntityTypeInterface $entity_type) { $route_collection = new RouteCollection(); - $route = (new Route("/node/{node}")) - ->addDefaults([ - '_controller' => '\Drupal\node\Controller\NodeViewController::view', - '_title_callback' => '\Drupal\node\Controller\NodeViewController::title', + $route = (new Route("/node/{entity}")) + ->setDefault('_controller', EntityViewController::class . '::redirectUUidToCanonical') + ->setOption('parameters', [ + 'entity' => ['type' => 'entity:node'], ]) // Set requirement for UUID pattern. - ->setRequirement('node', '^' . Uuid::VALID_PATTERN . '$') - ->setRequirement('_entity_access', 'node.view'); + ->setRequirement('entity', '^' . Uuid::VALID_PATTERN . '$') + ->setRequirement('_access', 'TRUE'); $route_collection->add('entity.node.uuid', $route); $route = (new Route('/node/{node}')) diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index 4957fa9..9b01e4f 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -77,14 +77,16 @@ entity.taxonomy_vocabulary.overview_form: _entity_access: 'taxonomy_vocabulary.view' entity.taxonomy_term.uuid: - path: '/taxonomy/term/{taxonomy_term}' + path: '/taxonomy/term/{entity}' defaults: - _entity_view: 'taxonomy_term.full' - _title: 'Taxonomy term' - _title_callback: '\Drupal\taxonomy\Controller\TaxonomyController::termTitle' + _controller: '\Drupal\Core\Entity\Controller\EntityViewController::redirectUUidToCanonical' requirements: - _entity_access: 'taxonomy_term.view' - taxonomy_term: '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}' + _access: 'TRUE' + entity: '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}' + options: + parameters: + entity: + type: 'entity:node' entity.taxonomy_term.canonical: path: '/taxonomy/term/{taxonomy_term}' diff --git a/core/modules/user/src/Entity/UserRouteProvider.php b/core/modules/user/src/Entity/UserRouteProvider.php index 14543bb..4740ea2 100644 --- a/core/modules/user/src/Entity/UserRouteProvider.php +++ b/core/modules/user/src/Entity/UserRouteProvider.php @@ -3,6 +3,7 @@ namespace Drupal\user\Entity; use Drupal\Component\Uuid\Uuid; +use Drupal\Core\Entity\Controller\EntityViewController; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Routing\EntityRouteProviderInterface; use Symfony\Component\Routing\Route; @@ -19,14 +20,14 @@ class UserRouteProvider implements EntityRouteProviderInterface { public function getRoutes(EntityTypeInterface $entity_type) { $route_collection = new RouteCollection(); - $route = (new Route("/user/{user}")) - ->addDefaults([ - '_entity_view' => 'user.full', - '_title_callback' => 'Drupal\user\Controller\UserController::userTitle', + $route = (new Route("/user/{entity}")) + ->setDefault('_controller', EntityViewController::class . '::redirectUUidToCanonical') + ->setOption('parameters', [ + 'entity' => ['type' => 'entity:user'], ]) // Set requirement for UUID pattern. - ->setRequirement('user', '^' . Uuid::VALID_PATTERN . '$') - ->setRequirement('_entity_access', 'user.view'); + ->setRequirement('entity', '^' . Uuid::VALID_PATTERN . '$') + ->setRequirement('_access', 'TRUE'); $route_collection->add('entity.user.uuid', $route); $route = (new Route('/user/{user}'))