Skip to content

Commit

Permalink
adds support & tests for embeddables in inheritance schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
schmittjoh committed Nov 2, 2013
1 parent d4e6618 commit ece62d6
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
21 changes: 20 additions & 1 deletion lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonS
$class->setIdGeneratorType($parent->generatorType);
$this->addInheritedFields($class, $parent);
$this->addInheritedRelations($class, $parent);
$this->addInheritedEmbeddedClasses($class, $parent);
$class->setIdentifier($parent->identifier);
$class->setVersioned($parent->isVersioned);
$class->setVersionField($parent->versionField);
Expand Down Expand Up @@ -141,7 +142,11 @@ protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonS
}

foreach ($class->embeddedClasses as $property => $embeddableClass) {
$embeddableMetadata = $this->getMetadataFor($embeddableClass);
if (isset($embeddableClass['inherited'])) {
continue;
}

$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
$class->inlineEmbeddable($property, $embeddableMetadata);
}

Expand Down Expand Up @@ -343,6 +348,20 @@ private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $p
}
}

private function addInheritedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->embeddedClasses as $field => $embeddedClass) {
if ( ! isset($embeddedClass['inherited']) && ! $parentClass->isMappedSuperclass) {
$embeddedClass['inherited'] = $parentClass->name;
}
if ( ! isset($embeddedClass['declared'])) {
$embeddedClass['declared'] = $parentClass->name;
}

$subClass->embeddedClasses[$field] = $embeddedClass;
}
}

/**
* Adds inherited named queries to the subclass mapping.
*
Expand Down
17 changes: 13 additions & 4 deletions lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -899,10 +899,12 @@ public function wakeupReflection($reflService)

foreach ($this->fieldMappings as $field => $mapping) {
if (isset($mapping['declaredField'])) {
$declaringClass = isset($this->embeddedClasses[$field]['declared']) ? $this->embeddedClasses[$field]['declared'] : $this->name;

$this->reflFields[$field] = new ReflectionEmbeddedProperty(
$reflService->getAccessibleProperty($this->name, $mapping['declaredField']),
$reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']], $mapping['originalField']),
$this->embeddedClasses[$mapping['declaredField']]
$reflService->getAccessibleProperty($declaringClass, $mapping['declaredField']),
$reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']]['class'], $mapping['originalField']),
$this->embeddedClasses[$mapping['declaredField']]['class']
);
continue;
}
Expand Down Expand Up @@ -2110,6 +2112,11 @@ public function isInheritedAssociation($fieldName)
return isset($this->associationMappings[$fieldName]['inherited']);
}

public function isInheritedEmbeddedClass($fieldName)
{
return isset($this->embeddedClasses[$fieldName]['inherited']);
}

/**
* Sets the name of the primary table the class is mapped to.
*
Expand Down Expand Up @@ -3079,7 +3086,9 @@ public function mapEmbedded(array $mapping)
{
$this->assertFieldNotMapped($mapping['fieldName']);

$this->embeddedClasses[$mapping['fieldName']] = $this->fullyQualifiedClassName($mapping['class']);
$this->embeddedClasses[$mapping['fieldName']] = array(
'class' => $this->fullyQualifiedClassName($mapping['class'])
);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
||
$metadata->isInheritedField($property->name)
||
$metadata->isInheritedAssociation($property->name)) {
$metadata->isInheritedAssociation($property->name)
||
$metadata->isInheritedEmbeddedClass($property->name)) {
continue;
}

Expand Down
42 changes: 42 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public function setUp()
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Person'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Address'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Vehicle'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Car'),
));
} catch(\Exception $e) {
}
Expand Down Expand Up @@ -146,6 +148,16 @@ public function testDqlWithNonExistentEmbeddableField()
$this->_em->createQuery("SELECT p FROM " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.asdfasdf IS NULL")
->execute();
}

public function testEmbeddableWithInheritance()
{
$car = new DDC93Car(new DDC93Address('Foo', '12345', 'Asdf'));
$this->_em->persist($car);
$this->_em->flush($car);

$reloadedCar = $this->_em->find(__NAMESPACE__.'\\DDC93Car', $car->id);
$this->assertEquals($car, $reloadedCar);
}
}

/**
Expand All @@ -171,6 +183,36 @@ public function __construct($name = null, DDC93Address $address = null)
}
}

/**
* @Entity
*
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name = "t", type = "string", length = 10)
* @DiscriminatorMap({
* "v" = "Doctrine\Tests\ORM\Functional\DDC93Car",
* })
*/
abstract class DDC93Vehicle
{
/** @Id @GeneratedValue(strategy = "AUTO") @Column(type = "integer") */
public $id;

/** @Embedded(class = "DDC93Address") */
public $address;

public function __construct(DDC93Address $address)
{
$this->address = $address;
}
}

/**
* @Entity
*/
class DDC93Car extends DDC93Vehicle
{
}

/**
* @Embeddable
*/
Expand Down

0 comments on commit ece62d6

Please sign in to comment.