From e7a6d8799071fb33da9c2fcadfe68f829809593a Mon Sep 17 00:00:00 2001 From: Francisco Facioni Date: Thu, 12 Jan 2012 14:38:07 -0300 Subject: [PATCH 1/2] When using a ManyToMany relationship no listener is notified about any change to the owning entity. What I'm doing with this patch is marking the entity for update when there is a modification in the ManyToMany relationship so the listeners are notified about it. The main reason for this is for hooking up services like Solr or other indexers to update the entities even for ManyToMany relationships. --- lib/Doctrine/ORM/UnitOfWork.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 0ebdedcb9..bf491084e 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -620,6 +620,15 @@ class UnitOfWork implements PropertyChangedListener foreach ($class->associationMappings as $field => $assoc) { if (($val = $class->reflFields[$field]->getValue($entity)) !== null) { $this->computeAssociationChanges($assoc, $val); + if (!isset($this->entityChangeSets[$oid]) && + $assoc['isOwningSide'] && + $assoc['type'] == ClassMetadata::MANY_TO_MANY && + $val instanceof PersistentCollection && + $val->isDirty()) { + $this->entityChangeSets[$oid] = array(); + $this->originalEntityData[$oid] = $actualData; + $this->entityUpdates[$oid] = $entity; + } } } } From bab14bfd240e8aa280a0094c700cc01e3f3d5cc8 Mon Sep 17 00:00:00 2001 From: Francisco Facioni Date: Fri, 13 Jan 2012 09:35:27 -0300 Subject: [PATCH 2/2] UnitTest for ManyToMany update notification --- .../ORM/Functional/ManyToManyEventTest.php | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/ManyToManyEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyEventTest.php b/tests/Doctrine/Tests/ORM/Functional/ManyToManyEventTest.php new file mode 100644 index 000000000..47c96b1fe --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ManyToManyEventTest.php @@ -0,0 +1,76 @@ + + */ +class ManyToManyEventTest extends \Doctrine\Tests\OrmFunctionalTestCase +{ + /** + * @var PostUpdateListener + */ + private $listener; + + protected function setUp() + { + $this->useModelSet('cms'); + parent::setUp(); + $this->listener = new PostUpdateListener(); + $evm = $this->_em->getEventManager(); + $evm->addEventListener(Events::postUpdate, $this->listener); + } + + public function testListenerShouldBeNotifiedOnlyWhenUpdating() + { + $user = $this->createNewValidUser(); + $this->_em->persist($user); + $this->_em->flush(); + $this->assertFalse($this->listener->wasNotified); + + $group = new CmsGroup(); + $group->name = "admins"; + $user->addGroup($group); + $this->_em->persist($user); + $this->_em->flush(); + + $this->assertTrue($this->listener->wasNotified); + } + + /** + * @return CmsUser + */ + private function createNewValidUser() + { + $user = new CmsUser(); + $user->username = 'fran6co'; + $user->name = 'Francisco Facioni'; + $group = new CmsGroup(); + $group->name = "users"; + $user->addGroup($group); + return $user; + } +} + +class PostUpdateListener +{ + /** + * @var bool + */ + public $wasNotified = false; + + /** + * @param $args + */ + public function postUpdate($args) + { + $this->wasNotified = true; + } +} + +