From 4bec3e2c4965f5b539f5a947562cf71d42921262 Mon Sep 17 00:00:00 2001 From: romanb Date: Fri, 22 Jan 2010 15:10:13 +0000 Subject: [PATCH] [2.0][DDC-263] Fixed. Patch provided by Christian Heinrich. --- .../Common/Collections/Collection.php | 7 ++-- .../ORM/Mapping/AssociationMapping.php | 17 +++++++-- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 25 ++++--------- .../ORM/Mapping/Driver/YamlDriver.php | 37 ++----------------- .../Tests/ORM/Mapping/MappingDriverTest.php | 12 ++++++ .../Doctrine.Tests.ORM.Mapping.User.dcm.xml | 8 +++- .../Doctrine.Tests.ORM.Mapping.User.dcm.yml | 5 ++- tools/sandbox/index.php | 3 +- 8 files changed, 54 insertions(+), 60 deletions(-) diff --git a/lib/Doctrine/Common/Collections/Collection.php b/lib/Doctrine/Common/Collections/Collection.php index 44218fc8a..c97daa09c 100644 --- a/lib/Doctrine/Common/Collections/Collection.php +++ b/lib/Doctrine/Common/Collections/Collection.php @@ -22,7 +22,7 @@ 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, * 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 can be iterated with external iterators, which is preferrable. * 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 * used to iterate over the collection. * @@ -58,8 +58,7 @@ interface Collection extends \Countable, \IteratorAggregate, \ArrayAccess function add($element); /** - * Clears the collection. - * + * Clears the collection, removing all elements. */ function clear(); diff --git a/lib/Doctrine/ORM/Mapping/AssociationMapping.php b/lib/Doctrine/ORM/Mapping/AssociationMapping.php index e958a6d91..dc0f9611a 100644 --- a/lib/Doctrine/ORM/Mapping/AssociationMapping.php +++ b/lib/Doctrine/ORM/Mapping/AssociationMapping.php @@ -167,11 +167,22 @@ abstract class AssociationMapping $this->fetchMode = isset($mapping['fetch']) ? $mapping['fetch'] : self::FETCH_LAZY; $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->isCascadeRefresh = in_array('refresh', $cascades); - $this->isCascadeMerge = in_array('merge', $cascades); - $this->isCascadeDetach = in_array('detach', $cascades); + $this->isCascadeMerge = in_array('merge', $cascades); + $this->isCascadeDetach = in_array('detach', $cascades); } /** diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index a45fa4773..d1dd4e7cb 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -232,7 +232,7 @@ class XmlDriver extends AbstractFileDriver if (isset($oneToOneElement->cascade)) { $mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade); } - + if (isset($oneToOneElement->{'orphan-removal'})) { $mapping['orphanRemoval'] = (bool)$oneToOneElement->{'orphan-removal'}; } @@ -434,23 +434,14 @@ class XmlDriver extends AbstractFileDriver private function _getCascadeMappings($cascadeElement) { $cascades = array(); - - if (isset($cascadeElement->{'cascade-persist'})) { - $cascades[] = 'persist'; + foreach ($cascadeElement->children() as $action) { + // According to the JPA specifications, XML uses "cascade-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; } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index 05a9e7010..f5723a98e 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -247,7 +247,7 @@ class YamlDriver extends AbstractFileDriver } if (isset($oneToOneElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement['cascade']); + $mapping['cascade'] = $oneToOneElement['cascade']; } $metadata->mapOneToOne($mapping); @@ -268,7 +268,7 @@ class YamlDriver extends AbstractFileDriver } if (isset($oneToManyElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement['cascade']); + $mapping['cascade'] = $oneToManyElement['cascade']; } $metadata->mapOneToMany($mapping); @@ -306,7 +306,7 @@ class YamlDriver extends AbstractFileDriver $mapping['joinColumns'] = $joinColumns; if (isset($manyToOneElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement['cascade']); + $mapping['cascade'] = $manyToOneElement['cascade']; } $metadata->mapManyToOne($mapping); @@ -359,7 +359,7 @@ class YamlDriver extends AbstractFileDriver } if (isset($manyToManyElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement['cascade']); + $mapping['cascade'] = $manyToManyElement['cascade']; } $metadata->mapManyToMany($mapping); @@ -411,35 +411,6 @@ class YamlDriver extends AbstractFileDriver 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 * from class/entity names to their corresponding elements. diff --git a/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTest.php index 848f4c54a..cce7c6dbf 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTest.php @@ -67,6 +67,12 @@ class MappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue($class->associationMappings['address'] instanceof \Doctrine\ORM\Mapping\OneToOneMapping); $this->assertTrue(isset($class->associationMappings['address'])); $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(isset($class->associationMappings['phonenumbers'])); @@ -80,6 +86,12 @@ class MappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals(count($class->lifecycleCallbacks), 2); $this->assertEquals($class->lifecycleCallbacks['prePersist'][0], 'doStuffOnPrePersist'); $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); } } diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml index 7e7ba0186..932b8cc3b 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml @@ -20,6 +20,9 @@ + + + @@ -37,8 +40,11 @@ + + + - \ No newline at end of file + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml index 8302f30cb..c29e6c908 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml @@ -16,11 +16,12 @@ Doctrine\Tests\ORM\Mapping\User: joinColumn: name: address_id referencedColumnName: id + cascade: [ remove ] oneToMany: phonenumbers: targetEntity: Phonenumber mappedBy: user - cascade: cascadePersist + cascade: [ persist ] manyToMany: groups: targetEntity: Group @@ -32,6 +33,8 @@ Doctrine\Tests\ORM\Mapping\User: inverseJoinColumns: group_id: referencedColumnName: id + cascade: + - all lifecycleCallbacks: doStuffOnPrePersist: prePersist doStuffOnPostPersist: postPersist \ No newline at end of file diff --git a/tools/sandbox/index.php b/tools/sandbox/index.php index abaef7d2d..ab1f78dd4 100644 --- a/tools/sandbox/index.php +++ b/tools/sandbox/index.php @@ -50,4 +50,5 @@ $em = EntityManager::create($connectionOptions, $config); $user = new User; $address = new Address; -echo 'Hello World!' . PHP_EOL; \ No newline at end of file +echo 'Hello World!' . PHP_EOL; +