From c2f5a3e8e8d0c6afdb25420dfa52453aade181e3 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 17 Jul 2015 15:55:40 +0100
Subject: [PATCH] Issue #2496897 by sasanikolic, Arla, dawehner, miro_dietiker,
 Berdir: Throw helpful exception if link templates are missing leading /

---
 core/lib/Drupal/Core/Entity/EntityManager.php | 16 ++++++++++++++++
 .../InvalidLinkTemplateException.php          | 14 ++++++++++++++
 .../Tests/Core/Entity/EntityManagerTest.php   | 19 +++++++++++++++++++
 3 files changed, 49 insertions(+)
 create mode 100644 core/lib/Drupal/Core/Entity/Exception/InvalidLinkTemplateException.php

diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 42e475a93bbd..2d03dff552d0 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -15,6 +15,7 @@
 use Drupal\Core\Config\Entity\ConfigEntityType;
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
 use Drupal\Core\Entity\Exception\AmbiguousEntityClassException;
+use Drupal\Core\Entity\Exception\InvalidLinkTemplateException;
 use Drupal\Core\Entity\Exception\NoCorrespondingEntityClassException;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
@@ -226,6 +227,21 @@ public function clearCachedDefinitions() {
     $this->handlers = array();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    /** @var \Drupal\Core\Entity\EntityTypeInterface $definition */
+    parent::processDefinition($definition, $plugin_id);
+
+    // All link templates must have a leading slash.
+    foreach ((array) $definition->getLinkTemplates() as $link_relation_name => $link_template) {
+      if ($link_template[0] != '/') {
+        throw new InvalidLinkTemplateException("Link template '$link_relation_name' for entity type '$plugin_id' must start with a leading slash, the current link template is '$link_template'");
+      }
+    }
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Entity/Exception/InvalidLinkTemplateException.php b/core/lib/Drupal/Core/Entity/Exception/InvalidLinkTemplateException.php
new file mode 100644
index 000000000000..f64d39fc4bd6
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Exception/InvalidLinkTemplateException.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Exception\InvalidLinkTemplateException.
+ */
+
+namespace Drupal\Core\Entity\Exception;
+
+/**
+ * Indicates that a link template does not follow the required pattern.
+ */
+class InvalidLinkTemplateException extends \Exception {
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
index 11b7ceda7761..a7f1c5eb8ac3 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
@@ -265,6 +265,25 @@ public function testClearCachedDefinitions() {
     $this->entityManager->clearCachedDefinitions();
   }
 
+  /**
+   * Tests the processDefinition() method.
+   *
+   * @covers ::processDefinition
+   *
+   * @expectedException \Drupal\Core\Entity\Exception\InvalidLinkTemplateException
+   * @expectedExceptionMessage Link template 'canonical' for entity type 'apple' must start with a leading slash, the current link template is 'path/to/apple'
+   */
+  public function testProcessDefinition() {
+    $apple = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
+    $apple->expects($this->once())
+      ->method('getLinkTemplates')
+      ->willReturn(['canonical' => 'path/to/apple']);
+
+    $this->setUpEntityManager(array('apple' => $apple));
+
+    $this->entityManager->processDefinition($apple, 'apple');
+  }
+
   /**
    * Tests the getDefinition() method.
    *
-- 
GitLab