From 120e6942e83c3cfb4adc7798ddfc6bdd73554bc5 Mon Sep 17 00:00:00 2001
From: beberlei <beberlei@625475ce-881a-0410-a577-b389adb331d8>
Date: Wed, 4 Nov 2009 19:59:34 +0000
Subject: [PATCH] [2.0] DDC-115 - Fix for multiple class metadata instances
 because of classes being addressed with or without prepending namespace
 separator.

---
 .../ORM/Mapping/ClassMetadataFactory.php      | 12 ++++
 .../Models/Global/GlobalNamespaceModel.php    | 68 +++++++++++++++++++
 .../ORM/Mapping/ClassMetadataFactoryTest.php  | 45 +++++++++---
 3 files changed, 116 insertions(+), 9 deletions(-)
 create mode 100644 tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php

diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
index 9c6167d59..60686bf9d 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -102,6 +102,10 @@ class ClassMetadataFactory
      */
     public function getMetadataFor($className)
     {
+        if($className[0] == "\\") {
+            $className = substr($className, 1);
+        }
+
         if ( ! isset($this->_loadedMetadata[$className])) {
             $cacheKey = "$className\$CLASSMETADATA";
             if ($this->_cacheDriver) {
@@ -126,6 +130,10 @@ class ClassMetadataFactory
      */
     public function hasMetadataFor($className)
     {
+        if($className[0] == "\\") {
+            $className = substr($className, 1);
+        }
+
         return isset($this->_loadedMetadata[$className]);
     }
 
@@ -139,6 +147,10 @@ class ClassMetadataFactory
      */
     public function setMetadataFor($className, $class)
     {
+        if($className[0] == "\\") {
+            $className = substr($className, 1);
+        }
+
         $this->_loadedMetadata[$className] = $class;
     }
     
diff --git a/tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php b/tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php
new file mode 100644
index 000000000..d474832ee
--- /dev/null
+++ b/tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @entity
+ * @table(name="articles")
+ */
+class DoctrineGlobal_Article
+{
+    /**
+     * @id
+     * @column(type="int")
+     */
+    protected $id;
+
+    /**
+     * @column(type="string")
+     */
+    protected $headline;
+
+    /**
+     * @column(type="text")
+     */
+    protected $text;
+
+    /**
+     * @ManyToMany(targetEntity="DoctrineGlobal_User")
+     * @JoinTable(name="author_articles",
+     *      joinColumns={@JoinColumn(name="article_id", referencedColumnName="id")},
+     *      inverseJoinColumns={@JoinColumn(name="author_id", referencedColumnName="id", unique=true)}
+     * )
+     */
+    protected $author;
+
+    /**
+     * @ManyToMany(targetEntity="\DoctrineGlobal_User")
+     * @JoinTable(name="editor_articles",
+     *      joinColumns={@JoinColumn(name="article_id", referencedColumnName="id")},
+     *      inverseJoinColumns={@JoinColumn(name="editor_id", referencedColumnName="id", unique=true)}
+     * )
+     */
+    protected $editor;
+}
+
+/**
+ * @Entity
+ * @Table(name="users")
+ */
+class DoctrineGlobal_User
+{
+    /**
+     * @Id
+     * @column(type="integer")
+     * @var int
+     */
+    private $id;
+
+    /**
+     * @column(type="string", length=64)
+     * @var string
+     */
+    private $username;
+
+    /**
+     * @column(type="string", length=128)
+     * @var string
+     */
+    private $email;
+}
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php
index 130a2c8e1..49fa2ecf0 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php
@@ -16,17 +16,10 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
 {
     public function testGetMetadataForSingleClass()
     {
-        $driverMock = new DriverMock();
-        $config = new \Doctrine\ORM\Configuration();
-        $config->setProxyDir(__DIR__ . '/../../Proxies');
-        $config->setProxyNamespace('Doctrine\Tests\Proxies');
-        $eventManager = new EventManager();
-        $conn = new ConnectionMock(array(), $driverMock, $config, $eventManager);
         $mockDriver = new MetadataDriverMock();
-        $config->setMetadataDriverImpl($mockDriver);
-
-        $entityManager = EntityManagerMock::create($conn, $config, $eventManager);
+        $entityManager = $this->_createEntityManager($mockDriver);
 
+        $conn = $entityManager->getConnection();
         $mockPlatform = $conn->getDatabasePlatform();
         $mockPlatform->setPrefersSequences(true);
         $mockPlatform->setPrefersIdentityColumns(false);
@@ -65,6 +58,40 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
         $this->assertTrue($cm1->hasField('name'));
         $this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType);
     }
+
+    public function testGetMetadataGlobalNamespaceModel()
+    {
+        require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
+
+        $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache);
+        $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
+        $metadataDriver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader);
+        $metadataDriver->setClassDirectory(__DIR__."/../../Models/Global/");
+
+        $entityManager = $this->_createEntityManager($metadataDriver);
+
+        $mf = $entityManager->getMetadataFactory();
+        $m1 = $mf->getMetadataFor("DoctrineGlobal_Article");
+        $h2 = $mf->hasMetadataFor("\DoctrineGlobal_Article");
+        $m2 = $mf->getMetadataFor("\DoctrineGlobal_Article");
+
+        $this->assertSame($m1, $m2);
+        $this->assertTrue($h2);
+    }
+
+    protected function _createEntityManager($metadataDriver)
+    {
+        $driverMock = new DriverMock();
+        $config = new \Doctrine\ORM\Configuration();
+        $config->setProxyDir(__DIR__ . '/../../Proxies');
+        $config->setProxyNamespace('Doctrine\Tests\Proxies');
+        $eventManager = new EventManager();
+        $conn = new ConnectionMock(array(), $driverMock, $config, $eventManager);
+        $mockDriver = new MetadataDriverMock();
+        $config->setMetadataDriverImpl($metadataDriver);
+
+        return EntityManagerMock::create($conn, $config, $eventManager);
+    }
 }
 
 /* Test subject class with overriden factory method for mocking purposes */