From 24e3c5d154040104d76d84b54fffdb7c29982809 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 18 Sep 2013 14:10:04 +0100
Subject: [PATCH] =?UTF-8?q?Issue=20#2083615=20by=20G=C3=A1bor=20Hojtsy,=20?=
 =?UTF-8?q?YesCT:=20Use=20links=20annotation=20for=20config=20entity=20URI?=
 =?UTF-8?q?=20like=20for=20content=20entities.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Core/Config/Entity/ConfigEntityBase.php   |   7 ++
 core/lib/Drupal/Core/Entity/Entity.php        | 119 ++++++++++++++----
 core/lib/Drupal/Core/Entity/EntityNG.php      |  55 --------
 .../custom_block/Entity/CustomBlockType.php   |  16 +--
 .../Drupal/config/Tests/ConfigEntityTest.php  |   2 +-
 .../tests/config_test/config_test.module      |  12 --
 .../config_test/Entity/ConfigQueryTest.php    |   4 +-
 .../Drupal/config_test/Entity/ConfigTest.php  |   4 +-
 core/modules/contact/contact.module           |  15 ---
 .../lib/Drupal/contact/Entity/Category.php    |   4 +-
 .../Drupal/entity/Entity/EntityFormMode.php   |  16 +--
 .../Drupal/entity/Entity/EntityViewMode.php   |  16 +--
 .../lib/Drupal/filter/Entity/FilterFormat.php |  16 +--
 core/modules/image/image.module               |   9 --
 .../lib/Drupal/image/Entity/ImageStyle.php    |   4 +-
 .../lib/Drupal/language/Entity/Language.php   |  16 +--
 .../node/lib/Drupal/node/Entity/NodeType.php  |  16 +--
 .../Drupal/picture/Entity/PictureMapping.php  |  16 +--
 .../Drupal/shortcut/Entity/ShortcutSet.php    |  16 +--
 .../lib/Drupal/system/Entity/Action.php       |  16 +--
 .../lib/Drupal/system/Entity/DateFormat.php   |  16 +--
 .../system/lib/Drupal/system/Entity/Menu.php  |   3 +
 .../lib/Drupal/taxonomy/Entity/Vocabulary.php |  16 +--
 .../user/lib/Drupal/user/Entity/Role.php      |  16 +--
 .../views/lib/Drupal/views/Entity/View.php    |  16 +--
 25 files changed, 158 insertions(+), 288 deletions(-)

diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index c8b9edabcc5a..aa1cb3484ee7 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -188,4 +188,11 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function uri() {
+    return parent::uri('edit-form');
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 958996cb9fd7..683ef530d209 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -148,36 +148,109 @@ public function label($langcode = NULL) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::uri().
+   * Returns the URI elements of the entity.
+   *
+   * URI templates might be set in the links array in an annotation, for
+   * example:
+   * @code
+   * links = {
+   *   "canonical" = "/node/{node}",
+   *   "edit-form" = "/node/{node}/edit",
+   *   "version-history" = "/node/{node}/revisions"
+   * }
+   * @endcode
+   * or specified in a callback function set like:
+   * @code
+   * uri_callback = "contact_category_uri",
+   * @endcode
+   * If looking for the canonical URI, and it was not set in the links array
+   * or in a uri_callback function, the path is set using the default template:
+   * entity/entityType/id.
+   *
+   * @param string $rel
+   *   The link relationship type, for example: canonical or edit-form.
+   *
+   * @return array
+   *   An array containing the 'path' and 'options' keys used to build the URI
+   *   of the entity, and matching the signature of url().
    */
-  public function uri() {
-    $bundle = $this->bundle();
-    // A bundle-specific callback takes precedence over the generic one for the
-    // entity type.
+  public function uri($rel = 'canonical') {
     $entity_info = $this->entityInfo();
-    $bundles = entity_get_bundles($this->entityType);
-    if (isset($bundles[$bundle]['uri_callback'])) {
-      $uri_callback = $bundles[$bundle]['uri_callback'];
-    }
-    elseif (isset($entity_info['uri_callback'])) {
-      $uri_callback = $entity_info['uri_callback'];
+
+    // The links array might contain URI templates set in annotations.
+    $link_templates = isset($entity_info['links']) ? $entity_info['links'] : array();
+
+    if (isset($link_templates[$rel])) {
+      // If there is a template for the given relationship type, do the
+      // placeholder replacement and use that as the path.
+      $template = $link_templates[$rel];
+      $replacements = $this->uriPlaceholderReplacements();
+      $uri['path'] = str_replace(array_keys($replacements), array_values($replacements), $template);
+
+      // @todo Remove this once http://drupal.org/node/1888424 is in and we can
+      //   move the BC handling of / vs. no-/ to the generator.
+      $uri['path'] = trim($uri['path'], '/');
+
+      // Pass the entity data to url() so that alter functions do not need to
+      // look up this entity again.
+      $uri['options']['entity_type'] = $this->entityType;
+      $uri['options']['entity'] = $this;
+      return $uri;
     }
 
-    // Invoke the callback to get the URI. If there is no callback, use the
-    // default URI format.
-    if (isset($uri_callback) && function_exists($uri_callback)) {
-      $uri = $uri_callback($this);
+    // Only use these defaults for a canonical link (that is, a link to self).
+    // Other relationship types are not supported by this logic.
+    if ($rel == 'canonical') {
+      $bundle = $this->bundle();
+      // A bundle-specific callback takes precedence over the generic one for
+      // the entity type.
+      $bundles = entity_get_bundles($this->entityType);
+      if (isset($bundles[$bundle]['uri_callback'])) {
+        $uri_callback = $bundles[$bundle]['uri_callback'];
+      }
+      elseif (isset($entity_info['uri_callback'])) {
+        $uri_callback = $entity_info['uri_callback'];
+      }
+
+      // Invoke the callback to get the URI. If there is no callback, use the
+      // default URI format.
+      if (isset($uri_callback) && function_exists($uri_callback)) {
+        $uri = $uri_callback($this);
+      }
+      else {
+        $uri = array(
+          'path' => 'entity/' . $this->entityType . '/' . $this->id(),
+        );
+      }
+      // Pass the entity data to url() so that alter functions do not need to
+      // look up this entity again.
+      $uri['options']['entity_type'] = $this->entityType;
+      $uri['options']['entity'] = $this;
+      return $uri;
     }
-    else {
-      $uri = array(
-        'path' => 'entity/' . $this->entityType . '/' . $this->id(),
+  }
+
+  /**
+   * Returns an array of placeholders for this entity.
+   *
+   * Individual entity classes may override this method to add additional
+   * placeholders if desired. If so, they should be sure to replicate the
+   * property caching logic.
+   *
+   * @return array
+   *   An array of URI placeholders.
+   */
+  protected function uriPlaceholderReplacements() {
+    if (empty($this->uriPlaceholderReplacements)) {
+      $this->uriPlaceholderReplacements = array(
+        '{entityType}' => $this->entityType(),
+        '{bundle}' => $this->bundle(),
+        '{id}' => $this->id(),
+        '{uuid}' => $this->uuid(),
+        '{' . $this->entityType() . '}' => $this->id(),
       );
     }
-    // Pass the entity data to url() so that alter functions do not need to
-    // look up this entity again.
-    $uri['options']['entity_type'] = $this->entityType;
-    $uri['options']['entity'] = $this;
-    return $uri;
+    return $this->uriPlaceholderReplacements;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/EntityNG.php
index 35e002aeeab1..9d8b53c1e828 100644
--- a/core/lib/Drupal/Core/Entity/EntityNG.php
+++ b/core/lib/Drupal/Core/Entity/EntityNG.php
@@ -207,61 +207,6 @@ public function uuid() {
     return $this->get('uuid')->value;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri($rel = 'canonical') {
-    $entity_info = $this->entityInfo();
-
-    $link_templates = isset($entity_info['links']) ? $entity_info['links'] : array();
-
-    if (isset($link_templates[$rel])) {
-      $template = $link_templates[$rel];
-      $replacements = $this->uriPlaceholderReplacements();
-      $uri['path'] = str_replace(array_keys($replacements), array_values($replacements), $template);
-
-      // @todo Remove this once http://drupal.org/node/1888424 is in and we can
-      //   move the BC handling of / vs. no-/ to the generator.
-      $uri['path'] = trim($uri['path'], '/');
-
-      // Pass the entity data to url() so that alter functions do not need to
-      // look up this entity again.
-      $uri['options']['entity_type'] = $this->entityType;
-      $uri['options']['entity'] = $this;
-      return $uri;
-    }
-
-    // For a canonical link (that is, a link to self), look up the stack for
-    // default logic. Other relationship types are not supported by parent
-    // classes.
-    if ($rel == 'canonical') {
-      return parent::uri();
-    }
-  }
-
-  /**
-   * Returns an array of placeholders for this entity.
-   *
-   * Individual entity classes may override this method to add additional
-   * placeholders if desired. If so, they should be sure to replicate the
-   * property caching logic.
-   *
-   * @return array
-   *   An array of URI placeholders.
-   */
-  protected function uriPlaceholderReplacements() {
-    if (empty($this->uriPlaceholderReplacements)) {
-      $this->uriPlaceholderReplacements = array(
-        '{entityType}' => $this->entityType(),
-        '{bundle}' => $this->bundle(),
-        '{id}' => $this->id(),
-        '{uuid}' => $this->uuid(),
-        '{' . $this->entityType() . '}' => $this->id(),
-      );
-    }
-    return $this->uriPlaceholderReplacements;
-  }
-
   /**
    * Implements \Drupal\Core\TypedData\ComplexDataInterface::get().
    */
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
index 3eeddb59fb64..75e4a4caf343 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
@@ -37,6 +37,9 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/block/custom-blocks/manage/{custom_block_type}"
  *   }
  * )
  */
@@ -77,19 +80,6 @@ class CustomBlockType extends ConfigEntityBase implements CustomBlockTypeInterfa
    */
   public $description;
 
-  /**
-   * Overrides \Drupal\Core\Entity\Entity::uri().
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/structure/block/custom-blocks/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      )
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
index 3e2a71820302..2b16c9d443ff 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
@@ -62,7 +62,7 @@ function testCRUD() {
     $this->assertIdentical($empty->isNewRevision(), FALSE);
     $this->assertIdentical($empty->entityType(), 'config_test');
     $uri = $empty->uri();
-    $this->assertIdentical($uri['path'], 'admin/structure/config_test/manage/');
+    $this->assertIdentical($uri['path'], 'admin/structure/config_test/manage');
     $this->assertIdentical($empty->isDefaultRevision(), TRUE);
 
     // Verify that an empty entity cannot be saved.
diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module
index 557224775e90..b81561027445 100644
--- a/core/modules/config/tests/config_test/config_test.module
+++ b/core/modules/config/tests/config_test/config_test.module
@@ -10,18 +10,6 @@
 
 require_once dirname(__FILE__) . '/config_test.hooks.inc';
 
-/**
- * Entity URI callback.
- *
- * @param Drupal\config_test\Entity\ConfigTest $config_test
- *   A ConfigTest entity.
- */
-function config_test_uri(ConfigTest $config_test) {
-  return array(
-    'path' => 'admin/structure/config_test/manage/' . $config_test->id(),
-  );
-}
-
 /**
  * Implements hook_menu().
  */
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php
index e909f4d1eefc..6c550572235a 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php
@@ -24,12 +24,14 @@
  *       "default" = "Drupal\config_test\ConfigTestFormController"
  *     }
  *   },
- *   uri_callback = "config_test_uri",
  *   config_prefix = "config_query_test.dynamic",
  *   entity_keys = {
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/config_test/manage/{config_query_test}"
  *   }
  * )
  *
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php
index c355e25c7faf..c4d330e6f477 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php
@@ -28,13 +28,15 @@
  *     },
  *     "access" = "Drupal\config_test\ConfigTestAccessController"
  *   },
- *   uri_callback = "config_test_uri",
  *   config_prefix = "config_test.dynamic",
  *   entity_keys = {
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid",
  *     "status" = "status"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/config_test/manage/{config_test}"
  *   }
  * )
  */
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index bcfe6891133c..020fd17fd394 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -234,21 +234,6 @@ function contact_category_load($id) {
   return entity_load('contact_category', $id);
 }
 
-/**
- * Entity URI callback.
- *
- * @param Drupal\contact\Entity\Category $category
- *   A contact category entity.
- *
- * @return array
- *   An array with 'path' as the key and the path to the category as the value.
- */
-function contact_category_uri(Category $category) {
-  return array(
-    'path' => 'admin/structure/contact/manage/' . $category->id(),
-  );
-}
-
 /**
  * Implements hook_mail().
  */
diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Category.php b/core/modules/contact/lib/Drupal/contact/Entity/Category.php
index f8b43fea7b8e..2e6dd3bb336d 100644
--- a/core/modules/contact/lib/Drupal/contact/Entity/Category.php
+++ b/core/modules/contact/lib/Drupal/contact/Entity/Category.php
@@ -30,13 +30,15 @@
  *       "delete" = "Drupal\contact\Form\CategoryDeleteForm"
  *     }
  *   },
- *   uri_callback = "contact_category_uri",
  *   config_prefix = "contact.category",
  *   bundle_of = "contact_message",
  *   entity_keys = {
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/contact/manage/{contact_category}"
  *   }
  * )
  */
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
index f2aa4bd1daaf..ac13757274ae 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
@@ -48,22 +48,12 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/display-modes/form/manage/{form_mode}"
  *   }
  * )
  */
 class EntityFormMode extends EntityDisplayModeBase implements EntityFormModeInterface {
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/structure/display-modes/form/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
 }
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
index e7f2a10c4f25..c46ef609f6ae 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
@@ -49,22 +49,12 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/display-modes/view/manage/{view_mode}"
  *   }
  * )
  */
 class EntityViewMode extends EntityDisplayModeBase implements EntityViewModeInterface {
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/structure/display-modes/view/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
 }
diff --git a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php
index 19417a48d8f4..45033e9b342d 100644
--- a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php
+++ b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php
@@ -38,6 +38,9 @@
  *     "uuid" = "uuid",
  *     "weight" = "weight",
  *     "status" = "status"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/content/formats/manage/{filter_format}"
  *   }
  * )
  */
@@ -188,19 +191,6 @@ public function disable() {
     return $this;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/config/content/formats/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index b93bc533218d..910612b435bc 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -77,15 +77,6 @@ function image_help($path, $arg) {
   }
 }
 
-/**
- * Entity URI callback for image style.
- */
-function image_style_entity_uri(ImageStyle $style) {
-  return array(
-    'path' => 'admin/config/media/image-styles/manage/' . $style->id(),
-  );
-}
-
 /**
  * Implements hook_menu().
  */
diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
index 459c7c921eaf..83aea6fee91c 100644
--- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
@@ -35,12 +35,14 @@
  *     "list" = "Drupal\image\ImageStyleListController",
  *     "access" = "Drupal\image\ImageStyleAccessController"
  *   },
- *   uri_callback = "image_style_entity_uri",
  *   config_prefix = "image.style",
  *   entity_keys = {
  *     "id" = "name",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/media/image-styles/manage/{image_style}"
  *   }
  * )
  */
diff --git a/core/modules/language/lib/Drupal/language/Entity/Language.php b/core/modules/language/lib/Drupal/language/Entity/Language.php
index c145f25caefe..53e721f4aea1 100644
--- a/core/modules/language/lib/Drupal/language/Entity/Language.php
+++ b/core/modules/language/lib/Drupal/language/Entity/Language.php
@@ -37,6 +37,9 @@
  *     "label" = "label",
  *     "weight" = "weight",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/regional/language/edit/{language_entity}"
  *   }
  * )
  */
@@ -97,17 +100,4 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
     $this->langcode = 'en';
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/config/regional/language/edit/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
 }
diff --git a/core/modules/node/lib/Drupal/node/Entity/NodeType.php b/core/modules/node/lib/Drupal/node/Entity/NodeType.php
index c4ac5dd8b9c9..8a638161f414 100644
--- a/core/modules/node/lib/Drupal/node/Entity/NodeType.php
+++ b/core/modules/node/lib/Drupal/node/Entity/NodeType.php
@@ -36,6 +36,9 @@
  *     "id" = "type",
  *     "label" = "name",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/types/manage/{node_type}"
  *   }
  * )
  */
@@ -136,19 +139,6 @@ public function id() {
     return $this->type;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/structure/types/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php
index fb266fa5afe2..b42fbee1f089 100644
--- a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php
+++ b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php
@@ -36,6 +36,9 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/media/picturemapping/{picture_mapping}"
  *   }
  * )
  */
@@ -162,17 +165,4 @@ public function hasMappings() {
     }
     return $mapping_found;
   }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/config/media/picturemapping/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
 }
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
index e53191756d50..b52fccbe8470 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
@@ -37,6 +37,9 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/user-interface/shortcut/manage/{shortcut_set}"
  *   }
  * )
  */
@@ -70,19 +73,6 @@ class ShortcutSet extends ConfigEntityBase implements ShortcutSetInterface {
    */
   public $links = array();
 
-  /**
-   * Overrides \Drupal\Core\Entity\Entity::uri().
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/config/user-interface/shortcut/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/system/lib/Drupal/system/Entity/Action.php b/core/modules/system/lib/Drupal/system/Entity/Action.php
index 08a5d3d6fe8a..ac73e40fe99a 100644
--- a/core/modules/system/lib/Drupal/system/Entity/Action.php
+++ b/core/modules/system/lib/Drupal/system/Entity/Action.php
@@ -31,6 +31,9 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/system/actions/configure/{action}"
  *   }
  * )
  */
@@ -137,19 +140,6 @@ public function getType() {
     return $this->type;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/config/system/actions/configure/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php
index 0c3b2611ee1c..54e58d8d5360 100644
--- a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php
+++ b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php
@@ -36,6 +36,9 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/config/regional/date-time/formats/manage/{date_format}"
  *   }
  * )
  */
@@ -81,19 +84,6 @@ class DateFormat extends ConfigEntityBase implements DateFormatInterface {
    */
   protected $locales = array();
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/config/regional/date-time/formats/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/system/lib/Drupal/system/Entity/Menu.php b/core/modules/system/lib/Drupal/system/Entity/Menu.php
index 4727f8aed768..0898744ec30e 100644
--- a/core/modules/system/lib/Drupal/system/Entity/Menu.php
+++ b/core/modules/system/lib/Drupal/system/Entity/Menu.php
@@ -28,6 +28,9 @@
  *     "id" = "id",
  *     "label" = "label",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/menu/manage/{menu}"
  *   }
  * )
  */
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
index d0c6316b1a50..df4018a852a7 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
@@ -37,6 +37,9 @@
  *     "label" = "name",
  *     "weight" = "weight",
  *     "uuid" = "uuid"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/taxonomy/manage/{taxonomy_vocabulary}"
  *   }
  * )
  */
@@ -96,19 +99,6 @@ public function id() {
     return $this->vid;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/structure/taxonomy/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/user/lib/Drupal/user/Entity/Role.php b/core/modules/user/lib/Drupal/user/Entity/Role.php
index 61f6f2e2058f..83e4e5ebedfe 100644
--- a/core/modules/user/lib/Drupal/user/Entity/Role.php
+++ b/core/modules/user/lib/Drupal/user/Entity/Role.php
@@ -35,6 +35,9 @@
  *     "uuid" = "uuid",
  *     "weight" = "weight",
  *     "label" = "label"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/people/roles/manage/{user_role}"
  *   }
  * )
  */
@@ -75,19 +78,6 @@ class Role extends ConfigEntityBase implements RoleInterface {
    */
   public $permissions = array();
 
-  /**
-   * {@inheritdoc}
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/people/roles/manage/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/views/lib/Drupal/views/Entity/View.php b/core/modules/views/lib/Drupal/views/Entity/View.php
index ce820ffc8b78..e1f9873bcb8c 100644
--- a/core/modules/views/lib/Drupal/views/Entity/View.php
+++ b/core/modules/views/lib/Drupal/views/Entity/View.php
@@ -33,6 +33,9 @@
  *     "label" = "label",
  *     "uuid" = "uuid",
  *     "status" = "status"
+ *   },
+ *   links = {
+ *     "edit-form" = "admin/structure/views/view/{view}"
  *   }
  * )
  */
@@ -134,19 +137,6 @@ public function getExecutable() {
     return $this->executable;
   }
 
-  /**
-   * Overrides Drupal\Core\Entity\EntityInterface::uri().
-   */
-  public function uri() {
-    return array(
-      'path' => 'admin/structure/views/view/' . $this->id(),
-      'options' => array(
-        'entity_type' => $this->entityType,
-        'entity' => $this,
-      ),
-    );
-  }
-
   /**
    * Overrides Drupal\Core\Config\Entity\ConfigEntityBase::createDuplicate().
    */
-- 
GitLab