diff --git a/core/lib/Drupal/Core/Entity/EntityTypeManager.php b/core/lib/Drupal/Core/Entity/EntityTypeManager.php index 399963f..6dbe4d2 100644 --- a/core/lib/Drupal/Core/Entity/EntityTypeManager.php +++ b/core/lib/Drupal/Core/Entity/EntityTypeManager.php @@ -87,7 +87,7 @@ public function processDefinition(&$definition, $plugin_id) { // Add the UUID link template if applicable. $route_providers = $definition->getRouteProviderClasses(); $has_uuid_route = isset($route_providers['html']) && in_array(EntityUuidRouteProviderInterface::class, class_implements($route_providers['html']), TRUE); - if ($definition->hasKey('uuid') && $definition->hasViewBuilderClass() && $has_uuid_route) { + if (!$definition->hasLinkTemplate('uuid') && $definition->hasKey('uuid') && $definition->hasViewBuilderClass() && $has_uuid_route) { $definition->setLinkTemplate('uuid', "/{$plugin_id}/{{$plugin_id}}"); } // All link templates must have a leading slash. diff --git a/core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php b/core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php index c20df77..857d0f1 100644 --- a/core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php +++ b/core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php @@ -153,13 +153,12 @@ public function checkNodeAccess(array $tree) { $query->condition('status', NODE_PUBLISHED); } - $nids = $query->execute(); - if ($nids) { - foreach ($nids as $nid) { - if (isset($node_links[$nid])) { - foreach ($node_links[$nid] as $key => $link) { - $node_links[$nid][$key]->access = $access_result; - } + // Cast to an array so we can loop, even if there are no results. + $nids = (array) $query->execute(); + foreach ($nids as $nid) { + if (isset($node_links[$nid])) { + foreach ($node_links[$nid] as $key => $link) { + $node_links[$nid][$key]->access = $access_result; } } } diff --git a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php index 0d93051..855356b7 100644 --- a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php +++ b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php @@ -58,6 +58,8 @@ public function __construct(EntityManagerInterface $entity_manager) { /** * {@inheritdoc} + * + * The value here can be either a serial entity ID, or the entity UUID. */ public function convert($value, $definition, $name, array $defaults) { $entity_type_id = $this->getEntityTypeFromDefaults($definition, $name, $defaults); diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index cab395f..fdf1f7d 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -204,6 +204,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { $query = \Drupal::entityQuery('menu_link_content'); $group = $query->orConditionGroup() ->condition('link.uri', 'entity:node/' . $node->id()) + ->condition('link.uri', 'entity:node/' . $node->uuid()) ->condition('link.uri', 'internal:/node/' . $node->id()) ->condition('link.uri', 'internal:/node/' . $node->uuid()); $query->condition($group) @@ -219,6 +220,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { $query = \Drupal::entityQuery('menu_link_content'); $group = $query->orConditionGroup() ->condition('link.uri', 'entity:node/' . $node->id()) + ->condition('link.uri', 'entity:node/' . $node->uuid()) ->condition('link.uri', 'internal:/node/' . $node->id()) ->condition('link.uri', 'internal:/node/' . $node->uuid()); $query->condition($group) diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php index 6c96e79..6d9796c 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php @@ -17,6 +17,7 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManager; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Tests\UnitTestCase; @@ -99,12 +100,12 @@ protected function setUpEntityTypeDefinitions($definitions = []) { // Give the entity type a legitimate class to return. $entity_type->getClass()->willReturn($class); - // Don't allow uuid key. - $entity_type->hasKey('uuid')->willReturn(FALSE); - // Or route provider. if (!$entity_type->getMethodProphecies('getRouteProviderClasses')) { $entity_type->getRouteProviderClasses()->willReturn([]); + // Don't allow uuid key. + $entity_type->hasKey('uuid')->willReturn(FALSE); + $entity_type->hasLinkTemplate('uuid')->willReturn(FALSE); } $definitions[$key] = $entity_type->reveal(); @@ -308,6 +309,10 @@ public function testGetRouteProviders() { $apple = $this->prophesize(EntityTypeInterface::class); $apple->getRouteProviderClasses()->willReturn(['default' => TestRouteProvider::class]); + // Don't allow uuid key. + $apple->hasKey('uuid')->willReturn(FALSE); + $apple->hasLinkTemplate('uuid')->willReturn(FALSE); + $this->setUpEntityTypeDefinitions([ 'apple' => $apple, ]); @@ -319,6 +324,27 @@ public function testGetRouteProviders() { } /** + * @covers ::processDefinition + */ + public function testUuidRouteProviders() { + $apple = $this->prophesize(EntityTypeInterface::class); + $apple->getRouteProviderClasses()->willReturn(['html' => DefaultHtmlRouteProvider::class]); + + // Allow uuid key. + $apple->hasKey('uuid')->willReturn(TRUE); + $apple->hasLinkTemplate('uuid')->willReturn(FALSE); + $apple->hasViewBuilderClass()->willReturn(TRUE); + + $this->setUpEntityTypeDefinitions([ + 'apple' => $apple, + ]); + + $apple->setLinkTemplate('uuid', '/apple/{apple}')->shouldBeCalled(); + $definition = $apple->reveal(); + $this->entityTypeManager->processDefinition($definition, 'apple'); + } + + /** * Tests the processDefinition() method. * * @covers ::processDefinition