diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index 96a75da78a..e95c01b2c8 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -269,6 +269,7 @@ public function buildMultiple(array $build_list) { $this->moduleHandler()->invokeAll($view_hook, [&$build_list[$key], $entity, $display, $view_mode]); $this->moduleHandler()->invokeAll('entity_view', [&$build_list[$key], $entity, $display, $view_mode]); + $this->addContextualLinks($build_list[$key], $entity); $this->alterBuild($build_list[$key], $entity, $display, $view_mode); // Assign the weights configured in the display. @@ -324,6 +325,36 @@ public function buildComponents(array &$build, array $entities, array $displays, } } + /** + * Add contextual links. + * + * @param array $build + * The render array that is being created. + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to be prepared. + */ + protected function addContextualLinks(array &$build, EntityInterface $entity) { + if ($entity->isNew()) { + return; + } + $key = $entity->getEntityTypeId(); + $rel = 'canonical'; + if ($entity instanceof ContentEntityInterface && !$entity->isDefaultRevision()) { + $rel = 'revision'; + $key .= '_revision'; + } + if ($entity->hasLinkTemplate($rel)) { + $build['#contextual_links'][$key] = [ + 'route_parameters' => $entity->toUrl($rel)->getRouteParameters(), + ]; + if ($entity instanceof EntityChangedInterface) { + $build['#contextual_links'][$key]['metadata'] = [ + 'changed' => $entity->getChangedTime(), + ]; + } + } + } + /** * Specific per-entity building. * diff --git a/core/modules/block_content/src/BlockContentViewBuilder.php b/core/modules/block_content/src/BlockContentViewBuilder.php index 29c668cd63..2ea321d769 100644 --- a/core/modules/block_content/src/BlockContentViewBuilder.php +++ b/core/modules/block_content/src/BlockContentViewBuilder.php @@ -2,7 +2,6 @@ namespace Drupal\block_content; -use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityViewBuilder; @@ -41,18 +40,4 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) { return $build; } - /** - * {@inheritdoc} - */ - protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { - parent::alterBuild($build, $entity, $display, $view_mode); - // Add contextual links for this custom block. - if (!$entity->isNew()) { - $build['#contextual_links']['block_content'] = [ - 'route_parameters' => ['block_content' => $entity->id()], - 'metadata' => ['changed' => $entity->getChangedTime()], - ]; - } - } - } diff --git a/core/modules/block_content/tests/src/Functional/BlockContentContextualLinksTest.php b/core/modules/block_content/tests/src/Functional/BlockContentContextualLinksTest.php new file mode 100644 index 0000000000..e4e1a48ac8 --- /dev/null +++ b/core/modules/block_content/tests/src/Functional/BlockContentContextualLinksTest.php @@ -0,0 +1,37 @@ +createBlockContent(); + + $block = $this->placeBlock('block_content:' . $block_content->uuid()); + + $user = $this->drupalCreateUser([ + 'administer blocks', + 'access contextual links', + ]); + $this->drupalLogin($user); + + $this->drupalGet(''); + $this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'block:block=' . $block->id() . ':langcode=en|block_content:block_content=' . $block_content->id() . ':'); + } + +} diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php index f0971fb3bb..2bb7f4a2af 100644 --- a/core/modules/node/src/NodeViewBuilder.php +++ b/core/modules/node/src/NodeViewBuilder.php @@ -2,7 +2,6 @@ namespace Drupal\node; -use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityViewBuilder; use Drupal\node\Entity\Node; @@ -141,29 +140,4 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) { ]; } - /** - * {@inheritdoc} - */ - protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { - /** @var \Drupal\node\NodeInterface $entity */ - parent::alterBuild($build, $entity, $display, $view_mode); - if ($entity->id()) { - if ($entity->isDefaultRevision()) { - $build['#contextual_links']['node'] = [ - 'route_parameters' => ['node' => $entity->id()], - 'metadata' => ['changed' => $entity->getChangedTime()], - ]; - } - else { - $build['#contextual_links']['node_revision'] = [ - 'route_parameters' => [ - 'node' => $entity->id(), - 'node_revision' => $entity->getRevisionId(), - ], - 'metadata' => ['changed' => $entity->getChangedTime()], - ]; - } - } - } - } diff --git a/core/modules/node/tests/src/Functional/NodeContextualLinksTest.php b/core/modules/node/tests/src/Functional/NodeContextualLinksTest.php new file mode 100644 index 0000000000..0d4aabe6a0 --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeContextualLinksTest.php @@ -0,0 +1,42 @@ + 'article', + 'title' => 'Unnamed', + ]); + $node->save(); + + $user = $this->drupalCreateUser([ + 'administer nodes', + 'access contextual links', + ]); + $this->drupalLogin($user); + + $this->drupalGet('node/' . $node->id()); + $this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'node:node=' . $node->id() . ':'); + } + +} diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index 2e70a1cf7d..b8eac0acc3 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -19,7 +19,7 @@ * handlers = { * "storage" = "Drupal\taxonomy\TermStorage", * "storage_schema" = "Drupal\taxonomy\TermStorageSchema", - * "view_builder" = "Drupal\taxonomy\TermViewBuilder", + * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", * "list_builder" = "Drupal\Core\Entity\EntityListBuilder", * "access" = "Drupal\taxonomy\TermAccessControlHandler", * "views_data" = "Drupal\taxonomy\TermViewsData", diff --git a/core/modules/taxonomy/src/TermViewBuilder.php b/core/modules/taxonomy/src/TermViewBuilder.php index 6748a4b03c..07d0c078f2 100644 --- a/core/modules/taxonomy/src/TermViewBuilder.php +++ b/core/modules/taxonomy/src/TermViewBuilder.php @@ -2,24 +2,17 @@ namespace Drupal\taxonomy; -use Drupal\Core\Entity\Display\EntityViewDisplayInterface; -use Drupal\Core\Entity\EntityInterface; +@trigger_error(__NAMESPACE__ . '\TermViewBuilder is deprecated in Drupal 8.5.x and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityViewBuilder instead. See https://www.drupal.org/node/2924233.', E_USER_DEPRECATED); + use Drupal\Core\Entity\EntityViewBuilder; /** * View builder handler for taxonomy terms. + * + * @deprecated in Drupal 8.5.x and will be removed before Drupal 9.0.0. + * Use \Drupal\Core\Entity\EntityViewBuilder instead. + * + * @see \Drupal\Core\Entity\EntityViewBuilder + * @see https://www.drupal.org/node/2924233 */ -class TermViewBuilder extends EntityViewBuilder { - - /** - * {@inheritdoc} - */ - protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { - parent::alterBuild($build, $entity, $display, $view_mode); - $build['#contextual_links']['taxonomy_term'] = [ - 'route_parameters' => ['taxonomy_term' => $entity->id()], - 'metadata' => ['changed' => $entity->getChangedTime()], - ]; - } - -} +class TermViewBuilder extends EntityViewBuilder {} diff --git a/core/modules/taxonomy/tests/src/Functional/TermContextualLinksTest.php b/core/modules/taxonomy/tests/src/Functional/TermContextualLinksTest.php new file mode 100644 index 0000000000..997e698b9e --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TermContextualLinksTest.php @@ -0,0 +1,36 @@ +createVocabulary(); + $term = $this->createTerm($vocabulary); + + $user = $this->drupalCreateUser([ + 'administer taxonomy', + 'access contextual links', + ]); + $this->drupalLogin($user); + + $this->drupalGet('taxonomy/term/' . $term->id()); + $this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'taxonomy_term:taxonomy_term=' . $term->id() . ':'); + } + +}