Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #335 from FabioBatSilva/DDC-964

association/attribute override
  • Loading branch information...
commit 0a09a28ec9301b371da54babb076df84a0d2033f 2 parents d5d4722 + fa140d8
Guilherme Blanco authored

Showing 29 changed files with 1,587 additions and 175 deletions. Show diff stats Hide diff stats

  1. 33  doctrine-mapping.xsd
  2. 56  lib/Doctrine/ORM/Mapping/AssociationOverride.php
  3. 41  lib/Doctrine/ORM/Mapping/AssociationOverrides.php
  4. 47  lib/Doctrine/ORM/Mapping/AttributeOverride.php
  5. 41  lib/Doctrine/ORM/Mapping/AttributeOverrides.php
  6. 96  lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
  7. 2  lib/Doctrine/ORM/Mapping/Column.php
  8. 209  lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
  9. 6  lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
  10. 178  lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
  11. 187  lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
  12. 2  lib/Doctrine/ORM/Mapping/JoinTable.php
  13. 22  lib/Doctrine/ORM/Mapping/MappingException.php
  14. 123  tests/Doctrine/Tests/Models/DDC964/DDC964Address.php
  15. 47  tests/Doctrine/Tests/Models/DDC964/DDC964Admin.php
  16. 70  tests/Doctrine/Tests/Models/DDC964/DDC964Group.php
  17. 44  tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php
  18. 155  tests/Doctrine/Tests/Models/DDC964/DDC964User.php
  19. 132  tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
  20. 42  tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
  21. 21  tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Admin.php
  22. 13  tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php
  23. 46  tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php
  24. 27  tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.xml
  25. 18  tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml
  26. 39  tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml
  27. 17  tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.yml
  28. 13  tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml
  29. 35  tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml
33  doctrine-mapping.xsd
@@ -145,6 +145,8 @@
145 145
       <xs:element name="one-to-many" type="orm:one-to-many" minOccurs="0" maxOccurs="unbounded" />
146 146
       <xs:element name="many-to-one" type="orm:many-to-one" minOccurs="0" maxOccurs="unbounded" />
147 147
       <xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded" />
  148
+      <xs:element name="association-overrides" type="orm:association-overrides" minOccurs="0" maxOccurs="unbounded" />
  149
+      <xs:element name="attribute-overrides" type="orm:attribute-overrides" minOccurs="0" maxOccurs="unbounded" />
148 150
       <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
149 151
     </xs:sequence>
150 152
     <xs:attribute name="name" type="xs:string" use="required" />
@@ -483,4 +485,35 @@
483 485
     <xs:anyAttribute namespace="##other"/>
484 486
   </xs:complexType>
485 487
 
  488
+  <xs:complexType name="association-overrides">
  489
+    <xs:sequence>
  490
+      <xs:element name="association-override" type="orm:association-override" minOccurs="1" maxOccurs="unbounded" />
  491
+      <xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
  492
+    </xs:sequence>
  493
+  </xs:complexType>
  494
+
  495
+  <xs:complexType name="association-override">
  496
+    <xs:sequence>
  497
+      <xs:element name="join-table" type="orm:join-table" minOccurs="0" />
  498
+      <xs:element name="join-columns" type="orm:join-columns" minOccurs="0" />
  499
+      <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
  500
+    </xs:sequence>
  501
+    <xs:attribute name="name" type="xs:NMTOKEN" use="required" />
  502
+  </xs:complexType>
  503
+
  504
+  <xs:complexType name="attribute-overrides">
  505
+    <xs:sequence>
  506
+      <xs:element name="attribute-override" type="orm:attribute-override" minOccurs="1" maxOccurs="unbounded" />
  507
+      <xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
  508
+    </xs:sequence>
  509
+  </xs:complexType>
  510
+
  511
+  <xs:complexType name="attribute-override">
  512
+    <xs:sequence>
  513
+      <xs:element name="field" type="orm:field" minOccurs="1" />
  514
+      <xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
  515
+    </xs:sequence>
  516
+    <xs:attribute name="name" type="xs:NMTOKEN" use="required" />
  517
+  </xs:complexType>
  518
+
486 519
 </xs:schema>
56  lib/Doctrine/ORM/Mapping/AssociationOverride.php
... ...
@@ -0,0 +1,56 @@
  1
+<?php
  2
+/*
  3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14
+ *
  15
+ * This software consists of voluntary contributions made by many individuals
  16
+ * and is licensed under the LGPL. For more information, see
  17
+ * <http://www.doctrine-project.org>.
  18
+ */
  19
+
  20
+namespace Doctrine\ORM\Mapping;
  21
+
  22
+/**
  23
+ * This annotation is used to override association mapping of property for an entity relationship.
  24
+ *
  25
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
  26
+ * @since   2.3
  27
+ *
  28
+ * @Annotation
  29
+ * @Target("ANNOTATION")
  30
+ */
  31
+final class AssociationOverride implements Annotation
  32
+{
  33
+
  34
+    /**
  35
+     * The name of the relationship property whose mapping is being overridden
  36
+     * 
  37
+     * @var string 
  38
+     */
  39
+    public $name;
  40
+
  41
+    /**
  42
+     * The join column that is being mapped to the persistent attribute.
  43
+     *
  44
+     * @var array<\Doctrine\ORM\Mapping\JoinColumn>
  45
+     */
  46
+    public $joinColumns;
  47
+
  48
+
  49
+    /**
  50
+     * The join table that maps the relationship.
  51
+     *
  52
+     * @var \Doctrine\ORM\Mapping\JoinTable
  53
+     */
  54
+    public $joinTable;
  55
+
  56
+}
41  lib/Doctrine/ORM/Mapping/AssociationOverrides.php
... ...
@@ -0,0 +1,41 @@
  1
+<?php
  2
+/*
  3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14
+ *
  15
+ * This software consists of voluntary contributions made by many individuals
  16
+ * and is licensed under the LGPL. For more information, see
  17
+ * <http://www.doctrine-project.org>.
  18
+ */
  19
+
  20
+namespace Doctrine\ORM\Mapping;
  21
+
  22
+/**
  23
+ * This annotation is used to override association mappings of relationship properties.
  24
+ *
  25
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
  26
+ * @since   2.3
  27
+ *
  28
+ * @Annotation
  29
+ * @Target("CLASS")
  30
+ */
  31
+final class AssociationOverrides implements Annotation
  32
+{
  33
+
  34
+    /**
  35
+     * Mapping overrides of relationship properties
  36
+     *
  37
+     * @var array<\Doctrine\ORM\Mapping\AssociationOverride> 
  38
+     */
  39
+    public $value;
  40
+
  41
+}
47  lib/Doctrine/ORM/Mapping/AttributeOverride.php
... ...
@@ -0,0 +1,47 @@
  1
+<?php
  2
+/*
  3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14
+ *
  15
+ * This software consists of voluntary contributions made by many individuals
  16
+ * and is licensed under the LGPL. For more information, see
  17
+ * <http://www.doctrine-project.org>.
  18
+ */
  19
+
  20
+namespace Doctrine\ORM\Mapping;
  21
+
  22
+/**
  23
+ * This annotation is used to override the mapping of a entity property.
  24
+ *
  25
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
  26
+ * @since   2.3
  27
+ *
  28
+ * @Annotation
  29
+ * @Target("ANNOTATION")
  30
+ */
  31
+final class AttributeOverride implements Annotation
  32
+{
  33
+
  34
+    /**
  35
+     * The name of the property whose mapping is being overridden.
  36
+     * 
  37
+     * @var string 
  38
+     */
  39
+    public $name;
  40
+
  41
+    /**
  42
+     * The column definition.
  43
+     *
  44
+     * @var \Doctrine\ORM\Mapping\Column
  45
+     */
  46
+    public $column;
  47
+}
41  lib/Doctrine/ORM/Mapping/AttributeOverrides.php
... ...
@@ -0,0 +1,41 @@
  1
+<?php
  2
+/*
  3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14
+ *
  15
+ * This software consists of voluntary contributions made by many individuals
  16
+ * and is licensed under the LGPL. For more information, see
  17
+ * <http://www.doctrine-project.org>.
  18
+ */
  19
+
  20
+namespace Doctrine\ORM\Mapping;
  21
+
  22
+/**
  23
+ * This annotation is used to override the mapping of a entity property.
  24
+ *
  25
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
  26
+ * @since   2.3
  27
+ *
  28
+ * @Annotation
  29
+ * @Target("CLASS")
  30
+ */
  31
+final class AttributeOverrides implements Annotation
  32
+{
  33
+
  34
+    /**
  35
+     * One or more field or property mapping overrides.
  36
+     *
  37
+     * @var array<\Doctrine\ORM\Mapping\AttributeOverride>
  38
+     */
  39
+    public $value;
  40
+
  41
+}
96  lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -571,7 +571,7 @@ class ClassMetadataInfo implements ClassMetadata
571 571
     /**
572 572
      * NamingStrategy determining the default column and table names
573 573
      *
574  
-     * @var \Doctrine\ORM\NamingStrategy
  574
+     * @var \Doctrine\ORM\Mapping\NamingStrategy
575 575
      */
576 576
     protected $namingStrategy;
577 577
 
@@ -1238,7 +1238,7 @@ protected function _validateAndCompleteAssociationMapping(array $mapping)
1238 1238
         $mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
1239 1239
 
1240 1240
         // unset optional indexBy attribute if its empty
1241  
-        if (!isset($mapping['indexBy']) || !$mapping['indexBy']) {
  1241
+        if ( ! isset($mapping['indexBy']) || !$mapping['indexBy']) {
1242 1242
             unset($mapping['indexBy']);
1243 1243
         }
1244 1244
 
@@ -1364,7 +1364,7 @@ protected function _validateAndCompleteOneToOneMapping(array $mapping)
1364 1364
             foreach ($mapping['joinColumns'] as $key => &$joinColumn) {
1365 1365
                 if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
1366 1366
                     if (count($mapping['joinColumns']) == 1) {
1367  
-                        if (! isset($mapping['id']) || ! $mapping['id']) {
  1367
+                        if ( ! isset($mapping['id']) || ! $mapping['id']) {
1368 1368
                             $joinColumn['unique'] = true;
1369 1369
                         }
1370 1370
                     } else {
@@ -1383,7 +1383,7 @@ protected function _validateAndCompleteOneToOneMapping(array $mapping)
1383 1383
             }
1384 1384
 
1385 1385
             if ($uniqueContraintColumns) {
1386  
-                if (!$this->table) {
  1386
+                if ( ! $this->table) {
1387 1387
                     throw new \RuntimeException("ClassMetadataInfo::setTable() has to be called before defining a one to one relationship.");
1388 1388
                 }
1389 1389
                 $this->table['uniqueConstraints'][$mapping['fieldName']."_uniq"] = array(
@@ -1803,6 +1803,90 @@ public function setInheritanceType($type)
1803 1803
     }
1804 1804
 
1805 1805
     /**
  1806
+     * Sets the association to override association mapping of property for an entity relationship.
  1807
+     *
  1808
+     * @param string $fieldName
  1809
+     * @param array $overrideMapping
  1810
+     */
  1811
+    public function setAssociationOverride($fieldName, array $overrideMapping)
  1812
+    {
  1813
+        if ( ! isset($this->associationMappings[$fieldName])) {
  1814
+            throw MappingException::invalidOverrideFieldName($this->name, $fieldName);
  1815
+        }
  1816
+
  1817
+        $mapping = $this->associationMappings[$fieldName];
  1818
+
  1819
+        if (isset($overrideMapping['joinColumns'])) {
  1820
+            $mapping['joinColumns'] = $overrideMapping['joinColumns'];
  1821
+        }
  1822
+
  1823
+        if (isset($overrideMapping['joinTable'])) {
  1824
+            $mapping['joinTable'] = $overrideMapping['joinTable'];
  1825
+        }
  1826
+
  1827
+        $mapping['joinColumnFieldNames']        = null;
  1828
+        $mapping['joinTableColumns']            = null;
  1829
+        $mapping['sourceToTargetKeyColumns']    = null;
  1830
+        $mapping['relationToSourceKeyColumns']  = null;
  1831
+        $mapping['relationToTargetKeyColumns']  = null;
  1832
+        
  1833
+        switch ($mapping['type']) {
  1834
+            case self::ONE_TO_ONE:
  1835
+                $mapping = $this->_validateAndCompleteOneToOneMapping($mapping);
  1836
+                break;
  1837
+            case self::ONE_TO_MANY:
  1838
+                $mapping = $this->_validateAndCompleteOneToManyMapping($mapping);
  1839
+                break;
  1840
+            case self::MANY_TO_ONE:
  1841
+                $mapping = $this->_validateAndCompleteOneToOneMapping($mapping);
  1842
+                break;
  1843
+            case self::MANY_TO_MANY:
  1844
+                $mapping = $this->_validateAndCompleteManyToManyMapping($mapping);
  1845
+                break;
  1846
+        }
  1847
+
  1848
+        $this->associationMappings[$fieldName] = $mapping;
  1849
+    }
  1850
+
  1851
+     /**
  1852
+     * Sets the override for a mapped field.
  1853
+     *
  1854
+     * @param string $fieldName
  1855
+     * @param array $mapping
  1856
+     */
  1857
+    public function setAttributeOverride($fieldName, array $overrideMapping)
  1858
+    {
  1859
+        if ( ! isset($this->fieldMappings[$fieldName])) {
  1860
+            throw MappingException::invalidOverrideFieldName($this->name, $fieldName);
  1861
+        }
  1862
+
  1863
+        $mapping = $this->fieldMappings[$fieldName];
  1864
+
  1865
+        if (isset($mapping['id'])) {
  1866
+            $overrideMapping['id'] = $mapping['id'];
  1867
+        }
  1868
+
  1869
+        if ( ! isset($overrideMapping['type']) || $overrideMapping['type'] === null) {
  1870
+            $overrideMapping['type'] = $mapping['type'];
  1871
+        }
  1872
+
  1873
+        if ( ! isset($overrideMapping['fieldName']) || $overrideMapping['fieldName'] === null) {
  1874
+            $overrideMapping['fieldName'] = $mapping['fieldName'];
  1875
+        }
  1876
+
  1877
+        if ($overrideMapping['type'] !== $mapping['type']) {
  1878
+            throw MappingException::invalidOverrideFieldType($this->name, $fieldName);
  1879
+        }
  1880
+
  1881
+        unset($this->fieldMappings[$fieldName]);
  1882
+        unset($this->fieldNames[$mapping['columnName']]);
  1883
+        unset($this->columnNames[$mapping['fieldName']]);
  1884
+        $this->_validateAndCompleteFieldMapping($overrideMapping);
  1885
+
  1886
+        $this->fieldMappings[$fieldName] = $overrideMapping;
  1887
+    }
  1888
+
  1889
+    /**
1806 1890
      * Checks whether a mapped field is inherited from an entity superclass.
1807 1891
      *
1808 1892
      * @return boolean TRUE if the field is inherited, FALSE otherwise.
@@ -2362,7 +2446,7 @@ public function isAssociationWithSingleJoinColumn($fieldName)
2362 2446
      */
2363 2447
     public function getSingleAssociationJoinColumnName($fieldName)
2364 2448
     {
2365  
-        if (!$this->isAssociationWithSingleJoinColumn($fieldName)) {
  2449
+        if ( ! $this->isAssociationWithSingleJoinColumn($fieldName)) {
2366 2450
             throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName);
2367 2451
         }
2368 2452
         return $this->associationMappings[$fieldName]['joinColumns'][0]['name'];
@@ -2376,7 +2460,7 @@ public function getSingleAssociationJoinColumnName($fieldName)
2376 2460
      */
2377 2461
     public function getSingleAssociationReferencedJoinColumnName($fieldName)
2378 2462
     {
2379  
-        if (!$this->isAssociationWithSingleJoinColumn($fieldName)) {
  2463
+        if ( ! $this->isAssociationWithSingleJoinColumn($fieldName)) {
2380 2464
             throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName);
2381 2465
         }
2382 2466
         return $this->associationMappings[$fieldName]['joinColumns'][0]['referencedColumnName'];
2  lib/Doctrine/ORM/Mapping/Column.php
@@ -21,7 +21,7 @@
21 21
 
22 22
 /**
23 23
  * @Annotation
24  
- * @Target("PROPERTY")
  24
+ * @Target({"PROPERTY","ANNOTATION"})
25 25
  */
26 26
 final class Column implements Annotation
27 27
 {
209  lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -23,7 +23,9 @@
23 23
     Doctrine\Common\Annotations\AnnotationReader,
24 24
     Doctrine\Common\Annotations\AnnotationRegistry,
25 25
     Doctrine\ORM\Mapping\ClassMetadataInfo,
26  
-    Doctrine\ORM\Mapping\MappingException;
  26
+    Doctrine\ORM\Mapping\MappingException,
  27
+    Doctrine\ORM\Mapping\JoinColumn,
  28
+    Doctrine\ORM\Mapping\Column;
27 29
 
28 30
 /**
29 31
  * The AnnotationDriver reads the mapping metadata from docblock annotations.
@@ -134,7 +136,7 @@ public function setFileExtension($fileExtension)
134 136
     public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
135 137
     {
136 138
         $class = $metadata->getReflectionClass();
137  
-        if (!$class) {
  139
+        if ( ! $class) {
138 140
             // this happens when running annotation driver in combination with
139 141
             // static reflection services. This is not the nicest fix
140 142
             $class = new \ReflectionClass($metadata->name);
@@ -260,12 +262,12 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
260 262
         if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
261 263
             $namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
262 264
 
263  
-            if (!is_array($namedQueriesAnnot->value)) {
  265
+            if ( ! is_array($namedQueriesAnnot->value)) {
264 266
                 throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
265 267
             }
266 268
 
267 269
             foreach ($namedQueriesAnnot->value as $namedQuery) {
268  
-                if (!($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
  270
+                if ( ! ($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
269 271
                     throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
270 272
                 }
271 273
                 $metadata->addNamedQuery(array(
@@ -275,6 +277,43 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
275 277
             }
276 278
         }
277 279
 
  280
+        $associationOverrides = array();
  281
+        // Evaluate AssociationOverrides annotation
  282
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
  283
+            $associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
  284
+
  285
+            foreach ($associationOverridesAnnot->value as $associationOverride) {
  286
+                // Check for JoinColummn/JoinColumns annotations
  287
+                if ($associationOverride->joinColumns) {
  288
+                    $joinColumns = array();
  289
+                    foreach ($associationOverride->joinColumns as $joinColumn) {
  290
+                        $joinColumns[] = $this->joinColumnToArray($joinColumn);
  291
+                    }
  292
+                    $associationOverrides[$associationOverride->name]['joinColumns'] = $joinColumns;
  293
+                }
  294
+
  295
+                // Check for JoinTable annotations
  296
+                if ($associationOverride->joinTable) {
  297
+                    $joinTable      = null;
  298
+                    $joinTableAnnot = $associationOverride->joinTable;
  299
+                    $joinTable = array(
  300
+                        'name'      => $joinTableAnnot->name,
  301
+                        'schema'    => $joinTableAnnot->schema
  302
+                    );
  303
+
  304
+                    foreach ($joinTableAnnot->joinColumns as $joinColumn) {
  305
+                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
  306
+                    }
  307
+
  308
+                    foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
  309
+                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
  310
+                    }
  311
+
  312
+                    $associationOverrides[$associationOverride->name]['joinTable'] = $joinTable;
  313
+                }
  314
+            }
  315
+        }
  316
+
278 317
         // Evaluate InheritanceType annotation
279 318
         if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
280 319
             $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
@@ -326,24 +365,10 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
326 365
             $joinColumns = array();
327 366
 
328 367
             if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
329  
-                $joinColumns[] = array(
330  
-                    'name' => $joinColumnAnnot->name,
331  
-                    'referencedColumnName' => $joinColumnAnnot->referencedColumnName,
332  
-                    'unique' => $joinColumnAnnot->unique,
333  
-                    'nullable' => $joinColumnAnnot->nullable,
334  
-                    'onDelete' => $joinColumnAnnot->onDelete,
335  
-                    'columnDefinition' => $joinColumnAnnot->columnDefinition,
336  
-                );
  368
+                $joinColumns[] = $this->joinColumnToArray($joinColumnAnnot);
337 369
             } else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
338 370
                 foreach ($joinColumnsAnnot->value as $joinColumn) {
339  
-                    $joinColumns[] = array(
340  
-                        'name' => $joinColumn->name,
341  
-                        'referencedColumnName' => $joinColumn->referencedColumnName,
342  
-                        'unique' => $joinColumn->unique,
343  
-                        'nullable' => $joinColumn->nullable,
344  
-                        'onDelete' => $joinColumn->onDelete,
345  
-                        'columnDefinition' => $joinColumn->columnDefinition,
346  
-                    );
  371
+                    $joinColumns[] = $this->joinColumnToArray($joinColumn);
347 372
                 }
348 373
             }
349 374
 
@@ -354,23 +379,7 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
354 379
                     throw MappingException::propertyTypeIsRequired($className, $property->getName());
355 380
                 }
356 381
 
357  
-                $mapping['type'] = $columnAnnot->type;
358  
-                $mapping['length'] = $columnAnnot->length;
359  
-                $mapping['precision'] = $columnAnnot->precision;
360  
-                $mapping['scale'] = $columnAnnot->scale;
361  
-                $mapping['nullable'] = $columnAnnot->nullable;
362  
-                $mapping['unique'] = $columnAnnot->unique;
363  
-                if ($columnAnnot->options) {
364  
-                    $mapping['options'] = $columnAnnot->options;
365  
-                }
366  
-
367  
-                if (isset($columnAnnot->name)) {
368  
-                    $mapping['columnName'] = $columnAnnot->name;
369  
-                }
370  
-
371  
-                if (isset($columnAnnot->columnDefinition)) {
372  
-                    $mapping['columnDefinition'] = $columnAnnot->columnDefinition;
373  
-                }
  382
+                $mapping = $this->columnToArray($property->getName(), $columnAnnot);
374 383
 
375 384
                 if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
376 385
                     $mapping['id'] = true;
@@ -447,25 +456,11 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
447 456
                     );
448 457
 
449 458
                     foreach ($joinTableAnnot->joinColumns as $joinColumn) {
450  
-                        $joinTable['joinColumns'][] = array(
451  
-                            'name' => $joinColumn->name,
452  
-                            'referencedColumnName' => $joinColumn->referencedColumnName,
453  
-                            'unique' => $joinColumn->unique,
454  
-                            'nullable' => $joinColumn->nullable,
455  
-                            'onDelete' => $joinColumn->onDelete,
456  
-                            'columnDefinition' => $joinColumn->columnDefinition,
457  
-                        );
  459
+                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
458 460
                     }
459 461
 
460 462
                     foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
461  
-                        $joinTable['inverseJoinColumns'][] = array(
462  
-                            'name' => $joinColumn->name,
463  
-                            'referencedColumnName' => $joinColumn->referencedColumnName,
464  
-                            'unique' => $joinColumn->unique,
465  
-                            'nullable' => $joinColumn->nullable,
466  
-                            'onDelete' => $joinColumn->onDelete,
467  
-                            'columnDefinition' => $joinColumn->columnDefinition,
468  
-                        );
  463
+                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
469 464
                     }
470 465
                 }
471 466
 
@@ -486,6 +481,57 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
486 481
             }
487 482
         }
488 483
 
  484
+        // Evaluate AssociationOverrides annotation
  485
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
  486
+            $associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
  487
+
  488
+            foreach ($associationOverridesAnnot->value as $associationOverride) {
  489
+                $override   = array();
  490
+                $fieldName  = $associationOverride->name;
  491
+
  492
+                // Check for JoinColummn/JoinColumns annotations
  493
+                if ($associationOverride->joinColumns) {
  494
+                    $joinColumns = array();
  495
+                    foreach ($associationOverride->joinColumns as $joinColumn) {
  496
+                        $joinColumns[] = $this->joinColumnToArray($joinColumn);
  497
+                    }
  498
+                    $override['joinColumns'] = $joinColumns;
  499
+                }
  500
+
  501
+                // Check for JoinTable annotations
  502
+                if ($associationOverride->joinTable) {
  503
+                    $joinTable      = null;
  504
+                    $joinTableAnnot = $associationOverride->joinTable;
  505
+                    $joinTable = array(
  506
+                        'name'      => $joinTableAnnot->name,
  507
+                        'schema'    => $joinTableAnnot->schema
  508
+                    );
  509
+
  510
+                    foreach ($joinTableAnnot->joinColumns as $joinColumn) {
  511
+                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
  512
+                    }
  513
+
  514
+                    foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
  515
+                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
  516
+                    }
  517
+
  518
+                    $override['joinTable'] = $joinTable;
  519
+                }
  520
+
  521
+                $metadata->setAssociationOverride($fieldName, $override);
  522
+            }
  523
+        }
  524
+
  525
+         $attributeOverrides = array();
  526
+        // Evaluate AttributeOverrides annotation
  527
+        if (isset($classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'])) {
  528
+            $attributeOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'];
  529
+            foreach ($attributeOverridesAnnot->value as $attributeOverrideAnnot) {
  530
+                $attributeOverride = $this->columnToArray($attributeOverrideAnnot->name, $attributeOverrideAnnot->column);
  531
+                $metadata->setAttributeOverride($attributeOverrideAnnot->name, $attributeOverride);
  532
+            }
  533
+        }
  534
+
489 535
         // Evaluate @HasLifecycleCallbacks annotation
490 536
         if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
491 537
             foreach ($class->getMethods() as $method) {
@@ -574,7 +620,7 @@ public function getAllClassNames()
574 620
             return $this->_classNames;
575 621
         }
576 622
 
577  
-        if (!$this->_paths) {
  623
+        if ( ! $this->_paths) {
578 624
             throw MappingException::pathRequired();
579 625
         }
580 626
 
@@ -629,12 +675,65 @@ public function getAllClassNames()
629 675
      */
630 676
     private function getFetchMode($className, $fetchMode)
631 677
     {
632  
-        if(!defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
  678
+        if( ! defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
633 679
             throw MappingException::invalidFetchMode($className,  $fetchMode);
634 680
         }
635 681
 
636 682
         return constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode);
637 683
     }
  684
+
  685
+    /**
  686
+     * Parse the given JoinColumn as array
  687
+     *
  688
+     * @param   JoinColumn $joinColumn
  689
+     * @return  array
  690
+     */
  691
+    private function joinColumnToArray(JoinColumn $joinColumn)
  692
+    {
  693
+        return array(
  694
+            'name' => $joinColumn->name,
  695
+            'unique' => $joinColumn->unique,
  696
+            'nullable' => $joinColumn->nullable,
  697
+            'onDelete' => $joinColumn->onDelete,
  698
+            'columnDefinition' => $joinColumn->columnDefinition,
  699
+            'referencedColumnName' => $joinColumn->referencedColumnName,
  700
+        );
  701
+    }
  702
+
  703
+    /**
  704
+     * Parse the given Column as array
  705
+     *
  706
+     * @param   string $fieldName
  707
+     * @param   Column $column
  708
+     * @return  array
  709
+     */
  710
+    private function columnToArray($fieldName, Column $column)
  711
+    {
  712
+        $mapping = array(
  713
+            'fieldName' => $fieldName,
  714
+            'type'      => $column->type,
  715
+            'scale'     => $column->scale,
  716
+            'length'    => $column->length,
  717
+            'unique'    => $column->unique,
  718
+            'nullable'  => $column->nullable,
  719
+            'precision' => $column->precision
  720
+        );
  721
+
  722
+        if ($column->options) {
  723
+            $mapping['options'] = $column->options;
  724
+        }
  725
+
  726
+        if (isset($column->name)) {
  727
+            $mapping['columnName'] = $column->name;
  728
+        }
  729
+
  730
+        if (isset($column->columnDefinition)) {
  731
+            $mapping['columnDefinition'] = $column->columnDefinition;
  732
+        }
  733
+
  734
+        return $mapping;
  735
+    }
  736
+
638 737
     /**
639 738
      * Factory method for the Annotation Driver
640 739
      *
6  lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
@@ -59,4 +59,8 @@
59 59
 require_once __DIR__.'/../NamedNativeQuery.php';
60 60
 require_once __DIR__.'/../NamedNativeQueries.php';
61 61
 require_once __DIR__.'/../SqlResultSetMapping.php';
62  
-require_once __DIR__.'/../SqlResultSetMappings.php';
  62
+require_once __DIR__.'/../SqlResultSetMappings.php';
  63
+require_once __DIR__.'/../AssociationOverride.php';
  64
+require_once __DIR__.'/../AssociationOverrides.php';
  65
+require_once __DIR__.'/../AttributeOverride.php';
  66
+require_once __DIR__.'/../AttributeOverrides.php';
178  lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
@@ -50,7 +50,7 @@ class XmlDriver extends AbstractFileDriver
50 50
     public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
51 51
     {
52 52
         $xmlRoot = $this->getElement($className);
53  
-
  53
+        
54 54
         if ($xmlRoot->getName() == 'entity') {
55 55
             if (isset($xmlRoot['repository-class'])) {
56 56
                 $metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
@@ -224,51 +224,8 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
224 224
         // Evaluate <field ...> mappings
225 225
         if (isset($xmlRoot->field)) {
226 226
             foreach ($xmlRoot->field as $fieldMapping) {
227  
-                $mapping = array(
228  
-                    'fieldName' => (string)$fieldMapping['name'],
229  
-                );
230  
-
231  
-                if (isset($fieldMapping['type'])) {
232  
-                    $mapping['type'] = (string)$fieldMapping['type'];
233  
-                }
234  
-
235  
-                if (isset($fieldMapping['column'])) {
236  
-                    $mapping['columnName'] = (string)$fieldMapping['column'];
237  
-                }
238  
-
239  
-                if (isset($fieldMapping['length'])) {
240  
-                    $mapping['length'] = (int)$fieldMapping['length'];
241  
-                }
242  
-
243  
-                if (isset($fieldMapping['precision'])) {
244  
-                    $mapping['precision'] = (int)$fieldMapping['precision'];
245  
-                }
246  
-
247  
-                if (isset($fieldMapping['scale'])) {
248  
-                    $mapping['scale'] = (int)$fieldMapping['scale'];
249  
-                }
250  
-
251  
-                if (isset($fieldMapping['unique'])) {
252  
-                    $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true;
253  
-                }
254  
-
255  
-                if (isset($fieldMapping['nullable'])) {
256  
-                    $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true;
257  
-                }
258  
-
259  
-                if (isset($fieldMapping['version']) && $fieldMapping['version']) {
260  
-                    $metadata->setVersionMapping($mapping);
261  
-                }
262  
-
263  
-                if (isset($fieldMapping['column-definition'])) {
264  
-                    $mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
265  
-                }
266  
-
267  
-                if (isset($fieldMapping->options)) {
268  
-                    $mapping['options'] = $this->_parseOptions($fieldMapping->options->children());
269  
-                }
270  
-
271  
-                $mappings[] = $mapping;
  227
+                $mapping = $this->columnToArray($fieldMapping);
  228
+                $metadata->mapField($mapping);
272 229
             }
273 230
         }
274 231
 
@@ -293,6 +250,10 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
293 250
                 $mapping['type'] = (string)$idElement['type'];
294 251
             }
295 252
 
  253
+            if (isset($idElement['length'])) {
  254
+                $mapping['length'] = (string)$idElement['length'];
  255
+            }
  256
+
296 257
             if (isset($idElement['column'])) {
297 258
                 $mapping['columnName'] = (string)$idElement['column'];
298 259
             }
@@ -353,10 +314,10 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
353 314
                     $joinColumns = array();
354 315
 
355 316
                     if (isset($oneToOneElement->{'join-column'})) {
356  
-                        $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement->{'join-column'});
  317
+                        $joinColumns[] = $this->joinColumnToArray($oneToOneElement->{'join-column'});
357 318
                     } else if (isset($oneToOneElement->{'join-columns'})) {
358 319
                         foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
359  
-                            $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
  320
+                            $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
360 321
                         }
361 322
                     }
362 323
 
@@ -437,10 +398,10 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
437 398
                 $joinColumns = array();
438 399
 
439 400
                 if (isset($manyToOneElement->{'join-column'})) {
440  
-                    $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement->{'join-column'});
  401
+                    $joinColumns[] = $this->joinColumnToArray($manyToOneElement->{'join-column'});
441 402
                 } else if (isset($manyToOneElement->{'join-columns'})) {
442 403
                     foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
443  
-                        $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
  404
+                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
444 405
                     }
445 406
                 }
446 407
 
@@ -487,11 +448,11 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
487 448
                     }
488 449
 
489 450
                     foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
490  
-                        $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
  451
+                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
491 452
                     }
492 453
 
493 454
                     foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
494  
-                        $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
  455
+                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
495 456
                     }
496 457
 
497 458
                     $mapping['joinTable'] = $joinTable;
@@ -519,6 +480,62 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
519 480
             }
520 481
         }
521 482
 
  483
+        // Evaluate association-overrides
  484
+        if (isset($xmlRoot->{'attribute-overrides'})) {
  485
+            foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) {
  486
+                $fieldName = (string) $overrideElement['name'];
  487
+                foreach ($overrideElement->field as $field) {
  488
+                    $mapping = $this->columnToArray($field);
  489
+                    $mapping['fieldName'] = $fieldName;
  490
+                    $metadata->setAttributeOverride($fieldName, $mapping);
  491
+                }
  492
+            }
  493
+        }
  494
+
  495
+        // Evaluate association-overrides
  496
+        if (isset($xmlRoot->{'association-overrides'})) {
  497
+            foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) {
  498
+                $fieldName  = (string) $overrideElement['name'];
  499
+                $override   = array();
  500
+
  501
+                // Check for join-columns
  502
+                if (isset($overrideElement->{'join-columns'})) {
  503
+                    $joinColumns = array();
  504
+                    foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
  505
+                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
  506
+                    }
  507
+                    $override['joinColumns'] = $joinColumns;
  508
+                }
  509
+
  510
+                // Check for join-table
  511
+                if ($overrideElement->{'join-table'}) {
  512
+                    $joinTable          = null;
  513
+                    $joinTableElement   = $overrideElement->{'join-table'};
  514
+
  515
+                    $joinTable = array(
  516
+                        'name'      => (string) $joinTableElement['name'],
  517
+                        'schema'    => (string) $joinTableElement['schema']
  518
+                    );
  519
+
  520
+                    if (isset($joinTableElement->{'join-columns'})) {
  521
+                        foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
  522
+                            $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
  523
+                        }
  524
+                    }
  525
+
  526
+                    if (isset($joinTableElement->{'inverse-join-columns'})) {
  527
+                        foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
  528
+                            $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
  529
+                        }
  530
+                    }
  531
+
  532
+                    $override['joinTable'] = $joinTable;
  533
+                }
  534
+
  535
+                $metadata->setAssociationOverride($fieldName, $override);
  536
+            }
  537
+        }
  538
+
522 539
         // Evaluate <lifecycle-callbacks...>
523 540
         if (isset($xmlRoot->{'lifecycle-callbacks'})) {
524 541
             foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
@@ -563,7 +580,7 @@ private function _parseOptions(SimpleXMLElement $options)
563 580
      * @param $joinColumnElement The XML element.
564 581
      * @return array The mapping array.
565 582
      */
566  
-    private function _getJoinColumnMapping(SimpleXMLElement $joinColumnElement)
  583
+    private function joinColumnToArray(SimpleXMLElement $joinColumnElement)
567 584
     {
568 585
         $joinColumn = array(
569 586
             'name' => (string)$joinColumnElement['name'],
@@ -589,6 +606,61 @@ private function _getJoinColumnMapping(SimpleXMLElement $joinColumnElement)
589 606
         return $joinColumn;
590 607
     }
591 608
 
  609
+     /**
  610
+     * Parse the given field as array
  611
+     *
  612
+     * @param   SimpleXMLElement   $fieldMapping
  613
+     * @return  array
  614
+     */
  615
+    private function columnToArray(SimpleXMLElement $fieldMapping)
  616
+    {
  617
+        $mapping = array(
  618
+            'fieldName' => (string)$fieldMapping['name'],
  619
+        );
  620
+
  621
+        if (isset($fieldMapping['type'])) {
  622
+            $mapping['type'] = (string)$fieldMapping['type'];
  623
+        }
  624
+
  625
+        if (isset($fieldMapping['column'])) {
  626
+            $mapping['columnName'] = (string)$fieldMapping['column'];
  627
+        }
  628
+
  629
+        if (isset($fieldMapping['length'])) {
  630
+            $mapping['length'] = (int)$fieldMapping['length'];
  631
+        }
  632
+
  633
+        if (isset($fieldMapping['precision'])) {
  634
+            $mapping['precision'] = (int)$fieldMapping['precision'];
  635
+        }
  636
+
  637
+        if (isset($fieldMapping['scale'])) {
  638
+            $mapping['scale'] = (int)$fieldMapping['scale'];
  639
+        }
  640
+
  641
+        if (isset($fieldMapping['unique'])) {
  642
+            $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true;
  643
+        }
  644
+
  645
+        if (isset($fieldMapping['nullable'])) {
  646
+            $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true;
  647
+        }
  648
+
  649
+        if (isset($fieldMapping['version']) && $fieldMapping['version']) {
  650
+            $metadata->setVersionMapping($mapping);
  651
+        }
  652
+
  653
+        if (isset($fieldMapping['column-definition'])) {
  654
+            $mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
  655
+        }
  656
+
  657
+        if (isset($fieldMapping->options)) {
  658
+            $mapping['options'] = $this->_parseOptions($fieldMapping->options->children());
  659
+        }
  660
+
  661
+        return $mapping;
  662
+    }
  663
+
592 664
     /**
593 665
      * Gathers a list of cascade options found in the given cascade element.
594 666
      *
187  lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
@@ -277,19 +277,7 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
277 277
         if (isset($element['fields'])) {
278 278
             foreach ($element['fields'] as $name => $fieldMapping) {
279 279
 
280  
-                $mapping = array(
281  
-                    'fieldName' => $name
282  
-                );
283  
-
284  
-                if (isset($fieldMapping['type'])) {
285  
-                    $e = explode('(', $fieldMapping['type']);
286  
-                    $fieldMapping['type'] = $e[0];
287  
-                    $mapping['type']      = $fieldMapping['type'];
288  
-
289  
-                    if (isset($e[1])) {
290  
-                        $fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1);
291  
-                    }
292  
-                }
  280
+                $mapping = $this->columnToArray($name, $fieldMapping);
293 281
 
294 282
                 if (isset($fieldMapping['id'])) {
295 283
                     $mapping['id'] = true;
@@ -298,33 +286,6 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
298 286
                                 . strtoupper($fieldMapping['generator']['strategy'])));
299 287
                     }
300 288
                 }
301  
-                if (isset($fieldMapping['column'])) {
302  
-                    $mapping['columnName'] = $fieldMapping['column'];
303  
-                }
304  
-                if (isset($fieldMapping['length'])) {
305  
-                    $mapping['length'] = $fieldMapping['length'];
306  
-                }
307  
-                if (isset($fieldMapping['precision'])) {
308  
-                    $mapping['precision'] = $fieldMapping['precision'];
309  
-                }
310  
-                if (isset($fieldMapping['scale'])) {
311  
-                    $mapping['scale'] = $fieldMapping['scale'];
312  
-                }
313  
-                if (isset($fieldMapping['unique'])) {
314  
-                    $mapping['unique'] = (bool)$fieldMapping['unique'];
315  
-                }
316  
-                if (isset($fieldMapping['options'])) {
317  
-                    $mapping['options'] = $fieldMapping['options'];
318  
-                }
319  
-                if (isset($fieldMapping['nullable'])) {
320  
-                    $mapping['nullable'] = $fieldMapping['nullable'];
321  
-                }
322  
-                if (isset($fieldMapping['version']) && $fieldMapping['version']) {
323  
-                    $metadata->setVersionMapping($mapping);
324  
-                }
325  
-                if (isset($fieldMapping['columnDefinition'])) {
326  
-                    $mapping['columnDefinition'] = $fieldMapping['columnDefinition'];
327  
-                }
328 289
 
329 290
                 $metadata->mapField($mapping);
330 291
             }
@@ -356,14 +317,14 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
356 317
                     $joinColumns = array();
357 318
 
358 319
                     if (isset($oneToOneElement['joinColumn'])) {
359  
-                        $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement['joinColumn']);
  320
+                        $joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
360 321
                     } else if (isset($oneToOneElement['joinColumns'])) {
361 322
                         foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) {
362  
-                            if (!isset($joinColumnElement['name'])) {
  323
+                            if ( ! isset($joinColumnElement['name'])) {
363 324
                                 $joinColumnElement['name'] = $name;
364 325
                             }
365 326
 
366  
-                            $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
  327
+                            $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
367 328
                         }
368 329
                     }
369 330
 
@@ -438,14 +399,14 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
438 399
                 $joinColumns = array();
439 400
 
440 401
                 if (isset($manyToOneElement['joinColumn'])) {
441  
-                    $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement['joinColumn']);
  402
+                    $joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
442 403
                 } else if (isset($manyToOneElement['joinColumns'])) {
443 404
                     foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) {
444  
-                        if (!isset($joinColumnElement['name'])) {
  405
+                        if ( ! isset($joinColumnElement['name'])) {
445 406
                             $joinColumnElement['name'] = $name;
446 407
                         }
447 408
 
448  
-                        $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
  409
+                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
449 410
                     }
450 411
                 }
451 412
 
@@ -485,19 +446,19 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
485 446
                     }
486 447
 
487 448
                     foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
488  
-                        if (!isset($joinColumnElement['name'])) {
  449
+                        if ( ! isset($joinColumnElement['name'])) {
489 450
                             $joinColumnElement['name'] = $name;
490 451
                         }
491 452
 
492  
-                        $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
  453
+                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
493 454
                     }