From db31c5810209de5c381a8b4cfe0767832f5f9726 Mon Sep 17 00:00:00 2001 From: Geoffrey Wagner Date: Wed, 8 Jan 2014 17:17:47 -0600 Subject: [PATCH 1/4] Fix Lifecycle Callbacks Remove a bit of code that breaks lifecycle callbacks of parent MappedSuperclasses --- lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index a0f99ad9b..e35921130 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -469,10 +469,6 @@ class AnnotationDriver extends AbstractAnnotationDriver if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { /* @var $method \ReflectionMethod */ foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { - // filter for the declaring class only, callbacks from parents will already be registered. - if ($method->getDeclaringClass()->name !== $class->name) { - continue; - } foreach ($this->getMethodCallbacks($method) as $value) { $metadata->addLifecycleCallback($value[0], $value[1]); From 4772cbfae6364637911dd0ab8cea49c15faba03a Mon Sep 17 00:00:00 2001 From: Geoffrey Wagner Date: Wed, 8 Jan 2014 20:58:50 -0600 Subject: [PATCH 2/4] Add a test addLifecycleCallback now only allows a callback once so we do not hook them twice --- .../ORM/Mapping/ClassMetadataInfo.php | 3 + .../ORM/Mapping/Driver/AnnotationDriver.php | 10 +- .../ORM/Functional/Ticket/DDC2895Test.php | 113 ++++++++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 8a1a6587f..cc73a0e23 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2550,6 +2550,9 @@ class ClassMetadataInfo implements ClassMetadata */ public function addLifecycleCallback($callback, $event) { + if(isset($this->lifecycleCallbacks[$event]) && in_array($callback, $this->lifecycleCallbacks[$event])) + return; + $this->lifecycleCallbacks[$event][] = $callback; } diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index e35921130..78ea05ea6 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -466,11 +466,13 @@ class AnnotationDriver extends AbstractAnnotationDriver } // Evaluate @HasLifecycleCallbacks annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { + if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) + { /* @var $method \ReflectionMethod */ - foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { - - foreach ($this->getMethodCallbacks($method) as $value) { + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) + { + foreach ($this->getMethodCallbacks($method) as $value) + { $metadata->addLifecycleCallback($value[0], $value[1]); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php new file mode 100644 index 000000000..01a6d5c22 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php @@ -0,0 +1,113 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC2895'), + )); + } catch(\Exception $e) { + + } + } + + public function testPostLoadOneToManyInheritance() + { + $cm = $this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC2895'); + + $this->assertEquals( + array( + "prePersist" => array("setLastModifiedPreUpdate"), + "preUpdate" => array("setLastModifiedPreUpdate"), + ), + $cm->lifecycleCallbacks + ); + + $ddc2895 = new DDC2895(); + + $this->_em->persist($ddc2895); + $this->_em->flush(); + $this->_em->clear(); + + /** @var DDC2895 $ddc2895 */ + $ddc2895 = $this->_em->find(get_class($ddc2895), $ddc2895->id); + + $this->assertNotNull($ddc2895->getLastModified()); + + } +} + +/** + * @MappedSuperclass + * @HasLifecycleCallbacks + */ +abstract class AbstractDDC2895 +{ + /** + * @Column(name="last_modified", type="datetimetz", nullable=false) + * @var \DateTime + */ + protected $lastModified; + + /** + * @PrePersist + * @PreUpdate + */ + public function setLastModifiedPreUpdate() + { + $this->setLastModified(new \DateTime()); + } + + /** + * @param \DateTime $lastModified + */ + public function setLastModified( $lastModified ) + { + $this->lastModified = $lastModified; + } + + /** + * @return \DateTime + */ + public function getLastModified() + { + return $this->lastModified; + } +} + +/** + * @Entity + * @HasLifecycleCallbacks + */ +class DDC2895 extends AbstractDDC2895 +{ + /** @Id @GeneratedValue @Column(type="integer") */ + public $id; + + /** + * @param mixed $id + */ + public function setId( $id ) + { + $this->id = $id; + } + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } +} \ No newline at end of file From e9739f85911060a5789336af5efc7e328c8a5bea Mon Sep 17 00:00:00 2001 From: Geoffrey Wagner Date: Thu, 9 Jan 2014 10:48:38 -0600 Subject: [PATCH 3/4] Fix some code standard things --- lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 3 ++- lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 8 ++++---- .../Tests/ORM/Functional/Ticket/DDC2895Test.php | 11 +++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index cc73a0e23..b3c84cdba 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2550,8 +2550,9 @@ class ClassMetadataInfo implements ClassMetadata */ public function addLifecycleCallback($callback, $event) { - if(isset($this->lifecycleCallbacks[$event]) && in_array($callback, $this->lifecycleCallbacks[$event])) + if(isset($this->lifecycleCallbacks[$event]) && in_array($callback, $this->lifecycleCallbacks[$event])) { return; + } $this->lifecycleCallbacks[$event][] = $callback; } diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 78ea05ea6..79feb2479 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -469,10 +469,10 @@ class AnnotationDriver extends AbstractAnnotationDriver if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { /* @var $method \ReflectionMethod */ - foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) - { - foreach ($this->getMethodCallbacks($method) as $value) - { + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method){ + + foreach ($this->getMethodCallbacks($method) as $value) { + $metadata->addLifecycleCallback($value[0], $value[1]); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php index 01a6d5c22..5eece3f9b 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php @@ -1,13 +1,12 @@ Date: Sun, 12 Jan 2014 17:14:32 -0600 Subject: [PATCH 4/4] Fix some code standard things --- lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 79feb2479..76d06d13e 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -466,10 +466,9 @@ class AnnotationDriver extends AbstractAnnotationDriver } // Evaluate @HasLifecycleCallbacks annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) - { + if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { /* @var $method \ReflectionMethod */ - foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method){ + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { foreach ($this->getMethodCallbacks($method) as $value) {