diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd
index a51f4906d..e8b2e26b2 100644
--- a/doctrine-mapping.xsd
+++ b/doctrine-mapping.xsd
@@ -146,6 +146,7 @@
+
@@ -500,4 +501,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index b439573ac..81acb8021 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -1238,7 +1238,7 @@ class ClassMetadataInfo implements ClassMetadata
$mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
// unset optional indexBy attribute if its empty
- if (!isset($mapping['indexBy']) || !$mapping['indexBy']) {
+ if ( ! isset($mapping['indexBy']) || !$mapping['indexBy']) {
unset($mapping['indexBy']);
}
@@ -1364,7 +1364,7 @@ class ClassMetadataInfo implements ClassMetadata
foreach ($mapping['joinColumns'] as $key => &$joinColumn) {
if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
if (count($mapping['joinColumns']) == 1) {
- if (! isset($mapping['id']) || ! $mapping['id']) {
+ if ( ! isset($mapping['id']) || ! $mapping['id']) {
$joinColumn['unique'] = true;
}
} else {
@@ -1383,7 +1383,7 @@ class ClassMetadataInfo implements ClassMetadata
}
if ($uniqueContraintColumns) {
- if (!$this->table) {
+ if ( ! $this->table) {
throw new \RuntimeException("ClassMetadataInfo::setTable() has to be called before defining a one to one relationship.");
}
$this->table['uniqueConstraints'][$mapping['fieldName']."_uniq"] = array(
@@ -1810,7 +1810,7 @@ class ClassMetadataInfo implements ClassMetadata
*/
public function setAssociationOverride($fieldName, array $overrideMapping)
{
- if (!isset($this->associationMappings[$fieldName])) {
+ if ( ! isset($this->associationMappings[$fieldName])) {
throw MappingException::invalidOverrideFieldName($this->name, $fieldName);
}
@@ -1848,6 +1848,44 @@ class ClassMetadataInfo implements ClassMetadata
$this->associationMappings[$fieldName] = $mapping;
}
+ /**
+ * Sets the override for a mapped field.
+ *
+ * @param string $fieldName
+ * @param array $mapping
+ */
+ public function setAttributeOverride($fieldName, array $overrideMapping)
+ {
+ if ( ! isset($this->fieldMappings[$fieldName])) {
+ throw MappingException::invalidOverrideFieldName($this->name, $fieldName);
+ }
+
+ $mapping = $this->fieldMappings[$fieldName];
+
+ if (isset($mapping['id'])) {
+ $overrideMapping['id'] = $mapping['id'];
+ }
+
+ if ( ! isset($overrideMapping['type']) || $overrideMapping['type'] === null) {
+ $overrideMapping['type'] = $mapping['type'];
+ }
+
+ if ( ! isset($overrideMapping['fieldName']) || $overrideMapping['fieldName'] === null) {
+ $overrideMapping['fieldName'] = $mapping['fieldName'];
+ }
+
+ if ($overrideMapping['type'] !== $mapping['type']) {
+ throw MappingException::invalidOverrideFieldType($this->name, $fieldName);
+ }
+
+ unset($this->fieldMappings[$fieldName]);
+ unset($this->fieldNames[$mapping['columnName']]);
+ unset($this->columnNames[$mapping['fieldName']]);
+ $this->_validateAndCompleteFieldMapping($overrideMapping);
+
+ $this->fieldMappings[$fieldName] = $overrideMapping;
+ }
+
/**
* Checks whether a mapped field is inherited from an entity superclass.
*
@@ -2408,7 +2446,7 @@ class ClassMetadataInfo implements ClassMetadata
*/
public function getSingleAssociationJoinColumnName($fieldName)
{
- if (!$this->isAssociationWithSingleJoinColumn($fieldName)) {
+ if ( ! $this->isAssociationWithSingleJoinColumn($fieldName)) {
throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName);
}
return $this->associationMappings[$fieldName]['joinColumns'][0]['name'];
@@ -2422,7 +2460,7 @@ class ClassMetadataInfo implements ClassMetadata
*/
public function getSingleAssociationReferencedJoinColumnName($fieldName)
{
- if (!$this->isAssociationWithSingleJoinColumn($fieldName)) {
+ if ( ! $this->isAssociationWithSingleJoinColumn($fieldName)) {
throw MappingException::noSingleAssociationJoinColumnFound($this->name, $fieldName);
}
return $this->associationMappings[$fieldName]['joinColumns'][0]['referencedColumnName'];
diff --git a/lib/Doctrine/ORM/Mapping/Column.php b/lib/Doctrine/ORM/Mapping/Column.php
index 5f7dd7f64..d1c85509b 100644
--- a/lib/Doctrine/ORM/Mapping/Column.php
+++ b/lib/Doctrine/ORM/Mapping/Column.php
@@ -21,7 +21,7 @@ namespace Doctrine\ORM\Mapping;
/**
* @Annotation
- * @Target("PROPERTY")
+ * @Target({"PROPERTY","ANNOTATION"})
*/
final class Column implements Annotation
{
diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
index 053342cf8..9885c43ec 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -24,7 +24,8 @@ use Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationRegistry,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException,
- Doctrine\ORM\Mapping\JoinColumn;
+ Doctrine\ORM\Mapping\JoinColumn,
+ Doctrine\ORM\Mapping\Column;
/**
* The AnnotationDriver reads the mapping metadata from docblock annotations.
@@ -135,7 +136,7 @@ class AnnotationDriver implements Driver
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
$class = $metadata->getReflectionClass();
- if (!$class) {
+ if ( ! $class) {
// this happens when running annotation driver in combination with
// static reflection services. This is not the nicest fix
$class = new \ReflectionClass($metadata->name);
@@ -261,12 +262,12 @@ class AnnotationDriver implements Driver
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
$namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
- if (!is_array($namedQueriesAnnot->value)) {
+ if ( ! is_array($namedQueriesAnnot->value)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
foreach ($namedQueriesAnnot->value as $namedQuery) {
- if (!($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
+ if ( ! ($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
$metadata->addNamedQuery(array(
@@ -378,23 +379,7 @@ class AnnotationDriver implements Driver
throw MappingException::propertyTypeIsRequired($className, $property->getName());
}
- $mapping['type'] = $columnAnnot->type;
- $mapping['length'] = $columnAnnot->length;
- $mapping['precision'] = $columnAnnot->precision;
- $mapping['scale'] = $columnAnnot->scale;
- $mapping['nullable'] = $columnAnnot->nullable;
- $mapping['unique'] = $columnAnnot->unique;
- if ($columnAnnot->options) {
- $mapping['options'] = $columnAnnot->options;
- }
-
- if (isset($columnAnnot->name)) {
- $mapping['columnName'] = $columnAnnot->name;
- }
-
- if (isset($columnAnnot->columnDefinition)) {
- $mapping['columnDefinition'] = $columnAnnot->columnDefinition;
- }
+ $mapping = $this->columnToArray($property->getName(), $columnAnnot);
if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
@@ -537,6 +522,16 @@ class AnnotationDriver implements Driver
}
}
+ $attributeOverrides = array();
+ // Evaluate AttributeOverrides annotation
+ if (isset($classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'])) {
+ $attributeOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'];
+ foreach ($attributeOverridesAnnot->value as $attributeOverrideAnnot) {
+ $attributeOverride = $this->columnToArray($attributeOverrideAnnot->name, $attributeOverrideAnnot->column);
+ $metadata->setAttributeOverride($attributeOverrideAnnot->name, $attributeOverride);
+ }
+ }
+
// Evaluate @HasLifecycleCallbacks annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
foreach ($class->getMethods() as $method) {
@@ -625,7 +620,7 @@ class AnnotationDriver implements Driver
return $this->_classNames;
}
- if (!$this->_paths) {
+ if ( ! $this->_paths) {
throw MappingException::pathRequired();
}
@@ -680,7 +675,7 @@ class AnnotationDriver implements Driver
*/
private function getFetchMode($className, $fetchMode)
{
- if(!defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
+ if( ! defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
throw MappingException::invalidFetchMode($className, $fetchMode);
}
@@ -705,6 +700,40 @@ class AnnotationDriver implements Driver
);
}
+ /**
+ * Parse the given Column as array
+ *
+ * @param string $fieldName
+ * @param Column $column
+ * @return array
+ */
+ private function columnToArray($fieldName, Column $column)
+ {
+ $mapping = array(
+ 'fieldName' => $fieldName,
+ 'type' => $column->type,
+ 'scale' => $column->scale,
+ 'length' => $column->length,
+ 'unique' => $column->unique,
+ 'nullable' => $column->nullable,
+ 'precision' => $column->precision
+ );
+
+ if ($column->options) {
+ $mapping['options'] = $column->options;
+ }
+
+ if (isset($column->name)) {
+ $mapping['columnName'] = $column->name;
+ }
+
+ if (isset($column->columnDefinition)) {
+ $mapping['columnDefinition'] = $column->columnDefinition;
+ }
+
+ return $mapping;
+ }
+
/**
* Factory method for the Annotation Driver
*
diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
index cb911e522..f5a1a32b5 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
@@ -61,4 +61,7 @@ require_once __DIR__.'/../NamedNativeQueries.php';
require_once __DIR__.'/../SqlResultSetMapping.php';
require_once __DIR__.'/../SqlResultSetMappings.php';
require_once __DIR__.'/../AssociationOverride.php';
-require_once __DIR__.'/../AssociationOverrides.php';
\ No newline at end of file
+require_once __DIR__.'/../AssociationOverrides.php';
+require_once __DIR__.'/../AssociationOverrides.php';
+require_once __DIR__.'/../AttributeOverride.php';
+require_once __DIR__.'/../AttributeOverrides.php';
\ No newline at end of file
diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
index 12c50e4a3..bb2dcad99 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
@@ -50,7 +50,7 @@ class XmlDriver extends AbstractFileDriver
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
$xmlRoot = $this->getElement($className);
-
+
if ($xmlRoot->getName() == 'entity') {
if (isset($xmlRoot['repository-class'])) {
$metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
@@ -224,51 +224,8 @@ class XmlDriver extends AbstractFileDriver
// Evaluate mappings
if (isset($xmlRoot->field)) {
foreach ($xmlRoot->field as $fieldMapping) {
- $mapping = array(
- 'fieldName' => (string)$fieldMapping['name'],
- );
-
- if (isset($fieldMapping['type'])) {
- $mapping['type'] = (string)$fieldMapping['type'];
- }
-
- if (isset($fieldMapping['column'])) {
- $mapping['columnName'] = (string)$fieldMapping['column'];
- }
-
- if (isset($fieldMapping['length'])) {
- $mapping['length'] = (int)$fieldMapping['length'];
- }
-
- if (isset($fieldMapping['precision'])) {
- $mapping['precision'] = (int)$fieldMapping['precision'];
- }
-
- if (isset($fieldMapping['scale'])) {
- $mapping['scale'] = (int)$fieldMapping['scale'];
- }
-
- if (isset($fieldMapping['unique'])) {
- $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true;
- }
-
- if (isset($fieldMapping['nullable'])) {
- $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true;
- }
-
- if (isset($fieldMapping['version']) && $fieldMapping['version']) {
- $metadata->setVersionMapping($mapping);
- }
-
- if (isset($fieldMapping['column-definition'])) {
- $mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
- }
-
- if (isset($fieldMapping->options)) {
- $mapping['options'] = $this->_parseOptions($fieldMapping->options->children());
- }
-
- $mappings[] = $mapping;
+ $mapping = $this->columnToArray($fieldMapping);
+ $metadata->mapField($mapping);
}
}
@@ -293,6 +250,10 @@ class XmlDriver extends AbstractFileDriver
$mapping['type'] = (string)$idElement['type'];
}
+ if (isset($idElement['length'])) {
+ $mapping['length'] = (string)$idElement['length'];
+ }
+
if (isset($idElement['column'])) {
$mapping['columnName'] = (string)$idElement['column'];
}
@@ -519,25 +480,37 @@ class XmlDriver extends AbstractFileDriver
}
}
+ // Evaluate association-overrides
+ if (isset($xmlRoot->{'attribute-overrides'})) {
+ foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) {
+ $fieldName = (string) $overrideElement['name'];
+ foreach ($overrideElement->field as $field) {
+ $mapping = $this->columnToArray($field);
+ $mapping['fieldName'] = $fieldName;
+ $metadata->setAttributeOverride($fieldName, $mapping);
+ }
+ }
+ }
+
// Evaluate association-overrides
if (isset($xmlRoot->{'association-overrides'})) {
- foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $associationOverrideElement) {
- $fieldName = (string) $associationOverrideElement['name'];
+ foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) {
+ $fieldName = (string) $overrideElement['name'];
$override = array();
// Check for join-columns
- if (isset($associationOverrideElement->{'join-columns'})) {
+ if (isset($overrideElement->{'join-columns'})) {
$joinColumns = array();
- foreach ($associationOverrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
+ foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinColumns'] = $joinColumns;
}
// Check for join-table
- if ($associationOverrideElement->{'join-table'}) {
+ if ($overrideElement->{'join-table'}) {
$joinTable = null;
- $joinTableElement = $associationOverrideElement->{'join-table'};
+ $joinTableElement = $overrideElement->{'join-table'};
$joinTable = array(
'name' => (string) $joinTableElement['name'],
@@ -633,6 +606,61 @@ class XmlDriver extends AbstractFileDriver
return $joinColumn;
}
+ /**
+ * Parse the given field as array
+ *
+ * @param SimpleXMLElement $fieldMapping
+ * @return array
+ */
+ private function columnToArray(SimpleXMLElement $fieldMapping)
+ {
+ $mapping = array(
+ 'fieldName' => (string)$fieldMapping['name'],
+ );
+
+ if (isset($fieldMapping['type'])) {
+ $mapping['type'] = (string)$fieldMapping['type'];
+ }
+
+ if (isset($fieldMapping['column'])) {
+ $mapping['columnName'] = (string)$fieldMapping['column'];
+ }
+
+ if (isset($fieldMapping['length'])) {
+ $mapping['length'] = (int)$fieldMapping['length'];
+ }
+
+ if (isset($fieldMapping['precision'])) {
+ $mapping['precision'] = (int)$fieldMapping['precision'];
+ }
+
+ if (isset($fieldMapping['scale'])) {
+ $mapping['scale'] = (int)$fieldMapping['scale'];
+ }
+
+ if (isset($fieldMapping['unique'])) {
+ $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true;
+ }
+
+ if (isset($fieldMapping['nullable'])) {
+ $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true;
+ }
+
+ if (isset($fieldMapping['version']) && $fieldMapping['version']) {
+ $metadata->setVersionMapping($mapping);
+ }
+
+ if (isset($fieldMapping['column-definition'])) {
+ $mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
+ }
+
+ if (isset($fieldMapping->options)) {
+ $mapping['options'] = $this->_parseOptions($fieldMapping->options->children());
+ }
+
+ return $mapping;
+ }
+
/**
* Gathers a list of cascade options found in the given cascade element.
*
diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
index d7ec9af70..68ca0b29d 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
@@ -277,19 +277,7 @@ class YamlDriver extends AbstractFileDriver
if (isset($element['fields'])) {
foreach ($element['fields'] as $name => $fieldMapping) {
- $mapping = array(
- 'fieldName' => $name
- );
-
- if (isset($fieldMapping['type'])) {
- $e = explode('(', $fieldMapping['type']);
- $fieldMapping['type'] = $e[0];
- $mapping['type'] = $fieldMapping['type'];
-
- if (isset($e[1])) {
- $fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1);
- }
- }
+ $mapping = $this->columnToArray($name, $fieldMapping);
if (isset($fieldMapping['id'])) {
$mapping['id'] = true;
@@ -298,33 +286,6 @@ class YamlDriver extends AbstractFileDriver
. strtoupper($fieldMapping['generator']['strategy'])));
}
}
- if (isset($fieldMapping['column'])) {
- $mapping['columnName'] = $fieldMapping['column'];
- }
- if (isset($fieldMapping['length'])) {
- $mapping['length'] = $fieldMapping['length'];
- }
- if (isset($fieldMapping['precision'])) {
- $mapping['precision'] = $fieldMapping['precision'];
- }
- if (isset($fieldMapping['scale'])) {
- $mapping['scale'] = $fieldMapping['scale'];
- }
- if (isset($fieldMapping['unique'])) {
- $mapping['unique'] = (bool)$fieldMapping['unique'];
- }
- if (isset($fieldMapping['options'])) {
- $mapping['options'] = $fieldMapping['options'];
- }
- if (isset($fieldMapping['nullable'])) {
- $mapping['nullable'] = $fieldMapping['nullable'];
- }
- if (isset($fieldMapping['version']) && $fieldMapping['version']) {
- $metadata->setVersionMapping($mapping);
- }
- if (isset($fieldMapping['columnDefinition'])) {
- $mapping['columnDefinition'] = $fieldMapping['columnDefinition'];
- }
$metadata->mapField($mapping);
}
@@ -359,7 +320,7 @@ class YamlDriver extends AbstractFileDriver
$joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
} else if (isset($oneToOneElement['joinColumns'])) {
foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
@@ -441,7 +402,7 @@ class YamlDriver extends AbstractFileDriver
$joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
} else if (isset($manyToOneElement['joinColumns'])) {
foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
@@ -485,7 +446,7 @@ class YamlDriver extends AbstractFileDriver
}
foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
@@ -493,7 +454,7 @@ class YamlDriver extends AbstractFileDriver
}
foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
@@ -528,16 +489,16 @@ class YamlDriver extends AbstractFileDriver
}
// Evaluate associationOverride
- if (isset($element['associationOverride'])) {
+ if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {
- foreach ($element['associationOverride'] as $fieldName => $associationOverride) {
+ foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
$override = array();
// Check for joinColumn
- if (isset($associationOverride['joinColumn'])) {
+ if (isset($associationOverrideElement['joinColumn'])) {
$joinColumns = array();
- foreach ($associationOverride['joinColumn'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
@@ -546,9 +507,9 @@ class YamlDriver extends AbstractFileDriver
}
// Check for joinTable
- if (isset($associationOverride['joinTable'])) {
+ if (isset($associationOverrideElement['joinTable'])) {
- $joinTableElement = $associationOverride['joinTable'];
+ $joinTableElement = $associationOverrideElement['joinTable'];
$joinTable = array(
'name' => $joinTableElement['name']
);
@@ -558,7 +519,7 @@ class YamlDriver extends AbstractFileDriver
}
foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
@@ -566,7 +527,7 @@ class YamlDriver extends AbstractFileDriver
}
foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
- if (!isset($joinColumnElement['name'])) {
+ if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
@@ -580,6 +541,15 @@ class YamlDriver extends AbstractFileDriver
}
}
+ // Evaluate associationOverride
+ if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {
+
+ foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
+ $mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
+ $metadata->setAttributeOverride($fieldName, $mapping);
+ }
+ }
+
// Evaluate lifeCycleCallbacks
if (isset($element['lifecycleCallbacks'])) {
foreach ($element['lifecycleCallbacks'] as $type => $methods) {
@@ -631,6 +601,68 @@ class YamlDriver extends AbstractFileDriver
return $joinColumn;
}
+ /**
+ * Parse the given column as array
+ *
+ * @param string $fieldName
+ * @param array $column
+ * @return array
+ */
+ private function columnToArray($fieldName, $column)
+ {
+ $mapping = array(
+ 'fieldName' => $fieldName
+ );
+
+ if (isset($column['type'])) {
+ $params = explode('(', $column['type']);
+ $column['type'] = $params[0];
+ $mapping['type'] = $column['type'];
+
+ if (isset($params[1])) {
+ $column['length'] = substr($params[1], 0, strlen($params[1]) - 1);
+ }
+ }
+
+ if (isset($column['column'])) {
+ $mapping['columnName'] = $column['column'];
+ }
+
+ if (isset($column['length'])) {
+ $mapping['length'] = $column['length'];
+ }
+
+ if (isset($column['precision'])) {
+ $mapping['precision'] = $column['precision'];
+ }
+
+ if (isset($column['scale'])) {
+ $mapping['scale'] = $column['scale'];
+ }
+
+ if (isset($column['unique'])) {
+ $mapping['unique'] = (bool)$column['unique'];
+ }
+
+ if (isset($column['options'])) {
+ $mapping['options'] = $column['options'];
+ }
+
+ if (isset($column['nullable'])) {
+ $mapping['nullable'] = $column['nullable'];
+ }
+
+ if (isset($column['version']) && $column['version']) {
+ $metadata->setVersionMapping($mapping);
+ }
+
+ if (isset($column['columnDefinition'])) {
+ $mapping['columnDefinition'] = $column['columnDefinition'];
+ }
+
+ return $mapping;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php
index f88109f0c..dcf3a7da8 100644
--- a/lib/Doctrine/ORM/Mapping/MappingException.php
+++ b/lib/Doctrine/ORM/Mapping/MappingException.php
@@ -94,6 +94,17 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Invalid field override named '$fieldName' for class '$className'.");
}
+ /**
+ * Exception for invalid property type override.
+ *
+ * @param string $className The entity's name
+ * @param string $fieldName
+ */
+ public static function invalidOverrideFieldType($className, $fieldName)
+ {
+ return new self("The column type of attribute '$fieldName' on class '$className' could not be changed.");
+ }
+
public static function mappingNotFound($className, $fieldName)
{
return new self("No mapping found for field '$fieldName' on class '$className'.");
diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php b/tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php
index 71654a12b..90501187c 100644
--- a/tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php
+++ b/tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php
@@ -6,11 +6,39 @@ use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
+ * @AttributeOverrides({
+ * @AttributeOverride(name="id",
+ * column=@Column(
+ * name = "guest_id",
+ * type = "integer",
+ length = 140
+ * )
+ * ),
+ * @AttributeOverride(name="name",
+ * column=@Column(
+ * name = "guest_name",
+ * nullable = false,
+ * unique = true,
+ length = 240
+ * )
+ * )
+ * })
*/
class DDC964Guest extends DDC964User
{
public static function loadMetadata($metadata)
{
+ $metadata->setAttributeOverride('id', array(
+ 'columnName' => 'guest_id',
+ 'type' => 'integer',
+ 'length' => 140,
+ ));
+ $metadata->setAttributeOverride('name',array(
+ 'columnName' => 'guest_name',
+ 'nullable' => false,
+ 'unique' => true,
+ 'length' => 240,
+ ));
}
}
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964User.php b/tests/Doctrine/Tests/Models/DDC964/DDC964User.php
index 07947e57f..608f42d96 100644
--- a/tests/Doctrine/Tests/Models/DDC964/DDC964User.php
+++ b/tests/Doctrine/Tests/Models/DDC964/DDC964User.php
@@ -11,13 +11,14 @@ class DDC964User
{
/**
+ * @Id
* @GeneratedValue
- * @Id @Column(type="integer")
+ * @Column(type="integer", name="user_id", length=150)
*/
protected $id;
/**
- * @Column
+ * @Column(name="user_name", nullable=true, unique=false, length=250)
*/
protected $name;
@@ -112,11 +113,16 @@ class DDC964User
'id' => true,
'fieldName' => 'id',
'type' => 'integer',
- 'columnName' => 'id',
+ 'columnName' => 'user_id',
+ 'length' => 150,
));
$metadata->mapField(array(
- 'fieldName' => 'name',
- 'type' => 'string',
+ 'fieldName' => 'name',
+ 'type' => 'string',
+ 'columnName'=> 'user_name',
+ 'nullable' => true,
+ 'unique' => false,
+ 'length' => 250,
));
$metadata->mapManyToOne(array(
diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
index 9e1cbde2d..e83a9dbc2 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
@@ -693,6 +693,46 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(array('adminaddress_id'=>'adminaddress_id'), $adminAddress['joinColumnFieldNames']);
$this->assertEquals(array('id'=>'adminaddress_id'), $adminAddress['targetToSourceKeyColumns']);
}
+
+ /**
+ * @group DDC-964
+ */
+ public function testAttributeOverridesMapping()
+ {
+
+ $factory = $this->createClassMetadataFactory();
+ $guestMetadata = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Guest');
+ $adminMetadata = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Admin');
+
+ $this->assertTrue($adminMetadata->fieldMappings['id']['id']);
+ $this->assertEquals('id', $adminMetadata->fieldMappings['id']['fieldName']);
+ $this->assertEquals('user_id', $adminMetadata->fieldMappings['id']['columnName']);
+ $this->assertEquals(array('user_id'=>'id','user_name'=>'name'), $adminMetadata->fieldNames);
+ $this->assertEquals(array('id'=>'user_id','name'=>'user_name'), $adminMetadata->columnNames);
+ $this->assertEquals(150, $adminMetadata->fieldMappings['id']['length']);
+
+
+ $this->assertEquals('name', $adminMetadata->fieldMappings['name']['fieldName']);
+ $this->assertEquals('user_name', $adminMetadata->fieldMappings['name']['columnName']);
+ $this->assertEquals(250, $adminMetadata->fieldMappings['name']['length']);
+ $this->assertTrue($adminMetadata->fieldMappings['name']['nullable']);
+ $this->assertFalse($adminMetadata->fieldMappings['name']['unique']);
+
+
+ $this->assertTrue($guestMetadata->fieldMappings['id']['id']);
+ $this->assertEquals('guest_id', $guestMetadata->fieldMappings['id']['columnName']);
+ $this->assertEquals('id', $guestMetadata->fieldMappings['id']['fieldName']);
+ $this->assertEquals(array('guest_id'=>'id','guest_name'=>'name'), $guestMetadata->fieldNames);
+ $this->assertEquals(array('id'=>'guest_id','name'=>'guest_name'), $guestMetadata->columnNames);
+ $this->assertEquals(140, $guestMetadata->fieldMappings['id']['length']);
+
+ $this->assertEquals('name', $guestMetadata->fieldMappings['name']['fieldName']);
+ $this->assertEquals('guest_name', $guestMetadata->fieldMappings['name']['columnName']);
+ $this->assertEquals(240, $guestMetadata->fieldMappings['name']['length']);
+ $this->assertFalse($guestMetadata->fieldMappings['name']['nullable']);
+ $this->assertTrue($guestMetadata->fieldMappings['name']['unique']);
+ }
+
}
/**
diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
index 61d13f596..26ae1b511 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
@@ -939,7 +939,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
* @expectedException Doctrine\ORM\Mapping\MappingException
* @expectedExceptionMessage Invalid field override named 'invalidPropertyName' for class 'Doctrine\Tests\Models\DDC964\DDC964Admin
*/
- public function testInvalidPropertyOverrideNameException()
+ public function testInvalidPropertyAssociationOverrideNameException()
{
$cm = new ClassMetadata('Doctrine\Tests\Models\DDC964\DDC964Admin');
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
@@ -947,6 +947,34 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$cm->setAssociationOverride('invalidPropertyName', array());
}
+
+ /**
+ * @group DDC-964
+ * @expectedException Doctrine\ORM\Mapping\MappingException
+ * @expectedExceptionMessage Invalid field override named 'invalidPropertyName' for class 'Doctrine\Tests\Models\DDC964\DDC964Guest'.
+ */
+ public function testInvalidPropertyAttributeOverrideNameException()
+ {
+ $cm = new ClassMetadata('Doctrine\Tests\Models\DDC964\DDC964Guest');
+ $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+ $cm->mapField(array('fieldName' => 'name'));
+
+ $cm->setAttributeOverride('invalidPropertyName', array());
+ }
+
+ /**
+ * @group DDC-964
+ * @expectedException Doctrine\ORM\Mapping\MappingException
+ * @expectedExceptionMessage The column type of attribute 'name' on class 'Doctrine\Tests\Models\DDC964\DDC964Guest' could not be changed.
+ */
+ public function testInvalidOverrideAttributeFieldTypeException()
+ {
+ $cm = new ClassMetadata('Doctrine\Tests\Models\DDC964\DDC964Guest');
+ $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+ $cm->mapField(array('fieldName' => 'name', 'type'=>'string'));
+
+ $cm->setAttributeOverride('name', array('type'=>'date'));
+ }
}
class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php
index b3d9bbc7f..5094ecddf 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php
@@ -1 +1,13 @@
setAttributeOverride('id', array(
+ 'columnName' => 'guest_id',
+ 'type' => 'integer',
+ 'length' => 140,
+));
+
+$metadata->setAttributeOverride('name',array(
+ 'columnName' => 'guest_name',
+ 'nullable' => false,
+ 'unique' => true,
+ 'length' => 240,
+));
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php
index a3463d6f9..7b66deef0 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php
@@ -6,11 +6,16 @@ $metadata->mapField(array(
'id' => true,
'fieldName' => 'id',
'type' => 'integer',
- 'columnName' => 'id',
+ 'columnName' => 'user_id',
+ 'length' => 150,
));
$metadata->mapField(array(
- 'fieldName' => 'name',
- 'type' => 'string',
+ 'fieldName' => 'name',
+ 'type' => 'string',
+ 'columnName'=> 'user_name',
+ 'nullable' => true,
+ 'unique' => false,
+ 'length' => 250,
));
$metadata->mapManyToOne(array(
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml
index d3d61d81e..561066f6b 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml
@@ -5,6 +5,14 @@
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml
index 47333f18e..68db74b48 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml
@@ -5,11 +5,11 @@
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
-
+
-
+
diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml
index 7bfae82ff..ec7936f4a 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml
+++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml
@@ -1,2 +1,13 @@
Doctrine\Tests\Models\DDC964\DDC964Guest:
- type: entity
\ No newline at end of file
+ type: entity
+ attributeOverride:
+ id:
+ column: guest_id
+ type: integer
+ length: 140
+ name:
+ column: guest_name
+ type: string
+ length: 240
+ nullable: false
+ unique: true
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml
index 5f91b4053..3a9ebbf9d 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml
+++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml
@@ -3,12 +3,17 @@ Doctrine\Tests\Models\DDC964\DDC964User:
id:
id:
type: integer
- unsigned: true
+ column: user_id
+ length: 150
generator:
strategy: AUTO
fields:
name:
type: string
+ column: user_name
+ length: 250
+ nullable: true
+ unique: false
manyToOne:
address:
targetEntity: DDC964Address