[2.0][DDC-263] Fixed. Patch provided by Christian Heinrich.
This commit is contained in:
parent
c4549c4541
commit
4bec3e2c49
8 changed files with 54 additions and 60 deletions
|
@ -22,7 +22,7 @@
|
||||||
namespace Doctrine\Common\Collections;
|
namespace Doctrine\Common\Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The missing (SPL) Collection/Array interface.
|
* The missing (SPL) Collection/Array/OrderedMap interface.
|
||||||
*
|
*
|
||||||
* A Collection resembles the nature of a regular PHP array. That is,
|
* A Collection resembles the nature of a regular PHP array. That is,
|
||||||
* it is essentially an ordered map that can syntactically also be used
|
* it is essentially an ordered map that can syntactically also be used
|
||||||
|
@ -31,7 +31,7 @@ namespace Doctrine\Common\Collections;
|
||||||
* A Collection has an internal iterator just like a PHP array. In addition
|
* A Collection has an internal iterator just like a PHP array. In addition
|
||||||
* a Collection can be iterated with external iterators, which is preferrable.
|
* a Collection can be iterated with external iterators, which is preferrable.
|
||||||
* To use an external iterator simply use the foreach language construct to
|
* To use an external iterator simply use the foreach language construct to
|
||||||
* iterator over the collection (which canns getIterator() internally) or
|
* iterate over the collection (which calls getIterator() internally) or
|
||||||
* explicitly retrieve an iterator though getIterator() which can then be
|
* explicitly retrieve an iterator though getIterator() which can then be
|
||||||
* used to iterate over the collection.
|
* used to iterate over the collection.
|
||||||
*
|
*
|
||||||
|
@ -58,8 +58,7 @@ interface Collection extends \Countable, \IteratorAggregate, \ArrayAccess
|
||||||
function add($element);
|
function add($element);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the collection.
|
* Clears the collection, removing all elements.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
function clear();
|
function clear();
|
||||||
|
|
||||||
|
|
|
@ -167,11 +167,22 @@ abstract class AssociationMapping
|
||||||
$this->fetchMode = isset($mapping['fetch']) ?
|
$this->fetchMode = isset($mapping['fetch']) ?
|
||||||
$mapping['fetch'] : self::FETCH_LAZY;
|
$mapping['fetch'] : self::FETCH_LAZY;
|
||||||
$cascades = isset($mapping['cascade']) ? $mapping['cascade'] : array();
|
$cascades = isset($mapping['cascade']) ? $mapping['cascade'] : array();
|
||||||
$this->isCascadeRemove = in_array('remove', $cascades);
|
|
||||||
|
if (in_array('all', $cascades)) {
|
||||||
|
$cascades = array(
|
||||||
|
'remove',
|
||||||
|
'persist',
|
||||||
|
'refresh',
|
||||||
|
'merge',
|
||||||
|
'detach'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->isCascadeRemove = in_array('remove', $cascades);
|
||||||
$this->isCascadePersist = in_array('persist', $cascades);
|
$this->isCascadePersist = in_array('persist', $cascades);
|
||||||
$this->isCascadeRefresh = in_array('refresh', $cascades);
|
$this->isCascadeRefresh = in_array('refresh', $cascades);
|
||||||
$this->isCascadeMerge = in_array('merge', $cascades);
|
$this->isCascadeMerge = in_array('merge', $cascades);
|
||||||
$this->isCascadeDetach = in_array('detach', $cascades);
|
$this->isCascadeDetach = in_array('detach', $cascades);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -232,7 +232,7 @@ class XmlDriver extends AbstractFileDriver
|
||||||
if (isset($oneToOneElement->cascade)) {
|
if (isset($oneToOneElement->cascade)) {
|
||||||
$mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade);
|
$mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($oneToOneElement->{'orphan-removal'})) {
|
if (isset($oneToOneElement->{'orphan-removal'})) {
|
||||||
$mapping['orphanRemoval'] = (bool)$oneToOneElement->{'orphan-removal'};
|
$mapping['orphanRemoval'] = (bool)$oneToOneElement->{'orphan-removal'};
|
||||||
}
|
}
|
||||||
|
@ -434,23 +434,14 @@ class XmlDriver extends AbstractFileDriver
|
||||||
private function _getCascadeMappings($cascadeElement)
|
private function _getCascadeMappings($cascadeElement)
|
||||||
{
|
{
|
||||||
$cascades = array();
|
$cascades = array();
|
||||||
|
foreach ($cascadeElement->children() as $action) {
|
||||||
if (isset($cascadeElement->{'cascade-persist'})) {
|
// According to the JPA specifications, XML uses "cascade-persist"
|
||||||
$cascades[] = 'persist';
|
// instead of "persist". Here, both variations
|
||||||
|
// are supported because both YAML and Annotation use "persist"
|
||||||
|
// and we want to make sure that this driver doesn't need to know
|
||||||
|
// anything about the supported cascading actions
|
||||||
|
$cascades[] = str_replace('cascade-', '', $action->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($cascadeElement->{'cascade-remove'})) {
|
|
||||||
$cascades[] = 'remove';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($cascadeElement->{'cascade-merge'})) {
|
|
||||||
$cascades[] = 'merge';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($cascadeElement->{'cascade-refresh'})) {
|
|
||||||
$cascades[] = 'refresh';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $cascades;
|
return $cascades;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -247,7 +247,7 @@ class YamlDriver extends AbstractFileDriver
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($oneToOneElement['cascade'])) {
|
if (isset($oneToOneElement['cascade'])) {
|
||||||
$mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement['cascade']);
|
$mapping['cascade'] = $oneToOneElement['cascade'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata->mapOneToOne($mapping);
|
$metadata->mapOneToOne($mapping);
|
||||||
|
@ -268,7 +268,7 @@ class YamlDriver extends AbstractFileDriver
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($oneToManyElement['cascade'])) {
|
if (isset($oneToManyElement['cascade'])) {
|
||||||
$mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement['cascade']);
|
$mapping['cascade'] = $oneToManyElement['cascade'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata->mapOneToMany($mapping);
|
$metadata->mapOneToMany($mapping);
|
||||||
|
@ -306,7 +306,7 @@ class YamlDriver extends AbstractFileDriver
|
||||||
$mapping['joinColumns'] = $joinColumns;
|
$mapping['joinColumns'] = $joinColumns;
|
||||||
|
|
||||||
if (isset($manyToOneElement['cascade'])) {
|
if (isset($manyToOneElement['cascade'])) {
|
||||||
$mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement['cascade']);
|
$mapping['cascade'] = $manyToOneElement['cascade'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata->mapManyToOne($mapping);
|
$metadata->mapManyToOne($mapping);
|
||||||
|
@ -359,7 +359,7 @@ class YamlDriver extends AbstractFileDriver
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($manyToManyElement['cascade'])) {
|
if (isset($manyToManyElement['cascade'])) {
|
||||||
$mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement['cascade']);
|
$mapping['cascade'] = $manyToManyElement['cascade'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata->mapManyToMany($mapping);
|
$metadata->mapManyToMany($mapping);
|
||||||
|
@ -411,35 +411,6 @@ class YamlDriver extends AbstractFileDriver
|
||||||
return $joinColumn;
|
return $joinColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gathers a list of cascade options found in the given cascade element.
|
|
||||||
*
|
|
||||||
* @param $cascadeElement The cascade element.
|
|
||||||
* @return array The list of cascade options.
|
|
||||||
*/
|
|
||||||
private function _getCascadeMappings($cascadeElement)
|
|
||||||
{
|
|
||||||
$cascades = array();
|
|
||||||
|
|
||||||
if (isset($cascadeElement['cascadePersist'])) {
|
|
||||||
$cascades[] = 'persist';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($cascadeElement['cascadeRemove'])) {
|
|
||||||
$cascades[] = 'remove';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($cascadeElement['cascadeMerge'])) {
|
|
||||||
$cascades[] = 'merge';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($cascadeElement['cascadeRefresh'])) {
|
|
||||||
$cascades[] = 'refresh';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $cascades;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a mapping file with the given name and returns a map
|
* Loads a mapping file with the given name and returns a map
|
||||||
* from class/entity names to their corresponding elements.
|
* from class/entity names to their corresponding elements.
|
||||||
|
|
|
@ -67,6 +67,12 @@ class MappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||||
$this->assertTrue($class->associationMappings['address'] instanceof \Doctrine\ORM\Mapping\OneToOneMapping);
|
$this->assertTrue($class->associationMappings['address'] instanceof \Doctrine\ORM\Mapping\OneToOneMapping);
|
||||||
$this->assertTrue(isset($class->associationMappings['address']));
|
$this->assertTrue(isset($class->associationMappings['address']));
|
||||||
$this->assertTrue($class->associationMappings['address']->isOwningSide);
|
$this->assertTrue($class->associationMappings['address']->isOwningSide);
|
||||||
|
// Check cascading
|
||||||
|
$this->assertTrue($class->associationMappings['address']->isCascadeRemove);
|
||||||
|
$this->assertFalse($class->associationMappings['address']->isCascadePersist);
|
||||||
|
$this->assertFalse($class->associationMappings['address']->isCascadeRefresh);
|
||||||
|
$this->assertFalse($class->associationMappings['address']->isCascadeDetach);
|
||||||
|
$this->assertFalse($class->associationMappings['address']->isCascadeMerge);
|
||||||
|
|
||||||
$this->assertTrue($class->associationMappings['phonenumbers'] instanceof \Doctrine\ORM\Mapping\OneToManyMapping);
|
$this->assertTrue($class->associationMappings['phonenumbers'] instanceof \Doctrine\ORM\Mapping\OneToManyMapping);
|
||||||
$this->assertTrue(isset($class->associationMappings['phonenumbers']));
|
$this->assertTrue(isset($class->associationMappings['phonenumbers']));
|
||||||
|
@ -80,6 +86,12 @@ class MappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||||
$this->assertEquals(count($class->lifecycleCallbacks), 2);
|
$this->assertEquals(count($class->lifecycleCallbacks), 2);
|
||||||
$this->assertEquals($class->lifecycleCallbacks['prePersist'][0], 'doStuffOnPrePersist');
|
$this->assertEquals($class->lifecycleCallbacks['prePersist'][0], 'doStuffOnPrePersist');
|
||||||
$this->assertEquals($class->lifecycleCallbacks['postPersist'][0], 'doStuffOnPostPersist');
|
$this->assertEquals($class->lifecycleCallbacks['postPersist'][0], 'doStuffOnPostPersist');
|
||||||
|
// Make sure that cascade-all works as expected
|
||||||
|
$this->assertTrue($class->associationMappings['groups']->isCascadeRemove);
|
||||||
|
$this->assertTrue($class->associationMappings['groups']->isCascadePersist);
|
||||||
|
$this->assertTrue($class->associationMappings['groups']->isCascadeRefresh);
|
||||||
|
$this->assertTrue($class->associationMappings['groups']->isCascadeDetach);
|
||||||
|
$this->assertTrue($class->associationMappings['groups']->isCascadeMerge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
<one-to-one field="address" target-entity="Address">
|
<one-to-one field="address" target-entity="Address">
|
||||||
<join-column name="address_id" referenced-column-name="id"/>
|
<join-column name="address_id" referenced-column-name="id"/>
|
||||||
|
<cascade>
|
||||||
|
<cascade-remove />
|
||||||
|
</cascade>
|
||||||
</one-to-one>
|
</one-to-one>
|
||||||
|
|
||||||
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user">
|
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user">
|
||||||
|
@ -37,8 +40,11 @@
|
||||||
<join-column name="group_id" referenced-column-name="id"/>
|
<join-column name="group_id" referenced-column-name="id"/>
|
||||||
</inverse-join-columns>
|
</inverse-join-columns>
|
||||||
</join-table>
|
</join-table>
|
||||||
|
<cascade>
|
||||||
|
<cascade-all/>
|
||||||
|
</cascade>
|
||||||
</many-to-many>
|
</many-to-many>
|
||||||
|
|
||||||
</entity>
|
</entity>
|
||||||
|
|
||||||
</doctrine-mapping>
|
</doctrine-mapping>
|
||||||
|
|
|
@ -16,11 +16,12 @@ Doctrine\Tests\ORM\Mapping\User:
|
||||||
joinColumn:
|
joinColumn:
|
||||||
name: address_id
|
name: address_id
|
||||||
referencedColumnName: id
|
referencedColumnName: id
|
||||||
|
cascade: [ remove ]
|
||||||
oneToMany:
|
oneToMany:
|
||||||
phonenumbers:
|
phonenumbers:
|
||||||
targetEntity: Phonenumber
|
targetEntity: Phonenumber
|
||||||
mappedBy: user
|
mappedBy: user
|
||||||
cascade: cascadePersist
|
cascade: [ persist ]
|
||||||
manyToMany:
|
manyToMany:
|
||||||
groups:
|
groups:
|
||||||
targetEntity: Group
|
targetEntity: Group
|
||||||
|
@ -32,6 +33,8 @@ Doctrine\Tests\ORM\Mapping\User:
|
||||||
inverseJoinColumns:
|
inverseJoinColumns:
|
||||||
group_id:
|
group_id:
|
||||||
referencedColumnName: id
|
referencedColumnName: id
|
||||||
|
cascade:
|
||||||
|
- all
|
||||||
lifecycleCallbacks:
|
lifecycleCallbacks:
|
||||||
doStuffOnPrePersist: prePersist
|
doStuffOnPrePersist: prePersist
|
||||||
doStuffOnPostPersist: postPersist
|
doStuffOnPostPersist: postPersist
|
|
@ -50,4 +50,5 @@ $em = EntityManager::create($connectionOptions, $config);
|
||||||
$user = new User;
|
$user = new User;
|
||||||
$address = new Address;
|
$address = new Address;
|
||||||
|
|
||||||
echo 'Hello World!' . PHP_EOL;
|
echo 'Hello World!' . PHP_EOL;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue