add support for nesting embeddables
This commit is contained in:
parent
723529ffff
commit
bca9d31531
@ -142,14 +142,22 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$class->isMappedSuperclass) {
|
if (!$class->isMappedSuperclass) {
|
||||||
|
|
||||||
foreach ($class->embeddedClasses as $property => $embeddableClass) {
|
foreach ($class->embeddedClasses as $property => $embeddableClass) {
|
||||||
|
|
||||||
if (isset($embeddableClass['inherited'])) {
|
if (isset($embeddableClass['inherited'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($embeddableClass['class'] === $class->name) {
|
||||||
|
throw MappingException::infiniteEmbeddableNesting($class->name, $property);
|
||||||
|
}
|
||||||
|
|
||||||
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
|
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
|
||||||
|
|
||||||
|
if ($embeddableMetadata->isEmbeddedClass) {
|
||||||
|
$this->addNestedEmbeddedClasses($embeddableMetadata, $class, $property);
|
||||||
|
}
|
||||||
|
|
||||||
$class->inlineEmbeddable($property, $embeddableMetadata);
|
$class->inlineEmbeddable($property, $embeddableMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,6 +378,34 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds nested embedded classes metadata to a parent class.
|
||||||
|
*
|
||||||
|
* @param ClassMetadata $subClass Sub embedded class metadata to add nested embedded classes metadata from.
|
||||||
|
* @param ClassMetadata $parentClass Parent class to add nested embedded classes metadata to.
|
||||||
|
* @param string $prefix Embedded classes' prefix to use for nested embedded classes field names.
|
||||||
|
*/
|
||||||
|
private function addNestedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass, $prefix)
|
||||||
|
{
|
||||||
|
foreach ($subClass->embeddedClasses as $property => $embeddableClass) {
|
||||||
|
if (isset($embeddableClass['inherited'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
|
||||||
|
|
||||||
|
$parentClass->mapEmbedded(array(
|
||||||
|
'fieldName' => $prefix . '.' . $property,
|
||||||
|
'class' => $embeddableMetadata->name,
|
||||||
|
'columnPrefix' => $embeddableClass['columnPrefix'],
|
||||||
|
'declaredField' => $embeddableClass['declaredField']
|
||||||
|
? $prefix . '.' . $embeddableClass['declaredField']
|
||||||
|
: $prefix,
|
||||||
|
'originalField' => $embeddableClass['originalField'] ?: $property,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds inherited named queries to the subclass mapping.
|
* Adds inherited named queries to the subclass mapping.
|
||||||
*
|
*
|
||||||
|
@ -929,15 +929,31 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
// Restore ReflectionClass and properties
|
// Restore ReflectionClass and properties
|
||||||
$this->reflClass = $reflService->getClass($this->name);
|
$this->reflClass = $reflService->getClass($this->name);
|
||||||
|
|
||||||
|
$parentReflFields = array();
|
||||||
|
|
||||||
|
foreach ($this->embeddedClasses as $property => $embeddedClass) {
|
||||||
|
if (isset($embeddedClass['declaredField'])) {
|
||||||
|
$parentReflFields[$property] = new ReflectionEmbeddedProperty(
|
||||||
|
$parentReflFields[$embeddedClass['declaredField']],
|
||||||
|
$reflService->getAccessibleProperty(
|
||||||
|
$this->embeddedClasses[$embeddedClass['declaredField']]['class'],
|
||||||
|
$embeddedClass['originalField']
|
||||||
|
),
|
||||||
|
$embeddedClass['class']
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentReflFields[$property] = $reflService->getAccessibleProperty($this->name, $property);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->fieldMappings as $field => $mapping) {
|
foreach ($this->fieldMappings as $field => $mapping) {
|
||||||
if (isset($mapping['declaredField'])) {
|
if (isset($mapping['declaredField'])) {
|
||||||
$declaringClass = isset($this->embeddedClasses[$mapping['declaredField']]['declared'])
|
|
||||||
? $this->embeddedClasses[$mapping['declaredField']]['declared'] : $this->name;
|
|
||||||
|
|
||||||
$this->reflFields[$field] = new ReflectionEmbeddedProperty(
|
$this->reflFields[$field] = new ReflectionEmbeddedProperty(
|
||||||
$reflService->getAccessibleProperty($declaringClass, $mapping['declaredField']),
|
$parentReflFields[$mapping['declaredField']],
|
||||||
$reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']]['class'], $mapping['originalField']),
|
$reflService->getAccessibleProperty($mapping['originalClass'], $mapping['originalField']),
|
||||||
$this->embeddedClasses[$mapping['declaredField']]['class']
|
$mapping['originalClass']
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3171,15 +3187,13 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
*/
|
*/
|
||||||
public function mapEmbedded(array $mapping)
|
public function mapEmbedded(array $mapping)
|
||||||
{
|
{
|
||||||
if ($this->isEmbeddedClass) {
|
|
||||||
throw MappingException::noEmbeddablesInEmbeddable($this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertFieldNotMapped($mapping['fieldName']);
|
$this->assertFieldNotMapped($mapping['fieldName']);
|
||||||
|
|
||||||
$this->embeddedClasses[$mapping['fieldName']] = array(
|
$this->embeddedClasses[$mapping['fieldName']] = array(
|
||||||
'class' => $this->fullyQualifiedClassName($mapping['class']),
|
'class' => $this->fullyQualifiedClassName($mapping['class']),
|
||||||
'columnPrefix' => $mapping['columnPrefix'],
|
'columnPrefix' => $mapping['columnPrefix'],
|
||||||
|
'declaredField' => isset($mapping['declaredField']) ? $mapping['declaredField'] : null,
|
||||||
|
'originalField' => isset($mapping['originalField']) ? $mapping['originalField'] : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3192,8 +3206,15 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
public function inlineEmbeddable($property, ClassMetadataInfo $embeddable)
|
public function inlineEmbeddable($property, ClassMetadataInfo $embeddable)
|
||||||
{
|
{
|
||||||
foreach ($embeddable->fieldMappings as $fieldMapping) {
|
foreach ($embeddable->fieldMappings as $fieldMapping) {
|
||||||
$fieldMapping['declaredField'] = $property;
|
$fieldMapping['originalClass'] = isset($fieldMapping['originalClass'])
|
||||||
$fieldMapping['originalField'] = $fieldMapping['fieldName'];
|
? $fieldMapping['originalClass']
|
||||||
|
: $embeddable->name;
|
||||||
|
$fieldMapping['declaredField'] = isset($fieldMapping['declaredField'])
|
||||||
|
? $property . '.' . $fieldMapping['declaredField']
|
||||||
|
: $property;
|
||||||
|
$fieldMapping['originalField'] = isset($fieldMapping['originalField'])
|
||||||
|
? $fieldMapping['originalField']
|
||||||
|
: $fieldMapping['fieldName'];
|
||||||
$fieldMapping['fieldName'] = $property . "." . $fieldMapping['fieldName'];
|
$fieldMapping['fieldName'] = $property . "." . $fieldMapping['fieldName'];
|
||||||
|
|
||||||
if (! empty($this->embeddedClasses[$property]['columnPrefix'])) {
|
if (! empty($this->embeddedClasses[$property]['columnPrefix'])) {
|
||||||
|
@ -782,11 +782,21 @@ class MappingException extends \Doctrine\ORM\ORMException
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function noEmbeddablesInEmbeddable($className)
|
/**
|
||||||
|
* @param string $className
|
||||||
|
* @param string $propertyName
|
||||||
|
*
|
||||||
|
* @return MappingException
|
||||||
|
*/
|
||||||
|
public static function infiniteEmbeddableNesting($className, $propertyName)
|
||||||
{
|
{
|
||||||
return new self(sprintf(
|
return new self(
|
||||||
"You embedded one or more embeddables in embeddable '%s', but this behavior is currently unsupported.",
|
sprintf(
|
||||||
$className
|
'Infinite nesting detected for embedded property %s::%s. ' .
|
||||||
));
|
'You cannot embed an embeddable from the same type inside an embeddable.',
|
||||||
|
$className,
|
||||||
|
$propertyName
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$person->address->street = "United States of Tara Street";
|
$person->address->street = "United States of Tara Street";
|
||||||
$person->address->zip = "12345";
|
$person->address->zip = "12345";
|
||||||
$person->address->city = "funkytown";
|
$person->address->city = "funkytown";
|
||||||
|
$person->address->country = new DDC93Country('Germany');
|
||||||
|
|
||||||
// 1. check saving value objects works
|
// 1. check saving value objects works
|
||||||
$this->_em->persist($person);
|
$this->_em->persist($person);
|
||||||
@ -46,11 +47,14 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals('United States of Tara Street', $person->address->street);
|
$this->assertEquals('United States of Tara Street', $person->address->street);
|
||||||
$this->assertEquals('12345', $person->address->zip);
|
$this->assertEquals('12345', $person->address->zip);
|
||||||
$this->assertEquals('funkytown', $person->address->city);
|
$this->assertEquals('funkytown', $person->address->city);
|
||||||
|
$this->assertInstanceOf(DDC93Country::CLASSNAME, $person->address->country);
|
||||||
|
$this->assertEquals('Germany', $person->address->country->name);
|
||||||
|
|
||||||
// 3. check changing value objects works
|
// 3. check changing value objects works
|
||||||
$person->address->street = "Street";
|
$person->address->street = "Street";
|
||||||
$person->address->zip = "54321";
|
$person->address->zip = "54321";
|
||||||
$person->address->city = "another town";
|
$person->address->city = "another town";
|
||||||
|
$person->address->country->name = "United States of America";
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
|
|
||||||
$this->_em->clear();
|
$this->_em->clear();
|
||||||
@ -60,6 +64,7 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals('Street', $person->address->street);
|
$this->assertEquals('Street', $person->address->street);
|
||||||
$this->assertEquals('54321', $person->address->zip);
|
$this->assertEquals('54321', $person->address->zip);
|
||||||
$this->assertEquals('another town', $person->address->city);
|
$this->assertEquals('another town', $person->address->city);
|
||||||
|
$this->assertEquals('United States of America', $person->address->country->name);
|
||||||
|
|
||||||
// 4. check deleting works
|
// 4. check deleting works
|
||||||
$personId = $person->id;;
|
$personId = $person->id;;
|
||||||
@ -78,6 +83,7 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$person->address->street = "Tree";
|
$person->address->street = "Tree";
|
||||||
$person->address->zip = "12345";
|
$person->address->zip = "12345";
|
||||||
$person->address->city = "funkytown";
|
$person->address->city = "funkytown";
|
||||||
|
$person->address->country = new DDC93Country('United States of America');
|
||||||
|
|
||||||
$this->_em->persist($person);
|
$this->_em->persist($person);
|
||||||
}
|
}
|
||||||
@ -94,6 +100,8 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals('Tree', $person->address->street);
|
$this->assertEquals('Tree', $person->address->street);
|
||||||
$this->assertEquals('12345', $person->address->zip);
|
$this->assertEquals('12345', $person->address->zip);
|
||||||
$this->assertEquals('funkytown', $person->address->city);
|
$this->assertEquals('funkytown', $person->address->city);
|
||||||
|
$this->assertInstanceOf(DDC93Country::CLASSNAME, $person->address->country);
|
||||||
|
$this->assertEquals('United States of America', $person->address->country->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p";
|
$dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p";
|
||||||
@ -103,6 +111,7 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals('Tree', $person['address.street']);
|
$this->assertEquals('Tree', $person['address.street']);
|
||||||
$this->assertEquals('12345', $person['address.zip']);
|
$this->assertEquals('12345', $person['address.zip']);
|
||||||
$this->assertEquals('funkytown', $person['address.city']);
|
$this->assertEquals('funkytown', $person['address.city']);
|
||||||
|
$this->assertEquals('United States of America', $person['address.country.name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,32 +124,41 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->markTestSkipped('SLC does not work with UPDATE/DELETE queries through EM.');
|
$this->markTestSkipped('SLC does not work with UPDATE/DELETE queries through EM.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$person = new DDC93Person('Johannes', new DDC93Address('Moo', '12345', 'Karlsruhe'));
|
$person = new DDC93Person('Johannes', new DDC93Address('Moo', '12345', 'Karlsruhe', new DDC93Country('Germany')));
|
||||||
$this->_em->persist($person);
|
$this->_em->persist($person);
|
||||||
$this->_em->flush($person);
|
$this->_em->flush($person);
|
||||||
|
|
||||||
// SELECT
|
// SELECT
|
||||||
$selectDql = "SELECT p FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.address.city = :city";
|
$selectDql = "SELECT p FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.address.city = :city AND p.address.country.name = :country";
|
||||||
$loadedPerson = $this->_em->createQuery($selectDql)
|
$loadedPerson = $this->_em->createQuery($selectDql)
|
||||||
->setParameter('city', 'Karlsruhe')
|
->setParameter('city', 'Karlsruhe')
|
||||||
|
->setParameter('country', 'Germany')
|
||||||
->getSingleResult();
|
->getSingleResult();
|
||||||
$this->assertEquals($person, $loadedPerson);
|
$this->assertEquals($person, $loadedPerson);
|
||||||
|
|
||||||
$this->assertNull($this->_em->createQuery($selectDql)->setParameter('city', 'asdf')->getOneOrNullResult());
|
$this->assertNull(
|
||||||
|
$this->_em->createQuery($selectDql)
|
||||||
|
->setParameter('city', 'asdf')
|
||||||
|
->setParameter('country', 'Germany')
|
||||||
|
->getOneOrNullResult()
|
||||||
|
);
|
||||||
|
|
||||||
// UPDATE
|
// UPDATE
|
||||||
$updateDql = "UPDATE " . __NAMESPACE__ . "\\DDC93Person p SET p.address.street = :street WHERE p.address.city = :city";
|
$updateDql = "UPDATE " . __NAMESPACE__ . "\\DDC93Person p SET p.address.street = :street, p.address.country.name = :country WHERE p.address.city = :city";
|
||||||
$this->_em->createQuery($updateDql)
|
$this->_em->createQuery($updateDql)
|
||||||
->setParameter('street', 'Boo')
|
->setParameter('street', 'Boo')
|
||||||
|
->setParameter('country', 'DE')
|
||||||
->setParameter('city', 'Karlsruhe')
|
->setParameter('city', 'Karlsruhe')
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$this->_em->refresh($person);
|
$this->_em->refresh($person);
|
||||||
$this->assertEquals('Boo', $person->address->street);
|
$this->assertEquals('Boo', $person->address->street);
|
||||||
|
$this->assertEquals('DE', $person->address->country->name);
|
||||||
|
|
||||||
// DELETE
|
// DELETE
|
||||||
$this->_em->createQuery("DELETE " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.city = :city")
|
$this->_em->createQuery("DELETE " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.city = :city AND p.address.country.name = :country")
|
||||||
->setParameter('city', 'Karlsruhe')
|
->setParameter('city', 'Karlsruhe')
|
||||||
|
->setParameter('country', 'DE')
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$this->_em->clear();
|
$this->_em->clear();
|
||||||
@ -165,43 +183,24 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals($car, $reloadedCar);
|
$this->assertEquals($car, $reloadedCar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEmbeddableWithinEmbeddable()
|
|
||||||
{
|
|
||||||
$this->setExpectedException(
|
|
||||||
'Doctrine\ORM\Mapping\MappingException',
|
|
||||||
sprintf(
|
|
||||||
"You embedded one or more embeddables in embeddable '%s', but this behavior is currently unsupported.",
|
|
||||||
__NAMESPACE__ . '\DDC93ContactInfo'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->_schemaTool->createSchema(array(
|
|
||||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Customer'),
|
|
||||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93ContactInfo'),
|
|
||||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93PhoneNumber')
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testInlineEmbeddableWithPrefix()
|
public function testInlineEmbeddableWithPrefix()
|
||||||
{
|
{
|
||||||
$expectedColumnName = 'foobar_id';
|
$metadata = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonWithPrefix');
|
||||||
|
|
||||||
$actualColumnName = $this->_em
|
$this->assertEquals('foobar_id', $metadata->getColumnName('id.id'));
|
||||||
->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonWithPrefix')
|
$this->assertEquals('bloo_foo_id', $metadata->getColumnName('nested.nestedWithPrefix.id'));
|
||||||
->getColumnName('id.id');
|
$this->assertEquals('bloo_nestedWithEmptyPrefix_id', $metadata->getColumnName('nested.nestedWithEmptyPrefix.id'));
|
||||||
|
$this->assertEquals('bloo_id', $metadata->getColumnName('nested.nestedWithPrefixFalse.id'));
|
||||||
$this->assertEquals($expectedColumnName, $actualColumnName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInlineEmbeddableEmptyPrefix()
|
public function testInlineEmbeddableEmptyPrefix()
|
||||||
{
|
{
|
||||||
$expectedColumnName = 'id_id';
|
$metadata = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonEmptyPrefix');
|
||||||
|
|
||||||
$actualColumnName = $this->_em
|
$this->assertEquals('id_id', $metadata->getColumnName('id.id'));
|
||||||
->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonEmptyPrefix')
|
$this->assertEquals('nested_foo_id', $metadata->getColumnName('nested.nestedWithPrefix.id'));
|
||||||
->getColumnName('id.id');
|
$this->assertEquals('nested_nestedWithEmptyPrefix_id', $metadata->getColumnName('nested.nestedWithEmptyPrefix.id'));
|
||||||
|
$this->assertEquals('nested_id', $metadata->getColumnName('nested.nestedWithPrefixFalse.id'));
|
||||||
$this->assertEquals($expectedColumnName, $actualColumnName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInlineEmbeddablePrefixFalse()
|
public function testInlineEmbeddablePrefixFalse()
|
||||||
@ -223,6 +222,22 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
|
|
||||||
$this->assertTrue($isFieldMapped);
|
$this->assertTrue($isFieldMapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testThrowsExceptionOnInfiniteEmbeddableNesting()
|
||||||
|
{
|
||||||
|
$this->setExpectedException(
|
||||||
|
'Doctrine\ORM\Mapping\MappingException',
|
||||||
|
sprintf(
|
||||||
|
'Infinite nesting detected for embedded property %s::nested. ' .
|
||||||
|
'You cannot embed an embeddable from the same type inside an embeddable.',
|
||||||
|
__NAMESPACE__ . '\DDCInfiniteNestingEmbeddable'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_schemaTool->createSchema(array(
|
||||||
|
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDCInfiniteNestingEmbeddable'),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -297,6 +312,24 @@ class DDC93Car extends DDC93Vehicle
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Embeddable
|
||||||
|
*/
|
||||||
|
class DDC93Country
|
||||||
|
{
|
||||||
|
const CLASSNAME = __CLASS__;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Column(type="string", nullable=true)
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
public function __construct($name = null)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Embeddable
|
* @Embeddable
|
||||||
*/
|
*/
|
||||||
@ -316,12 +349,15 @@ class DDC93Address
|
|||||||
* @Column(type="string")
|
* @Column(type="string")
|
||||||
*/
|
*/
|
||||||
public $city;
|
public $city;
|
||||||
|
/** @Embedded(class = "DDC93Country") */
|
||||||
|
public $country;
|
||||||
|
|
||||||
public function __construct($street = null, $zip = null, $city = null)
|
public function __construct($street = null, $zip = null, $city = null, DDC93Country $country = null)
|
||||||
{
|
{
|
||||||
$this->street = $street;
|
$this->street = $street;
|
||||||
$this->zip = $zip;
|
$this->zip = $zip;
|
||||||
$this->city = $city;
|
$this->city = $city;
|
||||||
|
$this->country = $country;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,8 +374,14 @@ class DDC93Customer
|
|||||||
/** @Embeddable */
|
/** @Embeddable */
|
||||||
class DDC93ContactInfo
|
class DDC93ContactInfo
|
||||||
{
|
{
|
||||||
|
const CLASSNAME = __CLASS__;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Column(type="string")
|
||||||
|
*/
|
||||||
|
public $email;
|
||||||
/** @Embedded(class = "DDC93Address") */
|
/** @Embedded(class = "DDC93Address") */
|
||||||
private $address;
|
public $address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -352,9 +394,13 @@ class DDC3028PersonWithPrefix
|
|||||||
/** @Embedded(class="DDC3028Id", columnPrefix = "foobar_") */
|
/** @Embedded(class="DDC3028Id", columnPrefix = "foobar_") */
|
||||||
public $id;
|
public $id;
|
||||||
|
|
||||||
public function __construct(DDC3028Id $id = null)
|
/** @Embedded(class="DDC3028NestedEmbeddable", columnPrefix = "bloo_") */
|
||||||
|
public $nested;
|
||||||
|
|
||||||
|
public function __construct(DDC3028Id $id = null, DDC3028NestedEmbeddable $nested = null)
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
|
$this->nested = $nested;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,9 +414,13 @@ class DDC3028PersonEmptyPrefix
|
|||||||
/** @Embedded(class="DDC3028Id", columnPrefix = "") */
|
/** @Embedded(class="DDC3028Id", columnPrefix = "") */
|
||||||
public $id;
|
public $id;
|
||||||
|
|
||||||
public function __construct(DDC3028Id $id = null)
|
/** @Embedded(class="DDC3028NestedEmbeddable", columnPrefix = "") */
|
||||||
|
public $nested;
|
||||||
|
|
||||||
|
public function __construct(DDC3028Id $id = null, DDC3028NestedEmbeddable $nested = null)
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
|
$this->nested = $nested;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,6 +458,33 @@ class DDC3028Id
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Embeddable
|
||||||
|
*/
|
||||||
|
class DDC3028NestedEmbeddable
|
||||||
|
{
|
||||||
|
const CLASSNAME = __CLASS__;
|
||||||
|
|
||||||
|
/** @Embedded(class="DDC3028Id", columnPrefix = "foo_") */
|
||||||
|
public $nestedWithPrefix;
|
||||||
|
|
||||||
|
/** @Embedded(class="DDC3028Id", columnPrefix = "") */
|
||||||
|
public $nestedWithEmptyPrefix;
|
||||||
|
|
||||||
|
/** @Embedded(class="DDC3028Id", columnPrefix = false) */
|
||||||
|
public $nestedWithPrefixFalse;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
DDC3028Id $nestedWithPrefix = null,
|
||||||
|
DDC3028Id $nestedWithEmptyPrefix = null,
|
||||||
|
DDC3028Id $nestedWithPrefixFalse = null
|
||||||
|
) {
|
||||||
|
$this->nestedWithPrefix = $nestedWithPrefix;
|
||||||
|
$this->nestedWithEmptyPrefix = $nestedWithEmptyPrefix;
|
||||||
|
$this->nestedWithPrefixFalse = $nestedWithPrefixFalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @MappedSuperclass
|
* @MappedSuperclass
|
||||||
*/
|
*/
|
||||||
@ -426,3 +503,12 @@ abstract class DDC3027Animal
|
|||||||
class DDC3027Dog extends DDC3027Animal
|
class DDC3027Dog extends DDC3027Animal
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Embeddable
|
||||||
|
*/
|
||||||
|
class DDCInfiniteNestingEmbeddable
|
||||||
|
{
|
||||||
|
/** @Embedded(class="DDCInfiniteNestingEmbeddable") */
|
||||||
|
public $nested;
|
||||||
|
}
|
||||||
|
@ -65,7 +65,9 @@ class XmlMappingDriverTest extends AbstractMappingDriverTest
|
|||||||
array(
|
array(
|
||||||
'name' => array(
|
'name' => array(
|
||||||
'class' => 'Doctrine\Tests\Models\ValueObjects\Name',
|
'class' => 'Doctrine\Tests\Models\ValueObjects\Name',
|
||||||
'columnPrefix' => 'nm_'
|
'columnPrefix' => 'nm_',
|
||||||
|
'declaredField' => null,
|
||||||
|
'originalField' => null,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
$class->embeddedClasses
|
$class->embeddedClasses
|
||||||
|
Loading…
x
Reference in New Issue
Block a user