Browse Source

[Tree] Closure: Fix mapping exception thrown when used in conjunction with inheritance

Gustavo Adrian 14 năm trước cách đây
mục cha
commit
f1ba4e9b02

+ 48 - 43
lib/Gedmo/Tree/Strategy/ORM/Closure.php

@@ -61,48 +61,53 @@ class Closure implements Strategy
     {
         $config = $this->listener->getConfiguration($em, $meta->name);
         $closureMetadata = $em->getClassMetadata($config['closure']);
-        // create ancestor mapping
-        $ancestorMapping = array(
-            'fieldName' => 'ancestor',
-            'id' => false,
-            'joinColumns' => array(
-                array(
-                    'name' => 'ancestor',
-                    'referencedColumnName' => 'id',
-                    'unique' => false,
-                    'nullable' => false,
-                    'onDelete' => 'CASCADE',
-                    'onUpdate' => null,
-                    'columnDefinition' => null,
-                )
-            ),
-            'inversedBy' => null,
-            'targetEntity' => $meta->name,
-            'cascade' => null,
-            'fetch' => ClassMetadataInfo::FETCH_LAZY
-        );
-        $closureMetadata->mapManyToOne($ancestorMapping);
-        // create descendant mapping
-        $descendantMapping = array(
-            'fieldName' => 'descendant',
-            'id' => false,
-            'joinColumns' => array(
-                array(
-                    'name' => 'descendant',
-                    'referencedColumnName' => 'id',
-                    'unique' => false,
-                    'nullable' => false,
-                    'onDelete' => 'CASCADE',
-                    'onUpdate' => null,
-                    'columnDefinition' => null,
-                )
-            ),
-            'inversedBy' => null,
-            'targetEntity' => $meta->name,
-            'cascade' => null,
-            'fetch' => ClassMetadataInfo::FETCH_LAZY
-        );
-        $closureMetadata->mapManyToOne($descendantMapping);
+        if (!$closureMetadata->hasAssociation('ancestor')) {
+            // create ancestor mapping
+            $ancestorMapping = array(
+                'fieldName' => 'ancestor',
+                'id' => false,
+                'joinColumns' => array(
+                    array(
+                        'name' => 'ancestor',
+                        'referencedColumnName' => 'id',
+                        'unique' => false,
+                        'nullable' => false,
+                        'onDelete' => 'CASCADE',
+                        'onUpdate' => null,
+                        'columnDefinition' => null,
+                    )
+                ),
+                'inversedBy' => null,
+                'targetEntity' => $meta->name,
+                'cascade' => null,
+                'fetch' => ClassMetadataInfo::FETCH_LAZY
+            );
+            $closureMetadata->mapManyToOne($ancestorMapping);
+        }
+
+        if (!$closureMetadata->hasAssociation('descendant')) {
+            // create descendant mapping
+            $descendantMapping = array(
+                'fieldName' => 'descendant',
+                'id' => false,
+                'joinColumns' => array(
+                    array(
+                        'name' => 'descendant',
+                        'referencedColumnName' => 'id',
+                        'unique' => false,
+                        'nullable' => false,
+                        'onDelete' => 'CASCADE',
+                        'onUpdate' => null,
+                        'columnDefinition' => null,
+                    )
+                ),
+                'inversedBy' => null,
+                'targetEntity' => $meta->name,
+                'cascade' => null,
+                'fetch' => ClassMetadataInfo::FETCH_LAZY
+            );
+            $closureMetadata->mapManyToOne($descendantMapping);
+        }
         // create unique index on ancestor and descendant
         $indexName = substr(strtoupper("IDX_" . md5($closureMetadata->name)), 0, 20);
         $closureMetadata->table['uniqueConstraints'][$indexName] = array(
@@ -110,7 +115,7 @@ class Closure implements Strategy
         );
         // this one may not be very usefull
         $indexName = substr(strtoupper("IDX_" . md5($meta->name . 'depth')), 0, 20);
-        $closureMetadata->table['indexes']['depth_index'] = array(
+        $closureMetadata->table['indexes'][$indexName] = array(
             'columns' => array('depth')
         );
     }

+ 7 - 1
tests/Gedmo/Tree/ClosureTreeTest.php

@@ -21,6 +21,9 @@ class ClosureTreeTest extends BaseTestCaseORM
 {
     const CATEGORY = "Tree\\Fixture\\Closure\\Category";
     const CLOSURE = "Tree\\Fixture\\Closure\\CategoryClosure";
+    const PERSON = "Tree\\Fixture\\Closure\\Person";
+    const USER = "Tree\\Fixture\\Closure\\User";
+    const PERSON_CLOSURE = "Tree\\Fixture\\Closure\\PersonClosure";
 
     protected function setUp()
     {
@@ -205,7 +208,10 @@ class ClosureTreeTest extends BaseTestCaseORM
     {
         return array(
             self::CATEGORY,
-            self::CLOSURE
+            self::CLOSURE,
+            self::PERSON,
+            self::PERSON_CLOSURE,
+            self::USER
         );
     }
 

+ 65 - 0
tests/Gedmo/Tree/Fixture/Closure/Person.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace Tree\Fixture\Closure;
+
+/**
+ * @gedmo:Tree(type="closure")
+ * @gedmo:TreeClosure(class="Tree\Fixture\Closure\PersonClosure")
+ * @Entity(repositoryClass="Gedmo\Tree\Entity\Repository\ClosureTreeRepository")
+ * @InheritanceType("JOINED")
+ * @DiscriminatorColumn(name="discriminator", type="string")
+ * @DiscriminatorMap({
+    "user" = "User"
+    })
+ */
+class Person
+{
+    /**
+     * @Column(name="id", type="integer")
+     * @Id
+     * @GeneratedValue
+     */
+    private $id;
+
+    /**
+     * @Column(name="full_name", type="string", length=64)
+     */
+    private $fullName;
+
+    /**
+     * @gedmo:TreeParent
+     * @JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
+     * @ManyToOne(targetEntity="Person", inversedBy="children", cascade={"persist"})
+     */
+    private $parent;
+
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function setParent(Category $parent = null)
+    {
+        $this->parent = $parent;
+    }
+
+    public function getParent()
+    {
+        return $this->parent;
+    }
+
+    public function addClosure(CategoryClosure $closure)
+    {
+        $this->closures[] = $closure;
+    }
+}

+ 13 - 0
tests/Gedmo/Tree/Fixture/Closure/PersonClosure.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Tree\Fixture\Closure;
+
+use Gedmo\Tree\Entity\AbstractClosure;
+
+/**
+ * @Entity
+ */
+class PersonClosure extends AbstractClosure
+{
+
+}

+ 25 - 0
tests/Gedmo/Tree/Fixture/Closure/User.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace Tree\Fixture\Closure;
+
+/**
+ * @Entity
+ */
+class User extends Person
+{
+    /**
+     * @Column(name="username", type="string", length=64)
+     */
+    private $username;
+
+
+    public function setUsername($username)
+    {
+        $this->username = $username;
+    }
+
+    public function getUsername()
+    {
+        return $this->username;
+    }
+}