1
0
Fork 0
mirror of synced 2025-04-03 13:23:37 +03:00

fix handling infinite nesting of embeddables

This commit is contained in:
Steve Müller 2014-08-12 07:56:39 +02:00
parent bca9d31531
commit 0768916a06
2 changed files with 84 additions and 4 deletions

View file

@ -64,6 +64,11 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
*/ */
private $evm; private $evm;
/**
* @var array
*/
private $embeddablesActiveNesting = array();
/** /**
* @param EntityManager $em * @param EntityManager $em
*/ */
@ -148,10 +153,12 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
continue; continue;
} }
if ($embeddableClass['class'] === $class->name) { if (isset($this->embeddablesActiveNesting[$embeddableClass['class']])) {
throw MappingException::infiniteEmbeddableNesting($class->name, $property); throw MappingException::infiniteEmbeddableNesting($class->name, $property);
} }
$this->embeddablesActiveNesting[$class->name] = true;
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']); $embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
if ($embeddableMetadata->isEmbeddedClass) { if ($embeddableMetadata->isEmbeddedClass) {
@ -159,6 +166,8 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
} }
$class->inlineEmbeddable($property, $embeddableMetadata); $class->inlineEmbeddable($property, $embeddableMetadata);
unset($this->embeddablesActiveNesting[$class->name]);
} }
} }

View file

@ -223,21 +223,32 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($isFieldMapped); $this->assertTrue($isFieldMapped);
} }
public function testThrowsExceptionOnInfiniteEmbeddableNesting() /**
* @dataProvider getInfiniteEmbeddableNestingData
*/
public function testThrowsExceptionOnInfiniteEmbeddableNesting($embeddableClassName, $declaredEmbeddableClassName)
{ {
$this->setExpectedException( $this->setExpectedException(
'Doctrine\ORM\Mapping\MappingException', 'Doctrine\ORM\Mapping\MappingException',
sprintf( sprintf(
'Infinite nesting detected for embedded property %s::nested. ' . 'Infinite nesting detected for embedded property %s::nested. ' .
'You cannot embed an embeddable from the same type inside an embeddable.', 'You cannot embed an embeddable from the same type inside an embeddable.',
__NAMESPACE__ . '\DDCInfiniteNestingEmbeddable' __NAMESPACE__ . '\\' . $declaredEmbeddableClassName
) )
); );
$this->_schemaTool->createSchema(array( $this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDCInfiniteNestingEmbeddable'), $this->_em->getClassMetadata(__NAMESPACE__ . '\\' . $embeddableClassName),
)); ));
} }
public function getInfiniteEmbeddableNestingData()
{
return array(
array('DDCInfiniteNestingEmbeddable', 'DDCInfiniteNestingEmbeddable'),
array('DDCNestingEmbeddable1', 'DDCNestingEmbeddable4'),
);
}
} }
@ -512,3 +523,63 @@ class DDCInfiniteNestingEmbeddable
/** @Embedded(class="DDCInfiniteNestingEmbeddable") */ /** @Embedded(class="DDCInfiniteNestingEmbeddable") */
public $nested; public $nested;
} }
/**
* @Embeddable
*/
class DDCNestingEmbeddable1
{
/** @Embedded(class="DDC3028Id") */
public $id1;
/** @Embedded(class="DDC3028Id") */
public $id2;
/** @Embedded(class="DDCNestingEmbeddable2") */
public $nested;
}
/**
* @Embeddable
*/
class DDCNestingEmbeddable2
{
/** @Embedded(class="DDC3028Id") */
public $id1;
/** @Embedded(class="DDC3028Id") */
public $id2;
/** @Embedded(class="DDCNestingEmbeddable3") */
public $nested;
}
/**
* @Embeddable
*/
class DDCNestingEmbeddable3
{
/** @Embedded(class="DDC3028Id") */
public $id1;
/** @Embedded(class="DDC3028Id") */
public $id2;
/** @Embedded(class="DDCNestingEmbeddable4") */
public $nested;
}
/**
* @Embeddable
*/
class DDCNestingEmbeddable4
{
/** @Embedded(class="DDC3028Id") */
public $id1;
/** @Embedded(class="DDC3028Id") */
public $id2;
/** @Embedded(class="DDCNestingEmbeddable1") */
public $nested;
}