From 368cf73f892e266fce695bb3e2ab8a75aa603bc9 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 29 Jul 2012 19:10:33 -0300 Subject: [PATCH 01/41] entity listeners mapping --- .../ORM/Mapping/ClassMetadataFactory.php | 6 +- .../ORM/Mapping/ClassMetadataInfo.php | 48 +++++++ .../ORM/Mapping/Driver/AnnotationDriver.php | 122 +++++++++++------- .../Mapping/Driver/DoctrineAnnotations.php | 1 + lib/Doctrine/ORM/Mapping/EntityListeners.php | 41 ++++++ .../Tests/Models/Company/CompanyContract.php | 1 + .../Models/Company/ContractSubscriber.php | 31 +++++ .../EntityListenersDispatcherTest.php | 43 ++++++ 8 files changed, 247 insertions(+), 46 deletions(-) create mode 100644 lib/Doctrine/ORM/Mapping/EntityListeners.php create mode 100644 tests/Doctrine/Tests/Models/Company/ContractSubscriber.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index a259efa84..718105748 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -156,6 +156,10 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory $this->addInheritedSqlResultSetMappings($class, $parent); } + if ($parent && !empty($parent->entityListeners) && empty($class->entityListeners)) { + $class->entityListeners = $parent->entityListeners; + } + $class->setParentClasses($nonSuperclassParents); if ( $class->isRootEntity() && ! $class->isInheritanceTypeNone() && ! $class->discriminatorMap) { @@ -411,7 +415,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory } } - /** + /** * Completes the ID generator mapping. If "auto" is specified we choose the generator * most appropriate for the targeted database platform. * diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index a9dfa9b8c..db4acbb8b 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -26,6 +26,7 @@ use Doctrine\DBAL\Types\Type; use ReflectionClass; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\ClassLoader; +use Doctrine\Common\EventArgs; /** * A ClassMetadata instance holds all the object-relational mapping metadata @@ -436,6 +437,18 @@ class ClassMetadataInfo implements ClassMetadata */ public $lifecycleCallbacks = array(); + /** + * READ-ONLY: The registered entity listeners. + * + * @var array + */ + public $entityListeners = array(); + + /** + * @var array entity listeners instances. + */ + static private $entityListenerInstances = array(); + /** * READ-ONLY: The association mappings of this class. * @@ -2492,6 +2505,41 @@ class ClassMetadataInfo implements ClassMetadata $this->lifecycleCallbacks = $callbacks; } + /** + * Adds a entity listener for entities of this class. + * + * @param string $callback + * @param string $eventName + */ + public function addEntityListener($eventName, $class, $method) + { + $this->entityListeners[$eventName][] = array( + 'class' => $class, + 'method' => $method + ); + } + + /** + * Call the entity listeners. + * + * @param string $eventName The event name. + * @param object $entity An instance of the mapped entity + * @param \Doctrine\Common\EventArgs $arg The Event args + */ + public function dispatchEntityListeners($eventName, $entity, EventArgs $arg) + { + foreach ($this->entityListeners[$eventName] as $listener) { + $class = $listener['class']; + $method = $listener['method']; + + if ( ! isset(self::$entityListenerInstances[$class])) { + self::$entityListenerInstances[$class] = new $class(); + } + + self::$entityListenerInstances[$class]->{$method}($entity, $arg); + } + } + /** * Sets the discriminator column definition. * diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 004b55c5b..f8abdd149 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -25,6 +25,7 @@ use Doctrine\ORM\Mapping\JoinColumn; use Doctrine\ORM\Mapping\Column; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver; +use Doctrine\ORM\Events; /** * The AnnotationDriver reads the mapping metadata from docblock annotations. @@ -415,54 +416,39 @@ class AnnotationDriver extends AbstractAnnotationDriver } } + // Evaluate EntityListeners annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\EntityListeners'])) { + $entityListenersAnnot = $classAnnotations['Doctrine\ORM\Mapping\EntityListeners']; + + foreach ($entityListenersAnnot->value as $listener) { + + if ( ! class_exists($listener)) { + throw new \InvalidArgumentException("Indefined class \"$listener\""); + } + + $listener = new \ReflectionClass($listener); + + foreach ($listener->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + foreach ($this->getMethodCallbacks($method) as $value) { + list($callback, $event) = $value; + $metadata->addEntityListener($event, $listener->name, $callback); + } + } + } + } + // Evaluate @HasLifecycleCallbacks annotation if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { /* @var $method \ReflectionMethod */ - foreach ($class->getMethods() as $method) { + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { // filter for the declaring class only, callbacks from parents will already be registered. - if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) { - $annotations = $this->reader->getMethodAnnotations($method); + if ($method->getDeclaringClass()->name !== $class->name) { + continue; + } - if ($annotations) { - foreach ($annotations as $key => $annot) { - if ( ! is_numeric($key)) { - continue; - } - $annotations[get_class($annot)] = $annot; - } - } - - if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush); - } + foreach ($this->getMethodCallbacks($method) as $value) { + list($callback, $event) = $value; + $metadata->addLifecycleCallback($callback, $event); } } } @@ -488,9 +474,55 @@ class AnnotationDriver extends AbstractAnnotationDriver } /** - * Parses the given JoinColumn as array. + * Parses the given method. * - * @param JoinColumn $joinColumn + * @param \ReflectionMethod $method + * @return array + */ + private function getMethodCallbacks(\ReflectionMethod $method) + { + $callbacks = array(); + $annotations = $this->reader->getMethodAnnotations($method); + + foreach ($annotations as $annot) { + if ($annot instanceof \Doctrine\ORM\Mapping\PrePersist) { + $callbacks[] = array($method->name, Events::prePersist); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PostPersist) { + $callbacks[] = array($method->name, Events::postPersist); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PreUpdate) { + $callbacks[] = array($method->name, Events::preUpdate); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PostUpdate) { + $callbacks[] = array($method->name, Events::postUpdate); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PreRemove) { + $callbacks[] = array($method->name, Events::preRemove); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PostRemove) { + $callbacks[] = array($method->name, Events::postRemove); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PostLoad) { + $callbacks[] = array($method->name, Events::postLoad); + } + + if ($annot instanceof \Doctrine\ORM\Mapping\PreFlush) { + $callbacks[] = array($method->name, Events::preFlush); + } + } + + return $callbacks; + } + + /** + * Parse the given JoinColumn as array * * @return array */ diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php index 04bf2dedc..dc577d5c0 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php +++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php @@ -64,3 +64,4 @@ require_once __DIR__.'/../AssociationOverride.php'; require_once __DIR__.'/../AssociationOverrides.php'; require_once __DIR__.'/../AttributeOverride.php'; require_once __DIR__.'/../AttributeOverrides.php'; +require_once __DIR__.'/../EntityListeners.php'; diff --git a/lib/Doctrine/ORM/Mapping/EntityListeners.php b/lib/Doctrine/ORM/Mapping/EntityListeners.php new file mode 100644 index 000000000..3d08b2dc3 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/EntityListeners.php @@ -0,0 +1,41 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * The EntityListeners annotation specifies the callback listener classes to be used for an entity or mapped superclass. + * The EntityListeners annotation may be applied to an entity class or mapped superclass. + * + * @author Fabio B. Silva + * @since 2.4 + * + * @Annotation + * @Target("CLASS") + */ +final class EntityListeners implements Annotation +{ + /** + * Specifies the names of the entity listeners. + * + * @var array + */ + public $value; +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContract.php b/tests/Doctrine/Tests/Models/Company/CompanyContract.php index bc8503dfe..71aa6f060 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyContract.php @@ -7,6 +7,7 @@ namespace Doctrine\Tests\Models\Company; * @Table(name="company_contracts") * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") + * @EntityListeners({"Doctrine\Tests\Models\Company\ContractSubscriber"}) * @DiscriminatorMap({ * "fix" = "CompanyFixContract", * "flexible" = "CompanyFlexContract", diff --git a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php new file mode 100644 index 000000000..e6557c0fc --- /dev/null +++ b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php @@ -0,0 +1,31 @@ +_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyFixContract'); + $fixClass = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyFlexContract'); + + $this->assertNull(ContractSubscriber::$instances); + $this->assertNull(ContractSubscriber::$prePersistCalls); + $this->assertNull(ContractSubscriber::$postPersisCalls); + + $fix = new CompanyFixContract(); + $fixArg = new LifecycleEventArgs($fix, $this->_em); + + $flex = new CompanyFlexContract(); + $flexArg = new LifecycleEventArgs($fix, $this->_em); + + $fixClass->dispatchEntityListeners(Events::prePersist, $fix, $fixArg); + $flexClass->dispatchEntityListeners(Events::prePersist, $flex, $flexArg); + + $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); + $this->assertSame($fixArg, ContractSubscriber::$prePersistCalls[0][1]); + + $this->assertCount(1, ContractSubscriber::$instances); + $this->assertNull(ContractSubscriber::$postPersisCalls); + } +} \ No newline at end of file From 0f081d7c4525b51f577a753173f7ba9dd00350b6 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 29 Jul 2012 20:47:31 -0300 Subject: [PATCH 02/41] support short class name --- .../ORM/Mapping/ClassMetadataInfo.php | 42 +++++++++---------- .../ORM/Mapping/Driver/AnnotationDriver.php | 11 ++--- .../Tests/Models/Company/CompanyContract.php | 2 +- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index db4acbb8b..642da6701 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1326,10 +1326,7 @@ class ClassMetadataInfo implements ClassMetadata $mapping['sourceEntity'] = $this->name; if (isset($mapping['targetEntity'])) { - if (strlen($this->namespace) > 0 && strpos($mapping['targetEntity'], '\\') === false) { - $mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity']; - } - + $mapping['targetEntity'] = $this->fullyQualifiedClassName($mapping['targetEntity']); $mapping['targetEntity'] = ltrim($mapping['targetEntity'], '\\'); } @@ -1917,11 +1914,7 @@ class ClassMetadataInfo implements ClassMetadata public function setSubclasses(array $subclasses) { foreach ($subclasses as $subclass) { - if (strpos($subclass, '\\') === false && strlen($this->namespace)) { - $this->subClasses[] = $this->namespace . '\\' . $subclass; - } else { - $this->subClasses[] = $subclass; - } + $this->subClasses[] = $this->fullyQualifiedClassName($subclass); } } @@ -2274,11 +2267,9 @@ class ClassMetadataInfo implements ClassMetadata $queryMapping['isSelfClass'] = true; $queryMapping['resultClass'] = $this->name; - - } else if (strlen($this->namespace) > 0 && strpos($queryMapping['resultClass'], '\\') === false) { - $queryMapping['resultClass'] = $this->namespace . '\\' . $queryMapping['resultClass']; } + $queryMapping['resultClass'] = $this->fullyQualifiedClassName($queryMapping['resultClass']); $queryMapping['resultClass'] = ltrim($queryMapping['resultClass'], '\\'); } @@ -2317,10 +2308,9 @@ class ClassMetadataInfo implements ClassMetadata $entityResult['isSelfClass'] = true; $entityResult['entityClass'] = $this->name; - } else if (strlen($this->namespace) > 0 && strpos($entityResult['entityClass'], '\\') === false) { - $entityResult['entityClass'] = $this->namespace . '\\' . $entityResult['entityClass']; } + $entityResult['entityClass'] = $this->fullyQualifiedClassName($entityResult['entityClass']); $resultMapping['entities'][$key]['entityClass'] = ltrim($entityResult['entityClass'], '\\'); $resultMapping['entities'][$key]['isSelfClass'] = $entityResult['isSelfClass']; @@ -2432,11 +2422,7 @@ class ClassMetadataInfo implements ClassMetadata */ public function setCustomRepositoryClass($repositoryClassName) { - if ($repositoryClassName !== null && strpos($repositoryClassName, '\\') === false - && strlen($this->namespace) > 0) { - $repositoryClassName = $this->namespace . '\\' . $repositoryClassName; - } - $this->customRepositoryClassName = $repositoryClassName; + $this->customRepositoryClassName = $this->fullyQualifiedClassName($repositoryClassName); } /** @@ -2605,10 +2591,7 @@ class ClassMetadataInfo implements ClassMetadata */ public function addDiscriminatorMapClass($name, $className) { - if (strlen($this->namespace) > 0 && strpos($className, '\\') === false) { - $className = $this->namespace . '\\' . $className; - } - + $className = $this->fullyQualifiedClassName($className); $className = ltrim($className, '\\'); $this->discriminatorMap[$name] = $className; @@ -3030,4 +3013,17 @@ class ClassMetadataInfo implements ClassMetadata } return $relations; } + + /** + * @param string $className + * @return string + */ + public function fullyQualifiedClassName($className) + { + if ($className !== null && strpos($className, '\\') === false && strlen($this->namespace) > 0) { + return $this->namespace . '\\' . $className; + } + + return $className; + } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index f8abdd149..139795752 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -385,9 +385,8 @@ class AnnotationDriver extends AbstractAnnotationDriver // Check for JoinTable annotations if ($associationOverride->joinTable) { - $joinTable = null; $joinTableAnnot = $associationOverride->joinTable; - $joinTable = array( + $joinTable = array( 'name' => $joinTableAnnot->name, 'schema' => $joinTableAnnot->schema ); @@ -421,17 +420,16 @@ class AnnotationDriver extends AbstractAnnotationDriver $entityListenersAnnot = $classAnnotations['Doctrine\ORM\Mapping\EntityListeners']; foreach ($entityListenersAnnot->value as $listener) { + $listener = $metadata->fullyQualifiedClassName($listener); if ( ! class_exists($listener)) { throw new \InvalidArgumentException("Indefined class \"$listener\""); } $listener = new \ReflectionClass($listener); - foreach ($listener->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { foreach ($this->getMethodCallbacks($method) as $value) { - list($callback, $event) = $value; - $metadata->addEntityListener($event, $listener->name, $callback); + $metadata->addEntityListener($value[1], $listener->name, $value[0]); } } } @@ -447,8 +445,7 @@ class AnnotationDriver extends AbstractAnnotationDriver } foreach ($this->getMethodCallbacks($method) as $value) { - list($callback, $event) = $value; - $metadata->addLifecycleCallback($callback, $event); + $metadata->addLifecycleCallback($value[0], $value[1]); } } } diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContract.php b/tests/Doctrine/Tests/Models/Company/CompanyContract.php index 71aa6f060..b218d8f86 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyContract.php @@ -7,7 +7,7 @@ namespace Doctrine\Tests\Models\Company; * @Table(name="company_contracts") * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") - * @EntityListeners({"Doctrine\Tests\Models\Company\ContractSubscriber"}) + * @EntityListeners({"ContractSubscriber"}) * @DiscriminatorMap({ * "fix" = "CompanyFixContract", * "flexible" = "CompanyFlexContract", From 3c223a59c407610db94b1d5ad16916b72eabdd5c Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 29 Jul 2012 21:04:59 -0300 Subject: [PATCH 03/41] move call listeners tests to AbstractMappingDriverTest --- .../ORM/Mapping/Driver/AnnotationDriver.php | 2 + .../ORM/Mapping/AbstractMappingDriverTest.php | 45 +++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 139795752..eaad6576b 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -427,7 +427,9 @@ class AnnotationDriver extends AbstractAnnotationDriver } $listener = new \ReflectionClass($listener); + /* @var $method \ReflectionMethod */ foreach ($listener->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + // find method callbacks. foreach ($this->getMethodCallbacks($method) as $value) { $metadata->addEntityListener($value[1], $listener->name, $value[0]); } diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index f752c292e..4cf8c669c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -2,10 +2,14 @@ namespace Doctrine\Tests\ORM\Mapping; -use Doctrine\ORM\Mapping\ClassMetadata, - Doctrine\ORM\Mapping\ClassMetadataInfo, - Doctrine\ORM\Mapping\Driver\XmlDriver, - Doctrine\ORM\Mapping\Driver\YamlDriver; +use Doctrine\ORM\Events; +use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\Tests\Models\Company\CompanyFixContract; +use Doctrine\Tests\Models\Company\CompanyFlexContract; +use Doctrine\Tests\Models\Company\ContractSubscriber; + +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadataInfo; require_once __DIR__ . '/../../TestInit.php'; @@ -748,6 +752,39 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue($guestMetadata->fieldMappings['name']['unique']); } + /** + * @group DDC-1955 + */ + public function testCallEntityListeners() + { + if ( ! ($this instanceof AnnotationDriverTest)) { + $this->markTestIncomplete(); + } + + $em = $this->_getTestEntityManager(); + $factory = $this->createClassMetadataFactory($em); + $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); + $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); + + ContractSubscriber::$prePersistCalls = null; + ContractSubscriber::$postPersisCalls = null; + + $fix = new CompanyFixContract(); + $fixArg = new LifecycleEventArgs($fix, $em); + + $flex = new CompanyFlexContract(); + $flexArg = new LifecycleEventArgs($fix, $em); + + $fixClass->dispatchEntityListeners(Events::prePersist, $fix, $fixArg); + $flexClass->dispatchEntityListeners(Events::prePersist, $flex, $flexArg); + + $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); + $this->assertSame($fixArg, ContractSubscriber::$prePersistCalls[0][1]); + + $this->assertCount(1, ContractSubscriber::$instances); + $this->assertNull(ContractSubscriber::$postPersisCalls); + } + } /** From c5d59ab4c797ac079da1169799ac8729ff259335 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 29 Jul 2012 21:46:38 -0300 Subject: [PATCH 04/41] test entity listener metadata --- .../Company/CompanyFlexUltraContract.php | 1 + .../Models/Company/ContractSubscriber.php | 4 +- .../Company/FlexUltraContractSubscriber.php | 33 +++++++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 58 +++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php index b9ad3d4c9..ce76821a6 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php @@ -4,6 +4,7 @@ namespace Doctrine\Tests\Models\Company; /** * @Entity + * @EntityListeners({"ContractSubscriber","FlexUltraContractSubscriber"}) */ class CompanyFlexUltraContract extends CompanyFlexContract { diff --git a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php index e6557c0fc..2a7d7c76a 100644 --- a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php +++ b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php @@ -16,7 +16,7 @@ class ContractSubscriber /** * @PostPersist */ - public function postPersist(CompanyContract $contract) + public function postPersistHandler(CompanyContract $contract) { self::$postPersisCalls[] = func_get_args(); } @@ -24,7 +24,7 @@ class ContractSubscriber /** * @PrePersist */ - public function prePersist(CompanyContract $contract) + public function prePersistHandler(CompanyContract $contract) { self::$prePersistCalls[] = func_get_args(); } diff --git a/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php new file mode 100644 index 000000000..fd64594ba --- /dev/null +++ b/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php @@ -0,0 +1,33 @@ +assertTrue($guestMetadata->fieldMappings['name']['unique']); } + /** + * @group DDC-1955 + */ + public function testEntityListeners() + { + if ( ! ($this instanceof AnnotationDriverTest)) { + $this->markTestIncomplete(); + } + + $em = $this->_getTestEntityManager(); + $factory = $this->createClassMetadataFactory($em); + $superClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyContract'); + $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); + $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); + $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); + + $this->assertArrayHasKey(Events::prePersist, $superClass->entityListeners); + $this->assertArrayHasKey(Events::postPersist, $superClass->entityListeners); + + $this->assertCount(1, $superClass->entityListeners[Events::prePersist]); + $this->assertCount(1, $superClass->entityListeners[Events::postPersist]); + + $postPersist = $superClass->entityListeners[Events::postPersist][0]; + $prePersist = $superClass->entityListeners[Events::prePersist][0]; + + $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $postPersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $prePersist['class']); + $this->assertEquals('postPersistHandler', $postPersist['method']); + $this->assertEquals('prePersistHandler', $prePersist['method']); + + //Inherited listeners + $this->assertEquals($fixClass->entityListeners, $superClass->entityListeners); + $this->assertEquals($flexClass->entityListeners, $superClass->entityListeners); + + //overrited listeners + $this->assertArrayHasKey(Events::postPersist, $ultraClass->entityListeners); + $this->assertArrayHasKey(Events::prePersist, $ultraClass->entityListeners); + + $this->assertCount(1, $ultraClass->entityListeners[Events::postPersist]); + $this->assertCount(3, $ultraClass->entityListeners[Events::prePersist]); + + $postPersist = $ultraClass->entityListeners[Events::postPersist][0]; + $prePersist = $ultraClass->entityListeners[Events::prePersist][0]; + + $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $postPersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $prePersist['class']); + $this->assertEquals('postPersistHandler', $postPersist['method']); + $this->assertEquals('prePersistHandler', $prePersist['method']); + + $prePersist = $ultraClass->entityListeners[Events::prePersist][1]; + $this->assertEquals('Doctrine\Tests\Models\Company\FlexUltraContractSubscriber', $prePersist['class']); + $this->assertEquals('postPersistHandler1', $prePersist['method']); + + $prePersist = $ultraClass->entityListeners[Events::prePersist][2]; + $this->assertEquals('Doctrine\Tests\Models\Company\FlexUltraContractSubscriber', $prePersist['class']); + $this->assertEquals('postPersistHandler2', $prePersist['method']); + } + /** * @group DDC-1955 */ From ccc0a2a94f4ee01fa155fc68bb1e4608d5c29088 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 29 Jul 2012 22:03:29 -0300 Subject: [PATCH 05/41] test entity listener calls --- .../Models/Company/ContractSubscriber.php | 4 +-- .../Company/FlexUltraContractSubscriber.php | 9 +++--- .../EntityListenersDispatcherTest.php | 22 +------------ .../ORM/Mapping/AbstractMappingDriverTest.php | 32 ++++++++++++++++--- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php index 2a7d7c76a..afc30933e 100644 --- a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php +++ b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php @@ -5,7 +5,7 @@ namespace Doctrine\Tests\Models\Company; class ContractSubscriber { static public $prePersistCalls; - static public $postPersisCalls; + static public $postPersistCalls; static public $instances; public function __construct() @@ -18,7 +18,7 @@ class ContractSubscriber */ public function postPersistHandler(CompanyContract $contract) { - self::$postPersisCalls[] = func_get_args(); + self::$postPersistCalls[] = func_get_args(); } /** diff --git a/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php index fd64594ba..408bcad70 100644 --- a/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php +++ b/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php @@ -7,7 +7,6 @@ use Doctrine\ORM\Event\LifecycleEventArgs; class FlexUltraContractSubscriber { static public $prePersistCalls; - static public $postPersisCalls; static public $instances; public function __construct() @@ -18,16 +17,16 @@ class FlexUltraContractSubscriber /** * @PrePersist */ - public function postPersistHandler1(CompanyContract $contract, LifecycleEventArgs $args) + public function prePersistHandler1(CompanyContract $contract, LifecycleEventArgs $args) { - self::$postPersisCalls[] = func_get_args(); + self::$prePersistCalls[] = func_get_args(); } /** * @PrePersist */ - public function postPersistHandler2(CompanyContract $contract, LifecycleEventArgs $args) + public function prePersistHandler2(CompanyContract $contract, LifecycleEventArgs $args) { - self::$postPersisCalls[] = func_get_args(); + self::$prePersistCalls[] = func_get_args(); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php index 8b13b5951..c45bd944c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php @@ -18,26 +18,6 @@ class EntityListenersDispatcherTest extends \Doctrine\Tests\OrmFunctionalTestCas */ public function testEntityListeners() { - $flexClass = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyFixContract'); - $fixClass = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyFlexContract'); - - $this->assertNull(ContractSubscriber::$instances); - $this->assertNull(ContractSubscriber::$prePersistCalls); - $this->assertNull(ContractSubscriber::$postPersisCalls); - - $fix = new CompanyFixContract(); - $fixArg = new LifecycleEventArgs($fix, $this->_em); - - $flex = new CompanyFlexContract(); - $flexArg = new LifecycleEventArgs($fix, $this->_em); - - $fixClass->dispatchEntityListeners(Events::prePersist, $fix, $fixArg); - $flexClass->dispatchEntityListeners(Events::prePersist, $flex, $flexArg); - - $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); - $this->assertSame($fixArg, ContractSubscriber::$prePersistCalls[0][1]); - - $this->assertCount(1, ContractSubscriber::$instances); - $this->assertNull(ContractSubscriber::$postPersisCalls); + $this->markTestIncomplete(); } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 365bc69d0..a509add48 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -7,6 +7,7 @@ use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\Tests\Models\Company\CompanyFixContract; use Doctrine\Tests\Models\Company\CompanyFlexContract; use Doctrine\Tests\Models\Company\ContractSubscriber; +use Doctrine\Tests\Models\Company\FlexUltraContractSubscriber; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataInfo; @@ -803,11 +804,11 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $prePersist = $ultraClass->entityListeners[Events::prePersist][1]; $this->assertEquals('Doctrine\Tests\Models\Company\FlexUltraContractSubscriber', $prePersist['class']); - $this->assertEquals('postPersistHandler1', $prePersist['method']); + $this->assertEquals('prePersistHandler1', $prePersist['method']); $prePersist = $ultraClass->entityListeners[Events::prePersist][2]; $this->assertEquals('Doctrine\Tests\Models\Company\FlexUltraContractSubscriber', $prePersist['class']); - $this->assertEquals('postPersistHandler2', $prePersist['method']); + $this->assertEquals('prePersistHandler2', $prePersist['method']); } /** @@ -823,9 +824,11 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $factory = $this->createClassMetadataFactory($em); $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); + $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); - ContractSubscriber::$prePersistCalls = null; - ContractSubscriber::$postPersisCalls = null; + ContractSubscriber::$prePersistCalls = null; + ContractSubscriber::$postPersistCalls = null; + FlexUltraContractSubscriber::$prePersistCalls = null; $fix = new CompanyFixContract(); $fixArg = new LifecycleEventArgs($fix, $em); @@ -833,14 +836,33 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $flex = new CompanyFlexContract(); $flexArg = new LifecycleEventArgs($fix, $em); + $ultra = new CompanyFlexContract(); + $ultraArg = new LifecycleEventArgs($ultra, $em); + $fixClass->dispatchEntityListeners(Events::prePersist, $fix, $fixArg); $flexClass->dispatchEntityListeners(Events::prePersist, $flex, $flexArg); + $ultraClass->dispatchEntityListeners(Events::prePersist, $ultra, $ultraArg); + + $this->assertCount(3, ContractSubscriber::$prePersistCalls); + $this->assertCount(2, FlexUltraContractSubscriber::$prePersistCalls); $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); $this->assertSame($fixArg, ContractSubscriber::$prePersistCalls[0][1]); + $this->assertSame($flex, ContractSubscriber::$prePersistCalls[1][0]); + $this->assertSame($flexArg, ContractSubscriber::$prePersistCalls[1][1]); + + $this->assertSame($ultra, ContractSubscriber::$prePersistCalls[2][0]); + $this->assertSame($ultraArg, ContractSubscriber::$prePersistCalls[2][1]); + + $this->assertSame($ultra, FlexUltraContractSubscriber::$prePersistCalls[0][0]); + $this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[0][1]); + + $this->assertSame($ultra, FlexUltraContractSubscriber::$prePersistCalls[1][0]); + $this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[1][1]); + $this->assertCount(1, ContractSubscriber::$instances); - $this->assertNull(ContractSubscriber::$postPersisCalls); + $this->assertNull(ContractSubscriber::$postPersistCalls); } } From 315f7ba43b9c2226c9d801142ade87c4f5a8f56a Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Mon, 30 Jul 2012 22:26:55 -0300 Subject: [PATCH 06/41] call listeners in UoW --- lib/Doctrine/ORM/UnitOfWork.php | 131 ++++++++--- .../Models/Company/ContractSubscriber.php | 62 ++++- .../EntityListenersDispatcherTest.php | 215 +++++++++++++++++- .../ORM/Mapping/AbstractMappingDriverTest.php | 8 +- 4 files changed, 378 insertions(+), 38 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 9f54463c1..08c1af332 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -22,15 +22,21 @@ namespace Doctrine\ORM; use Exception; use InvalidArgumentException; use UnexpectedValueException; + use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\NotifyPropertyChanged; use Doctrine\Common\PropertyChangedListener; use Doctrine\Common\Persistence\ObjectManagerAware; -use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Proxy\Proxy; +use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PreUpdateEventArgs; +use Doctrine\ORM\Event\PreFlushEventArgs; +use Doctrine\ORM\Event\OnFlushEventArgs; +use Doctrine\ORM\Event\PostFlushEventArgs; + /** * The UnitOfWork is responsible for tracking changes to objects during an * "object-level" transaction and for writing out changes to the database @@ -267,7 +273,7 @@ class UnitOfWork implements PropertyChangedListener { // Raise preFlush if ($this->evm->hasListeners(Events::preFlush)) { - $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->em)); + $this->evm->dispatchEvent(Events::preFlush, new PreFlushEventArgs($this->em)); } // Compute changes done since last commit. @@ -511,6 +517,11 @@ class UnitOfWork implements PropertyChangedListener $class->invokeLifecycleCallbacks(Events::preFlush, $entity); } + // Fire PreFlush entity listeners + if (isset($class->entityListeners[Events::preFlush])) { + $class->dispatchEntityListeners(Events::preFlush, $entity, new PreFlushEventArgs($this->em)); + } + $actualData = array(); foreach ($class->reflFields as $name => $refProp) { @@ -798,21 +809,32 @@ class UnitOfWork implements PropertyChangedListener } /** - * @param ClassMetadata $class + * @param \Doctrine\ORM\Mapping\ClassMetadata $class * @param object $entity * * @return void */ private function persistNew($class, $entity) { - $oid = spl_object_hash($entity); + $oid = spl_object_hash($entity); + $hasListeners = $this->evm->hasListeners(Events::prePersist); + $hasEntityListeners = isset($class->entityListeners[Events::prePersist]); + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::prePersist]); - if (isset($class->lifecycleCallbacks[Events::prePersist])) { + if ($hasListeners || $hasEntityListeners) { + $event = new LifecycleEventArgs($entity, $this->em); + } + + if ($hasLifecycleCallbacks) { $class->invokeLifecycleCallbacks(Events::prePersist, $entity); } - if ($this->evm->hasListeners(Events::prePersist)) { - $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entity, $this->em)); + if ($hasEntityListeners) { + $class->dispatchEntityListeners(Events::prePersist, $entity, $event); + } + + if ($hasListeners) { + $this->evm->dispatchEvent(Events::prePersist, $event); } $idGen = $class->idGenerator; @@ -913,6 +935,7 @@ class UnitOfWork implements PropertyChangedListener $entities = array(); $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]); + $hasEntityListeners = isset($class->entityListeners[Events::postPersist]); $hasListeners = $this->evm->hasListeners(Events::postPersist); foreach ($this->entityInsertions as $oid => $entity) { @@ -924,7 +947,7 @@ class UnitOfWork implements PropertyChangedListener unset($this->entityInsertions[$oid]); - if ($hasLifecycleCallbacks || $hasListeners) { + if ($hasLifecycleCallbacks || $hasEntityListeners || $hasListeners) { $entities[] = $entity; } } @@ -946,14 +969,23 @@ class UnitOfWork implements PropertyChangedListener $this->addToIdentityMap($entity); } } - + foreach ($entities as $entity) { + + if ($hasListeners || $hasEntityListeners) { + $event = new LifecycleEventArgs($entity, $this->em); + } + if ($hasLifecycleCallbacks) { $class->invokeLifecycleCallbacks(Events::postPersist, $entity); } + if ($hasEntityListeners) { + $class->dispatchEntityListeners(Events::postPersist, $entity, $event); + } + if ($hasListeners) { - $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($entity, $this->em)); + $this->evm->dispatchEvent(Events::postPersist, $event); } } } @@ -971,9 +1003,11 @@ class UnitOfWork implements PropertyChangedListener $persister = $this->getEntityPersister($className); $hasPreUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preUpdate]); + $hasPreUpdateEntityListeners = isset($class->entityListeners[Events::preUpdate]); $hasPreUpdateListeners = $this->evm->hasListeners(Events::preUpdate); $hasPostUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postUpdate]); + $hasPostUpdateEntityListeners = isset($class->entityListeners[Events::postUpdate]); $hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate); foreach ($this->entityUpdates as $oid => $entity) { @@ -981,17 +1015,26 @@ class UnitOfWork implements PropertyChangedListener continue; } + if ($hasPreUpdateListeners || $hasPreUpdateEntityListeners) { + $preEvent = new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]); + } + + if ($hasPostUpdateListeners || $hasPostUpdateEntityListeners) { + $postEvent = new LifecycleEventArgs($entity, $this->em); + } + if ($hasPreUpdateLifecycleCallbacks) { $class->invokeLifecycleCallbacks(Events::preUpdate, $entity); $this->recomputeSingleEntityChangeSet($class, $entity); } + if ($hasPreUpdateEntityListeners) { + $class->dispatchEntityListeners(Events::preUpdate, $entity, $preEvent); + } + if ($hasPreUpdateListeners) { - $this->evm->dispatchEvent( - Events::preUpdate, - new Event\PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]) - ); + $this->evm->dispatchEvent(Events::preUpdate, $preEvent); } if (!empty($this->entityChangeSets[$oid])) { @@ -1004,8 +1047,12 @@ class UnitOfWork implements PropertyChangedListener $class->invokeLifecycleCallbacks(Events::postUpdate, $entity); } + if ($hasPostUpdateEntityListeners) { + $class->dispatchEntityListeners(Events::postUpdate, $entity, $postEvent); + } + if ($hasPostUpdateListeners) { - $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($entity, $this->em)); + $this->evm->dispatchEvent(Events::postUpdate, $postEvent); } } } @@ -1022,8 +1069,9 @@ class UnitOfWork implements PropertyChangedListener $className = $class->name; $persister = $this->getEntityPersister($className); - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]); - $hasListeners = $this->evm->hasListeners(Events::postRemove); + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]); + $hasEntityListeners = isset($class->entityListeners[Events::postRemove]); + $hasListeners = $this->evm->hasListeners(Events::postRemove); foreach ($this->entityDeletions as $oid => $entity) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) { @@ -1046,12 +1094,20 @@ class UnitOfWork implements PropertyChangedListener $class->reflFields[$class->identifier[0]]->setValue($entity, null); } + if ($hasListeners || $hasEntityListeners) { + $event = new LifecycleEventArgs($entity, $this->em); + } + if ($hasLifecycleCallbacks) { $class->invokeLifecycleCallbacks(Events::postRemove, $entity); } + if ($hasEntityListeners) { + $class->dispatchEntityListeners(Events::postRemove, $entity, $event); + } + if ($hasListeners) { - $this->evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($entity, $this->em)); + $this->evm->dispatchEvent(Events::postRemove, $event); } } } @@ -1691,12 +1747,24 @@ class UnitOfWork implements PropertyChangedListener break; case self::STATE_MANAGED: - if (isset($class->lifecycleCallbacks[Events::preRemove])) { + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preRemove]); + $hasEntityListeners = isset($class->entityListeners[Events::preRemove]); + $hasListeners = $this->evm->hasListeners(Events::preRemove); + + if ($hasListeners || $hasEntityListeners) { + $event = new LifecycleEventArgs($entity, $this->em); + } + + if ($hasLifecycleCallbacks) { $class->invokeLifecycleCallbacks(Events::preRemove, $entity); } - if ($this->evm->hasListeners(Events::preRemove)) { - $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entity, $this->em)); + if ($hasEntityListeners) { + $class->dispatchEntityListeners(Events::preRemove, $entity, $event); + } + + if ($hasListeners) { + $this->evm->dispatchEvent(Events::preRemove, $event); } $this->scheduleForDelete($entity); @@ -2695,13 +2763,24 @@ class UnitOfWork implements PropertyChangedListener } if ($overrideLocalValues) { - if (isset($class->lifecycleCallbacks[Events::postLoad])) { + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postLoad]); + $hasEntityListeners = isset($class->entityListeners[Events::postLoad]); + $hasListeners = $this->evm->hasListeners(Events::postLoad); + + if ($hasListeners || $hasEntityListeners) { + $event = new LifecycleEventArgs($entity, $this->em); + } + + if ($hasLifecycleCallbacks) { $class->invokeLifecycleCallbacks(Events::postLoad, $entity); } + if ($hasEntityListeners) { + $class->dispatchEntityListeners(Events::postLoad, $entity, $event); + } - if ($this->evm->hasListeners(Events::postLoad)) { - $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em)); + if ($hasListeners) { + $this->evm->dispatchEvent(Events::postLoad, $event); } } @@ -3177,14 +3256,14 @@ class UnitOfWork implements PropertyChangedListener private function dispatchOnFlushEvent() { if ($this->evm->hasListeners(Events::onFlush)) { - $this->evm->dispatchEvent(Events::onFlush, new Event\OnFlushEventArgs($this->em)); + $this->evm->dispatchEvent(Events::onFlush, new OnFlushEventArgs($this->em)); } } private function dispatchPostFlushEvent() { if ($this->evm->hasListeners(Events::postFlush)) { - $this->evm->dispatchEvent(Events::postFlush, new Event\PostFlushEventArgs($this->em)); + $this->evm->dispatchEvent(Events::postFlush, new PostFlushEventArgs($this->em)); } } } diff --git a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php index afc30933e..64e953a34 100644 --- a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php +++ b/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php @@ -4,8 +4,19 @@ namespace Doctrine\Tests\Models\Company; class ContractSubscriber { - static public $prePersistCalls; static public $postPersistCalls; + static public $prePersistCalls; + + static public $postUpdateCalls; + static public $preUpdateCalls; + + static public $postRemoveCalls; + static public $preRemoveCalls; + + static public $preFlushCalls; + + static public $postLoadCalls; + static public $instances; public function __construct() @@ -28,4 +39,53 @@ class ContractSubscriber { self::$prePersistCalls[] = func_get_args(); } + + /** + * @PostUpdate + */ + public function postUpdateHandler(CompanyContract $contract) + { + self::$postUpdateCalls[] = func_get_args(); + } + + /** + * @PreUpdate + */ + public function preUpdateHandler(CompanyContract $contract) + { + self::$preUpdateCalls[] = func_get_args(); + } + + /** + * @PostRemove + */ + public function postRemoveHandler(CompanyContract $contract) + { + self::$postRemoveCalls[] = func_get_args(); + } + + /** + * @PreRemove + */ + public function preRemoveHandler(CompanyContract $contract) + { + self::$preRemoveCalls[] = func_get_args(); + } + + /** + * @PreFlush + */ + public function preFlushHandler(CompanyContract $contract) + { + self::$preFlushCalls[] = func_get_args(); + } + + /** + * @PostLoad + */ + public function postLoadHandler(CompanyContract $contract) + { + self::$postLoadCalls[] = func_get_args(); + } + } diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php index c45bd944c..b60646612 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php @@ -2,22 +2,223 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\ORM\Events; -use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\Tests\Models\Company\CompanyFixContract; -use Doctrine\Tests\Models\Company\CompanyFlexContract; use Doctrine\Tests\Models\Company\ContractSubscriber; require_once __DIR__ . '/../../TestInit.php'; +/** +* @group DDC-1955 +*/ class EntityListenersDispatcherTest extends \Doctrine\Tests\OrmFunctionalTestCase { - /** - * @group DDC-1955 - */ - public function testEntityListeners() + protected function setUp() + { + $this->useModelSet('company'); + parent::setUp(); + } + + public function testPreFlushListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(2000); + + ContractSubscriber::$preFlushCalls = array(); + + $this->_em->persist($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$preFlushCalls); + + $this->assertSame($fix, ContractSubscriber::$preFlushCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$preFlushCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\PreFlushEventArgs', + ContractSubscriber::$preFlushCalls[0][1] + ); + } + + public function testPostLoadListeners() { $this->markTestIncomplete(); } + + public function testPrePersistListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(2000); + + ContractSubscriber::$prePersistCalls = array(); + + $this->_em->persist($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$prePersistCalls); + + $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$prePersistCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + ContractSubscriber::$prePersistCalls[0][1] + ); + } + + public function testPostPersistListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(2000); + + ContractSubscriber::$postPersistCalls = array(); + + $this->_em->persist($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$postPersistCalls); + + $this->assertSame($fix, ContractSubscriber::$postPersistCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$postPersistCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + ContractSubscriber::$postPersistCalls[0][1] + ); + } + + public function testPreUpdateListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(1000); + + $this->_em->persist($fix); + $this->_em->flush(); + + ContractSubscriber::$preUpdateCalls = array(); + + $fix->setFixPrice(2000); + + $this->_em->persist($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$preUpdateCalls); + + $this->assertSame($fix, ContractSubscriber::$preUpdateCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$preUpdateCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\PreUpdateEventArgs', + ContractSubscriber::$preUpdateCalls[0][1] + ); + } + + public function testPostUpdateListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(1000); + + $this->_em->persist($fix); + $this->_em->flush(); + + ContractSubscriber::$postUpdateCalls = array(); + + $fix->setFixPrice(2000); + + $this->_em->persist($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$postUpdateCalls); + + $this->assertSame($fix, ContractSubscriber::$postUpdateCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$postUpdateCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + ContractSubscriber::$postUpdateCalls[0][1] + ); + } + + public function testPreRemoveListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(1000); + + $this->_em->persist($fix); + $this->_em->flush(); + + ContractSubscriber::$preRemoveCalls = array(); + + $this->_em->remove($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$preRemoveCalls); + + $this->assertSame($fix, ContractSubscriber::$preRemoveCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$preRemoveCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + ContractSubscriber::$preRemoveCalls[0][1] + ); + } + + public function testPostRemoveListeners() + { + $fix = new CompanyFixContract(); + $fix->setFixPrice(1000); + + $this->_em->persist($fix); + $this->_em->flush(); + + ContractSubscriber::$postRemoveCalls = array(); + + $this->_em->remove($fix); + $this->_em->flush(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$postRemoveCalls); + + $this->assertSame($fix, ContractSubscriber::$postRemoveCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$postRemoveCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + ContractSubscriber::$postRemoveCalls[0][1] + ); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index a509add48..822872651 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -826,9 +826,9 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); - ContractSubscriber::$prePersistCalls = null; - ContractSubscriber::$postPersistCalls = null; - FlexUltraContractSubscriber::$prePersistCalls = null; + ContractSubscriber::$prePersistCalls = array(); + ContractSubscriber::$postPersistCalls = array(); + FlexUltraContractSubscriber::$prePersistCalls = array(); $fix = new CompanyFixContract(); $fixArg = new LifecycleEventArgs($fix, $em); @@ -862,7 +862,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[1][1]); $this->assertCount(1, ContractSubscriber::$instances); - $this->assertNull(ContractSubscriber::$postPersistCalls); + $this->assertEmpty(ContractSubscriber::$postPersistCalls); } } From dbd0697c2ced66adc6e4319ac8de7e8e466cc2ab Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Mon, 30 Jul 2012 22:35:41 -0300 Subject: [PATCH 07/41] test @PostLoad --- .../EntityListenersDispatcherTest.php | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php index b60646612..5127ff411 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php @@ -47,7 +47,32 @@ class EntityListenersDispatcherTest extends \Doctrine\Tests\OrmFunctionalTestCas public function testPostLoadListeners() { - $this->markTestIncomplete(); + $fix = new CompanyFixContract(); + $fix->setFixPrice(2000); + + $this->_em->persist($fix); + $this->_em->flush(); + $this->_em->clear(); + + ContractSubscriber::$postLoadCalls = array(); + + $dql = "SELECT f FROM Doctrine\Tests\Models\Company\CompanyFixContract f WHERE f.id = ?1"; + $fix = $this->_em->createQuery($dql)->setParameter(1, $fix->getId())->getSingleResult(); + + $this->assertCount(1,ContractSubscriber::$instances); + $this->assertCount(1,ContractSubscriber::$postLoadCalls); + + $this->assertSame($fix, ContractSubscriber::$postLoadCalls[0][0]); + + $this->assertInstanceOf( + 'Doctrine\Tests\Models\Company\CompanyFixContract', + ContractSubscriber::$postLoadCalls[0][0] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + ContractSubscriber::$postLoadCalls[0][1] + ); } public function testPrePersistListeners() From c6adcda5675036debad35d2ae6df968b458bd4bc Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 31 Jul 2012 20:10:36 -0300 Subject: [PATCH 08/41] give event to lifecycle callbacks --- .../ORM/Mapping/ClassMetadataInfo.php | 4 +- lib/Doctrine/ORM/UnitOfWork.php | 44 +++++++++++-------- ...atcherTest.php => EntityListenersTest.php} | 2 +- .../ORM/Functional/Ticket/DDC1707Test.php | 8 ++-- 4 files changed, 33 insertions(+), 25 deletions(-) rename tests/Doctrine/Tests/ORM/Functional/{EntityListenersDispatcherTest.php => EntityListenersTest.php} (98%) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 642da6701..f99ab54c0 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2434,10 +2434,10 @@ class ClassMetadataInfo implements ClassMetadata * * @return void */ - public function invokeLifecycleCallbacks($lifecycleEvent, $entity) + public function invokeLifecycleCallbacks($lifecycleEvent, $entity, EventArgs $event) { foreach ($this->lifecycleCallbacks[$lifecycleEvent] as $callback) { - $entity->$callback(); + $entity->$callback($event); } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 08c1af332..1c6cbeeb6 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -502,7 +502,13 @@ class UnitOfWork implements PropertyChangedListener */ public function computeChangeSet(ClassMetadata $class, $entity) { - $oid = spl_object_hash($entity); + $oid = spl_object_hash($entity); + $hasEntityListeners = isset($class->entityListeners[Events::preFlush]); + $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preFlush]); + + if ($hasEntityListeners || $hasLifecycleCallbacks) { + $event = new PreFlushEventArgs($entity, $this->em); + } if (isset($this->readOnlyObjects[$oid])) { return; @@ -513,13 +519,13 @@ class UnitOfWork implements PropertyChangedListener } // Fire PreFlush lifecycle callbacks - if (isset($class->lifecycleCallbacks[Events::preFlush])) { - $class->invokeLifecycleCallbacks(Events::preFlush, $entity); + if ($hasLifecycleCallbacks) { + $class->invokeLifecycleCallbacks(Events::preFlush, $entity, $event); } // Fire PreFlush entity listeners - if (isset($class->entityListeners[Events::preFlush])) { - $class->dispatchEntityListeners(Events::preFlush, $entity, new PreFlushEventArgs($this->em)); + if ($hasEntityListeners) { + $class->dispatchEntityListeners(Events::preFlush, $entity, $event); } $actualData = array(); @@ -821,12 +827,12 @@ class UnitOfWork implements PropertyChangedListener $hasEntityListeners = isset($class->entityListeners[Events::prePersist]); $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::prePersist]); - if ($hasListeners || $hasEntityListeners) { + if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { $event = new LifecycleEventArgs($entity, $this->em); } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::prePersist, $entity); + $class->invokeLifecycleCallbacks(Events::prePersist, $entity, $event); } if ($hasEntityListeners) { @@ -972,12 +978,12 @@ class UnitOfWork implements PropertyChangedListener foreach ($entities as $entity) { - if ($hasListeners || $hasEntityListeners) { + if ($hasListeners || $hasEntityListeners | $hasLifecycleCallbacks) { $event = new LifecycleEventArgs($entity, $this->em); } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postPersist, $entity); + $class->invokeLifecycleCallbacks(Events::postPersist, $entity, $event); } if ($hasEntityListeners) { @@ -1015,16 +1021,16 @@ class UnitOfWork implements PropertyChangedListener continue; } - if ($hasPreUpdateListeners || $hasPreUpdateEntityListeners) { + if ($hasPreUpdateListeners || $hasPreUpdateEntityListeners || $hasPreUpdateLifecycleCallbacks) { $preEvent = new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]); } - if ($hasPostUpdateListeners || $hasPostUpdateEntityListeners) { + if ($hasPostUpdateListeners || $hasPostUpdateEntityListeners || $hasPostUpdateLifecycleCallbacks) { $postEvent = new LifecycleEventArgs($entity, $this->em); } if ($hasPreUpdateLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::preUpdate, $entity); + $class->invokeLifecycleCallbacks(Events::preUpdate, $entity, $preEvent); $this->recomputeSingleEntityChangeSet($class, $entity); } @@ -1044,7 +1050,7 @@ class UnitOfWork implements PropertyChangedListener unset($this->entityUpdates[$oid]); if ($hasPostUpdateLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postUpdate, $entity); + $class->invokeLifecycleCallbacks(Events::postUpdate, $entity, $postEvent); } if ($hasPostUpdateEntityListeners) { @@ -1094,12 +1100,12 @@ class UnitOfWork implements PropertyChangedListener $class->reflFields[$class->identifier[0]]->setValue($entity, null); } - if ($hasListeners || $hasEntityListeners) { + if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { $event = new LifecycleEventArgs($entity, $this->em); } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postRemove, $entity); + $class->invokeLifecycleCallbacks(Events::postRemove, $entity, $event); } if ($hasEntityListeners) { @@ -1751,12 +1757,12 @@ class UnitOfWork implements PropertyChangedListener $hasEntityListeners = isset($class->entityListeners[Events::preRemove]); $hasListeners = $this->evm->hasListeners(Events::preRemove); - if ($hasListeners || $hasEntityListeners) { + if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { $event = new LifecycleEventArgs($entity, $this->em); } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::preRemove, $entity); + $class->invokeLifecycleCallbacks(Events::preRemove, $entity, $event); } if ($hasEntityListeners) { @@ -2767,12 +2773,12 @@ class UnitOfWork implements PropertyChangedListener $hasEntityListeners = isset($class->entityListeners[Events::postLoad]); $hasListeners = $this->evm->hasListeners(Events::postLoad); - if ($hasListeners || $hasEntityListeners) { + if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { $event = new LifecycleEventArgs($entity, $this->em); } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postLoad, $entity); + $class->invokeLifecycleCallbacks(Events::postLoad, $entity, $event); } if ($hasEntityListeners) { diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php similarity index 98% rename from tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php rename to tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php index 5127ff411..857fe7383 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php @@ -10,7 +10,7 @@ require_once __DIR__ . '/../../TestInit.php'; /** * @group DDC-1955 */ -class EntityListenersDispatcherTest extends \Doctrine\Tests\OrmFunctionalTestCase +class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase { protected function setUp() diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1707Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1707Test.php index 50e702d99..c6c23b991 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1707Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1707Test.php @@ -2,7 +2,7 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; -use Doctrine\ORM\UnitOfWork; +use Doctrine\ORM\Event\LifecycleEventArgs; /** * @group DDC-1707 @@ -25,9 +25,11 @@ class DDC1707Test extends \Doctrine\Tests\OrmFunctionalTestCase public function testPostLoadOnChild() { - $class = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1707Child'); + $class = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1707Child'); $entity = new DDC1707Child(); - $class->invokeLifecycleCallbacks(\Doctrine\ORM\Events::postLoad, $entity); + $event = new LifecycleEventArgs($entity, $this->_em); + + $class->invokeLifecycleCallbacks(\Doctrine\ORM\Events::postLoad, $entity, $event); $this->assertTrue($entity->postLoad); } From 4cfe2294e3d789688483cb56c1012543e0f758b4 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 31 Jul 2012 20:32:56 -0300 Subject: [PATCH 09/41] test lifecycle callbacks event args --- .../ORM/Functional/LifecycleCallbackTest.php | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index 230f562c6..a8825553a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -11,6 +11,7 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase parent::setUp(); try { $this->_schemaTool->createSchema(array( + $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackEventArgEntity'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestUser'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackCascader'), @@ -182,6 +183,77 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals('Bob', $bob->getName()); } + + /** + * @group DDC-1955 + */ + public function testLifecycleCallbackEventArgs() + { + $e = new LifecycleCallbackEventArgEntity; + + $e->value = 'foo'; + $this->_em->persist($e); + $this->_em->flush(); + + $e->value = 'var'; + $this->_em->persist($e); + $this->_em->flush(); + + $this->_em->refresh($e); + + $this->_em->remove($e); + $this->_em->flush(); + + + $this->assertArrayHasKey('preFlushHandler', $e->calls); + $this->assertArrayHasKey('postLoadHandler', $e->calls); + $this->assertArrayHasKey('prePersistHandler', $e->calls); + $this->assertArrayHasKey('postPersistHandler', $e->calls); + $this->assertArrayHasKey('preUpdateHandler', $e->calls); + $this->assertArrayHasKey('postUpdateHandler', $e->calls); + $this->assertArrayHasKey('preRemoveHandler', $e->calls); + $this->assertArrayHasKey('postRemoveHandler', $e->calls); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\PreFlushEventArgs', + $e->calls['preFlushHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['postLoadHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['prePersistHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['postPersistHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\PreUpdateEventArgs', + $e->calls['preUpdateHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['postUpdateHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['preRemoveHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['postRemoveHandler'] + ); + } } /** @Entity @HasLifecycleCallbacks */ @@ -309,3 +381,80 @@ class LifecycleListenerPreUpdate $eventArgs->setNewValue('name', 'Bob'); } } + + +/** @Entity @HasLifecycleCallbacks */ +class LifecycleCallbackEventArgEntity +{ + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + + /** @Column(type="integer") */ + public $value; + + public $calls = array(); + + /** + * @PostPersist + */ + public function postPersistHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PrePersist + */ + public function prePersistHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PostUpdate + */ + public function postUpdateHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PreUpdate + */ + public function preUpdateHandler(\Doctrine\ORM\Event\PreUpdateEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PostRemove + */ + public function postRemoveHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PreRemove + */ + public function preRemoveHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PreFlush + */ + public function preFlushHandler(\Doctrine\ORM\Event\PreFlushEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } + + /** + * @PostLoad + */ + public function postLoadHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } +} \ No newline at end of file From 6be7a03b72607f5834b11d9896a9f74ce6334a59 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 31 Jul 2012 20:49:54 -0300 Subject: [PATCH 10/41] fix previous test --- tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index a8825553a..589b91ee5 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -389,7 +389,7 @@ class LifecycleCallbackEventArgEntity /** @Id @Column(type="integer") @GeneratedValue */ public $id; - /** @Column(type="integer") */ + /** @Column() */ public $value; public $calls = array(); From 7e54ae370249dcabed7a2971fbb048d8f120ca0a Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 31 Jul 2012 22:20:21 -0300 Subject: [PATCH 11/41] xml driver --- .../ORM/Mapping/ClassMetadataInfo.php | 10 +++++ .../ORM/Mapping/Driver/AnnotationDriver.php | 14 +++---- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 15 +++++++ lib/Doctrine/ORM/Mapping/MappingException.php | 29 +++++++++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 6 ++- ...sts.Models.Company.CompanyContract.dcm.xml | 41 +++++++++++++++++++ ....Models.Company.CompanyFixContract.dcm.xml | 16 ++++++++ ...Models.Company.CompanyFlexContract.dcm.xml | 16 ++++++++ ...s.Company.CompanyFlexUltraContract.dcm.xml | 36 ++++++++++++++++ 9 files changed, 174 insertions(+), 9 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index f99ab54c0..51a04aa3f 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2499,6 +2499,16 @@ class ClassMetadataInfo implements ClassMetadata */ public function addEntityListener($eventName, $class, $method) { + $class = $this->fullyQualifiedClassName($class); + + if ( ! class_exists($class)) { + throw MappingException::entityListenerClassNotFound($class, $this->name); + } + + if ( !method_exists($class, $method)) { + throw MappingException::entityListenerMethodNotFound($class, $method, $this->name); + } + $this->entityListeners[$eventName][] = array( 'class' => $class, 'method' => $method diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index eaad6576b..30f664104 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -419,19 +419,19 @@ class AnnotationDriver extends AbstractAnnotationDriver if (isset($classAnnotations['Doctrine\ORM\Mapping\EntityListeners'])) { $entityListenersAnnot = $classAnnotations['Doctrine\ORM\Mapping\EntityListeners']; - foreach ($entityListenersAnnot->value as $listener) { - $listener = $metadata->fullyQualifiedClassName($listener); + foreach ($entityListenersAnnot->value as $item) { + $listenerClassName = $metadata->fullyQualifiedClassName($item); - if ( ! class_exists($listener)) { - throw new \InvalidArgumentException("Indefined class \"$listener\""); + if ( ! class_exists($listenerClassName)) { + throw MappingException::entityListenerClassNotFound($listenerClassName, $className); } - $listener = new \ReflectionClass($listener); + $listenerClass = new \ReflectionClass($listenerClassName); /* @var $method \ReflectionMethod */ - foreach ($listener->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + foreach ($listenerClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { // find method callbacks. foreach ($this->getMethodCallbacks($method) as $value) { - $metadata->addEntityListener($value[1], $listener->name, $value[0]); + $metadata->addEntityListener($value[1], $listenerClassName, $value[0]); } } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index b8b5e13b2..f22db0745 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -556,6 +556,21 @@ class XmlDriver extends FileDriver $metadata->addLifecycleCallback((string)$lifecycleCallback['method'], constant('Doctrine\ORM\Events::' . (string)$lifecycleCallback['type'])); } } + + // Evaluate entity listener + if (isset($xmlRoot->{'entity-listeners'})) { + foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { + $className = (string) $listenerElement['class']; + + foreach ($listenerElement as $type => $callbackElement) { + list($prefix, $suffix) = explode('-', $type); + $eventName = $prefix . ucfirst($suffix); + $methodName = (string) $callbackElement['method']; + + $metadata->addEntityListener($eventName, $className, $methodName); + } + } + } } /** diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index 3c32eebd5..a2688a177 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -684,6 +684,35 @@ class MappingException extends \Doctrine\ORM\ORMException return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback."); } + /** + * @param string $className + * @param string $methodName + * + * @return \Doctrine\ORM\Mapping\MappingException + */ + public static function entityListenerClassNotFound($listenerName, $className) + { + return new self(sprintf( + 'Entity Listener "%s" declared on "%s" not found.', + $listenerName, $className + )); + } + + /** + * @param string $listenerName + * @param string $methodName + * @param string $className + * + * @return \Doctrine\ORM\Mapping\MappingException + */ + public static function entityListenerMethodNotFound($listenerName, $methodName, $className) + { + return new self(sprintf( + 'Entity Listener "%s" declared on "%s" has no method "%s".', + $listenerName, $className, $methodName + )); + } + /** * @param string $className * @param string $annotation diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 822872651..5c6e04a69 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -758,7 +758,8 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testEntityListeners() { - if ( ! ($this instanceof AnnotationDriverTest)) { + if ( ! ($this instanceof AnnotationDriverTest) + && ! ($this instanceof XmlMappingDriverTest)) { $this->markTestIncomplete(); } @@ -816,7 +817,8 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testCallEntityListeners() { - if ( ! ($this instanceof AnnotationDriverTest)) { + if ( ! ($this instanceof AnnotationDriverTest) + && ! ($this instanceof XmlMappingDriverTest)) { $this->markTestIncomplete(); } diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml new file mode 100644 index 000000000..990b519b6 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml new file mode 100644 index 000000000..bd1019d68 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml new file mode 100644 index 000000000..91ef0bb1c --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml new file mode 100644 index 000000000..8b0075367 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 917aa70c9745a0f946ae34ebd870108fe3f0ffa4 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 4 Aug 2012 18:02:32 -0300 Subject: [PATCH 12/41] test invalid class/method --- .../ORM/Mapping/ClassMetadataInfo.php | 2 +- .../Tests/ORM/Mapping/ClassMetadataTest.php | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 51a04aa3f..597256ed7 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2505,7 +2505,7 @@ class ClassMetadataInfo implements ClassMetadata throw MappingException::entityListenerClassNotFound($class, $this->name); } - if ( !method_exists($class, $method)) { + if ( ! method_exists($class, $method)) { throw MappingException::entityListenerMethodNotFound($class, $method, $this->name); } diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index fee6d822c..2f79b967c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -997,6 +997,34 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase $cm->setAttributeOverride('name', array('type'=>'date')); } + + /** + * @group DDC-1955 + * + * @expectedException Doctrine\ORM\Mapping\MappingException + * @expectedExceptionMessage Entity Listener "\InvalidClassName" declared on "Doctrine\Tests\Models\CMS\CmsUser" not found. + */ + public function testInvalidEntityListenerClassException() + { + $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); + $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); + + $cm->addEntityListener(Events::postLoad, '\InvalidClassName', 'postLoadHandler'); + } + + /** + * @group DDC-1955 + * + * @expectedException Doctrine\ORM\Mapping\MappingException + * @expectedExceptionMessage Entity Listener "\Doctrine\Tests\Models\Company\ContractSubscriber" declared on "Doctrine\Tests\Models\CMS\CmsUser" has no method "invalidMethod". + */ + public function testInvalidEntityListenerMethodException() + { + $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); + $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); + + $cm->addEntityListener(Events::postLoad, '\Doctrine\Tests\Models\Company\ContractSubscriber', 'invalidMethod'); + } } class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy From f0b04375de5faca43788d29650ac05ec4bb69210 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 5 Aug 2012 16:50:56 -0300 Subject: [PATCH 13/41] yaml driver --- .../ORM/Mapping/Driver/YamlDriver.php | 11 +++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 6 ++-- ...sts.Models.Company.CompanyContract.dcm.xml | 2 +- ...s.Company.CompanyFlexUltraContract.dcm.xml | 2 +- ...sts.Models.Company.CompanyContract.dcm.yml | 30 +++++++++++++++++++ ....Models.Company.CompanyFixContract.dcm.yml | 5 ++++ ...Models.Company.CompanyFlexContract.dcm.yml | 7 +++++ ...s.Company.CompanyFlexUltraContract.dcm.yml | 22 ++++++++++++++ 8 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index 50e51ed05..e0af987e3 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -572,6 +572,17 @@ class YamlDriver extends FileDriver } } } + + // Evaluate entityListeners + if (isset($element['entityListeners'])) { + foreach ($element['entityListeners'] as $className => $entityListener) { + foreach ($entityListener as $eventName => $callbackElement){ + foreach ($callbackElement as $methodName){ + $metadata->addEntityListener($eventName, $className, $methodName); + } + } + } + } } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 5c6e04a69..a03434b58 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -759,7 +759,8 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase public function testEntityListeners() { if ( ! ($this instanceof AnnotationDriverTest) - && ! ($this instanceof XmlMappingDriverTest)) { + && ! ($this instanceof XmlMappingDriverTest) + && ! ($this instanceof YamlMappingDriverTest)) { $this->markTestIncomplete(); } @@ -818,7 +819,8 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase public function testCallEntityListeners() { if ( ! ($this instanceof AnnotationDriverTest) - && ! ($this instanceof XmlMappingDriverTest)) { + && ! ($this instanceof XmlMappingDriverTest) + && ! ($this instanceof YamlMappingDriverTest)) { $this->markTestIncomplete(); } diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml index 990b519b6..c4fc7adc8 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml @@ -21,7 +21,7 @@ - + diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml index 8b0075367..f699c313c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml @@ -15,7 +15,7 @@ - + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml new file mode 100644 index 000000000..c4e3f3026 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml @@ -0,0 +1,30 @@ +Doctrine\Tests\Models\Company\CompanyContract: + type: entity + table: company_contracts + inheritanceType: SINGLE_TABLE + discriminatorMap: + fix: CompanyFixContract + flexible: CompanyFlexContract + flexultra: CompanyFlexUltraContract + entityListeners: + ContractSubscriber: + preFlush: [preFlushHandler] + postLoad: [postLoadHandler] + + postPersist: [postPersistHandler] + prePersist: [prePersistHandler] + + postUpdate: [postUpdateHandler] + preUpdate: [preUpdateHandler] + + postRemove: [postRemoveHandler] + preRemove: [preRemoveHandler] + + id: + id: + type: integer + generator: + strategy: AUTO + fields: + completed: + type: boolean \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml new file mode 100644 index 000000000..83d0c75be --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml @@ -0,0 +1,5 @@ +Doctrine\Tests\Models\Company\CompanyFixContract: + type: entity + fields: + fixPrice: + type: integer \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml new file mode 100644 index 000000000..ef1d26306 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml @@ -0,0 +1,7 @@ +Doctrine\Tests\Models\Company\CompanyFlexContract: + type: entity + fields: + hoursWorked: + type: integer + pricePerHour: + type: integer \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml new file mode 100644 index 000000000..48a42e649 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml @@ -0,0 +1,22 @@ +Doctrine\Tests\Models\Company\CompanyFlexUltraContract: + type: entity + entityListeners: + ContractSubscriber: + preFlush: [preFlushHandler] + postLoad: [postLoadHandler] + + postPersist: [postPersistHandler] + prePersist: [prePersistHandler] + + postUpdate: [postUpdateHandler] + preUpdate: [preUpdateHandler] + + postRemove: [postRemoveHandler] + preRemove: [preRemoveHandler] + + FlexUltraContractSubscriber: + prePersist: [prePersistHandler1, prePersistHandler2] + + fields: + maxPrice: + type: integer \ No newline at end of file From 415c2a95f2bb57ad370c99e11ce224d48c47327a Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 7 Aug 2012 21:31:01 -0300 Subject: [PATCH 14/41] php static driver --- .../Tests/Models/Company/CompanyContract.php | 40 +++++++++++++++++++ .../Models/Company/CompanyFixContract.php | 9 +++++ .../Models/Company/CompanyFlexContract.php | 15 +++++++ .../Company/CompanyFlexUltraContract.php | 23 +++++++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 8 +--- 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContract.php b/tests/Doctrine/Tests/Models/Company/CompanyContract.php index b218d8f86..4fd6d92d0 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyContract.php @@ -129,4 +129,44 @@ abstract class CompanyContract } abstract public function calculatePrice(); + + static public function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->setInheritanceType(\Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_JOINED); + $metadata->setTableName( 'company_contracts'); + $metadata->setDiscriminatorColumn(array( + 'name' => 'discr', + 'type' => 'string', + )); + + $metadata->mapField(array( + 'id' => true, + 'name' => 'id', + 'fieldName' => 'id', + )); + + $metadata->mapField(array( + 'type' => 'boolean', + 'name' => 'completed', + 'fieldName' => 'completed', + )); + + $metadata->setDiscriminatorMap(array( + "fix" => "CompanyFixContract", + "flexible" => "CompanyFlexContract", + "flexultra" => "CompanyFlexUltraContract" + )); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); + } } diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFixContract.php b/tests/Doctrine/Tests/Models/Company/CompanyFixContract.php index 9186fc3b1..87f3ce952 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyFixContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFixContract.php @@ -27,4 +27,13 @@ class CompanyFixContract extends CompanyContract { $this->fixPrice = $fixPrice; } + + static public function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->mapField(array( + 'type' => 'integer', + 'name' => 'fixPrice', + 'fieldName' => 'fixPrice', + )); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexContract.php b/tests/Doctrine/Tests/Models/Company/CompanyFlexContract.php index 121d8ec8e..86e6b330c 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyFlexContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFlexContract.php @@ -107,4 +107,19 @@ class CompanyFlexContract extends CompanyContract { $this->managers->removeElement($manager); } + + static public function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->mapField(array( + 'type' => 'integer', + 'name' => 'hoursWorked', + 'fieldName' => 'hoursWorked', + )); + + $metadata->mapField(array( + 'type' => 'integer', + 'name' => 'pricePerHour', + 'fieldName' => 'pricePerHour', + )); + } } diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php index ce76821a6..d193d07d9 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php @@ -28,4 +28,27 @@ class CompanyFlexUltraContract extends CompanyFlexContract { $this->maxPrice = $maxPrice; } + + static public function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->mapField(array( + 'type' => 'integer', + 'name' => 'maxPrice', + 'fieldName' => 'maxPrice', + )); + $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler1'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler2'); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index a03434b58..c5fc1fba7 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -758,9 +758,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testEntityListeners() { - if ( ! ($this instanceof AnnotationDriverTest) - && ! ($this instanceof XmlMappingDriverTest) - && ! ($this instanceof YamlMappingDriverTest)) { + if ($this instanceof PHPMappingDriverTest) { $this->markTestIncomplete(); } @@ -818,9 +816,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testCallEntityListeners() { - if ( ! ($this instanceof AnnotationDriverTest) - && ! ($this instanceof XmlMappingDriverTest) - && ! ($this instanceof YamlMappingDriverTest)) { + if ($this instanceof PHPMappingDriverTest) { $this->markTestIncomplete(); } From 7021f002f22bcfd16a6e67d16662c4501ea6f2ec Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 7 Aug 2012 21:36:47 -0300 Subject: [PATCH 15/41] php driver --- .../ORM/Mapping/AbstractMappingDriverTest.php | 8 ---- ...e.Tests.Models.Company.CompanyContract.php | 40 +++++++++++++++++++ ...ests.Models.Company.CompanyFixContract.php | 7 ++++ ...sts.Models.Company.CompanyFlexContract.php | 13 ++++++ ...odels.Company.CompanyFlexUltraContract.php | 21 ++++++++++ 5 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index c5fc1fba7..ba9a0e0e9 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -758,10 +758,6 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testEntityListeners() { - if ($this instanceof PHPMappingDriverTest) { - $this->markTestIncomplete(); - } - $em = $this->_getTestEntityManager(); $factory = $this->createClassMetadataFactory($em); $superClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyContract'); @@ -816,10 +812,6 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testCallEntityListeners() { - if ($this instanceof PHPMappingDriverTest) { - $this->markTestIncomplete(); - } - $em = $this->_getTestEntityManager(); $factory = $this->createClassMetadataFactory($em); $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php new file mode 100644 index 000000000..636b952c9 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php @@ -0,0 +1,40 @@ +setInheritanceType(\Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_JOINED); +$metadata->setTableName( 'company_contracts'); +$metadata->setDiscriminatorColumn(array( + 'name' => 'discr', + 'type' => 'string', +)); + +$metadata->mapField(array( + 'id' => true, + 'name' => 'id', + 'fieldName' => 'id', +)); + +$metadata->mapField(array( + 'type' => 'boolean', + 'name' => 'completed', + 'fieldName' => 'completed', +)); + +$metadata->setDiscriminatorMap(array( + "fix" => "CompanyFixContract", + "flexible" => "CompanyFlexContract", + "flexultra" => "CompanyFlexUltraContract" +)); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php new file mode 100644 index 000000000..79b117729 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php @@ -0,0 +1,7 @@ +mapField(array( + 'type' => 'integer', + 'name' => 'fixPrice', + 'fieldName' => 'fixPrice', +)); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php new file mode 100644 index 000000000..5f1542dde --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php @@ -0,0 +1,13 @@ +mapField(array( + 'type' => 'integer', + 'name' => 'hoursWorked', + 'fieldName' => 'hoursWorked', +)); + +$metadata->mapField(array( + 'type' => 'integer', + 'name' => 'pricePerHour', + 'fieldName' => 'pricePerHour', +)); diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php new file mode 100644 index 000000000..31e4b60c0 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php @@ -0,0 +1,21 @@ +mapField(array( + 'type' => 'integer', + 'name' => 'maxPrice', + 'fieldName' => 'maxPrice', +)); +$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler1'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler2'); \ No newline at end of file From fd6f59243069e5d5b5073d5de0b7949fc5455286 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 7 Aug 2012 22:34:32 -0300 Subject: [PATCH 16/41] support @LifecycleCallback in @EntityListeners --- .../ORM/Mapping/Driver/AnnotationDriver.php | 8 ++++ .../Mapping/Driver/DoctrineAnnotations.php | 1 + lib/Doctrine/ORM/Mapping/EntityListeners.php | 9 +++- .../ORM/Mapping/LifecycleCallback.php | 41 +++++++++++++++++++ .../Tests/Models/Company/CompanyPerson.php | 11 +++++ .../ORM/Functional/LifecycleCallbackTest.php | 17 ++++++++ 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 lib/Doctrine/ORM/Mapping/LifecycleCallback.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 30f664104..b069364ab 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -435,6 +435,14 @@ class AnnotationDriver extends AbstractAnnotationDriver } } } + + // evaluate as lifecycle callback if the listener class is not given. + if(empty($entityListenersAnnot->value)) { + /* @var $method \Doctrine\ORM\Mapping\LifecycleCallback */ + foreach ($entityListenersAnnot->callbacks as $callback) { + $metadata->addLifecycleCallback($callback->method, $callback->event); + } + } } // Evaluate @HasLifecycleCallbacks annotation diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php index dc577d5c0..9a5f33448 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php +++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php @@ -65,3 +65,4 @@ require_once __DIR__.'/../AssociationOverrides.php'; require_once __DIR__.'/../AttributeOverride.php'; require_once __DIR__.'/../AttributeOverrides.php'; require_once __DIR__.'/../EntityListeners.php'; +require_once __DIR__.'/../LifecycleCallback.php'; diff --git a/lib/Doctrine/ORM/Mapping/EntityListeners.php b/lib/Doctrine/ORM/Mapping/EntityListeners.php index 3d08b2dc3..eef6fc43b 100644 --- a/lib/Doctrine/ORM/Mapping/EntityListeners.php +++ b/lib/Doctrine/ORM/Mapping/EntityListeners.php @@ -37,5 +37,12 @@ final class EntityListeners implements Annotation * * @var array */ - public $value; + public $value = array(); + + /** + * Specifies the entity the entity lifecycle callbacks. + * + * @var array<\Doctrine\ORM\Mapping\LifecycleCallback> + */ + public $callbacks = array(); } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/LifecycleCallback.php b/lib/Doctrine/ORM/Mapping/LifecycleCallback.php new file mode 100644 index 000000000..0b1b39585 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/LifecycleCallback.php @@ -0,0 +1,41 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * @author Fabio B. Silva + * @since 2.4 + * + * @Annotation + * @Target("ANNOTATION") + */ +final class LifecycleCallback implements Annotation +{ + /** + * @var string + */ + public $event; + + /** + * @var string + */ + public $method; +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/Company/CompanyPerson.php b/tests/Doctrine/Tests/Models/Company/CompanyPerson.php index 4636fa4e3..0d6a175ad 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyPerson.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyPerson.php @@ -15,6 +15,9 @@ namespace Doctrine\Tests\Models\Company; * "manager" = "CompanyManager", * "employee" = "CompanyEmployee" * }) + * @EntityListeners(callbacks = { + * @LifecycleCallback(\Doctrine\ORM\Events::prePersist, method = "prePersistHandler") + * }) * * @NamedNativeQueries({ * @NamedNativeQuery( @@ -79,6 +82,8 @@ class CompanyPerson */ private $friends; + public $prePersistHandlerCalls = array(); + public function __construct() { $this->friends = new \Doctrine\Common\Collections\ArrayCollection; } @@ -117,6 +122,12 @@ class CompanyPerson } } + public function prePersistHandler($event) + { + $this->prePersistHandlerCalls[] = $event; + } + + public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) { diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index 589b91ee5..4a740ceca 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -254,6 +254,23 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase $e->calls['postRemoveHandler'] ); } + /** + * @group DDC-1955 + */ + public function testEventListenersLifecycleCallback() + { + $e = new \Doctrine\Tests\Models\Company\CompanyPerson; + $e->setName('Fabio B. Silva'); + + $this->_em->persist($e); + $this->_em->flush(); + + $this->assertCount(1, $e->prePersistHandlerCalls); + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->prePersistHandlerCalls[0] + ); + } } /** @Entity @HasLifecycleCallbacks */ From 256cecbefae4a459e12d35b20bd36c861a1cc97c Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Thu, 9 Aug 2012 22:05:22 -0300 Subject: [PATCH 17/41] evaluate as lifecycle callback if the listener class is not given. --- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 26 ++++++++++--- .../ORM/Mapping/Driver/YamlDriver.php | 26 ++++++++++++- .../Doctrine/Tests/Models/CMS/CmsAddress.php | 37 +++++++++++++++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 14 +++++++ .../Doctrine.Tests.Models.CMS.CmsAddress.php | 23 ++++++++++++ ...ctrine.Tests.Models.CMS.CmsAddress.dcm.xml | 6 +++ ...ctrine.Tests.Models.CMS.CmsAddress.dcm.yml | 6 ++- ...sts.Models.Company.CompanyContract.dcm.yml | 21 ++++++----- ...s.Company.CompanyFlexUltraContract.dcm.yml | 31 +++++++++------- 9 files changed, 160 insertions(+), 30 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index f22db0745..22bdf1608 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -560,14 +560,30 @@ class XmlDriver extends FileDriver // Evaluate entity listener if (isset($xmlRoot->{'entity-listeners'})) { foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { - $className = (string) $listenerElement['class']; + $listeners = array(); foreach ($listenerElement as $type => $callbackElement) { - list($prefix, $suffix) = explode('-', $type); - $eventName = $prefix . ucfirst($suffix); - $methodName = (string) $callbackElement['method']; + list($prefix, $suffix) = explode('-', $type); - $metadata->addEntityListener($eventName, $className, $methodName); + $eventName = $prefix . ucfirst($suffix); + $methodName = (string) $callbackElement['method']; + $listeners[] = array($eventName, $methodName); + + } + + if (isset($listenerElement['class'])) { + $className = (string) $listenerElement['class']; + + foreach ($listeners as $item) { + $metadata->addEntityListener($item[0], $className, $item[1]); + } + + continue; + } + + // evaluate as lifecycle callback if the listener class is not given. + foreach ($listeners as $item) { + $metadata->addLifecycleCallback($item[1], $item[0]); } } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index e0af987e3..dc9fc3829 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -575,12 +575,34 @@ class YamlDriver extends FileDriver // Evaluate entityListeners if (isset($element['entityListeners'])) { - foreach ($element['entityListeners'] as $className => $entityListener) { + foreach ($element['entityListeners'] as $entityListener) { + $listeners = array(); + $className = null; + + if (isset($entityListener['class'])) { + $className = $entityListener['class']; + + unset($entityListener['class']); + } + foreach ($entityListener as $eventName => $callbackElement){ foreach ($callbackElement as $methodName){ - $metadata->addEntityListener($eventName, $className, $methodName); + $listeners[] = array($eventName, $methodName); } } + + if (null !== $className) { + foreach ($listeners as $item){ + $metadata->addEntityListener($item[0], $className, $item[1]); + } + + continue; + } + + // evaluate as lifecycle callback if the listener class is not given. + foreach ($listeners as $item){ + $metadata->addLifecycleCallback($item[1], $item[0]); + } } } } diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php index 9833f3dfb..16394fd87 100644 --- a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php +++ b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php @@ -59,6 +59,9 @@ namespace Doctrine\Tests\Models\CMS; * ) * }) * + * @EntityListeners(callbacks = { + * @LifecycleCallback(\Doctrine\ORM\Events::prePersist, method = "prePersistHandler") + * }) */ class CmsAddress { @@ -94,6 +97,11 @@ class CmsAddress */ public $user; + /** + * @var array + */ + public $prePersistHandlerCalls = array(); + public function getId() { return $this->id; } @@ -121,12 +129,41 @@ class CmsAddress } } + public function prePersistHandler($event) + { + $this->prePersistHandlerCalls[] = $event; + } + public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) { $metadata->setPrimaryTable(array( 'name' => 'company_person', )); + $metadata->mapField(array ( + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', + )); + + $metadata->mapField(array ( + 'fieldName' => 'zip', + 'length' => 50, + )); + + $metadata->mapField(array ( + 'fieldName' => 'city', + 'length' => 50, + )); + + $metadata->mapOneToOne(array( + 'fieldName' => 'user', + 'targetEntity' => 'CmsUser', + 'joinColumns' => array(array('referencedColumnName' => 'id')) + )); + + $metadata->addLifecycleCallback('prePersistHandler', 'prePersist'); + $metadata->addNamedNativeQuery(array ( 'name' => 'find-all', 'query' => 'SELECT id, country, city FROM cms_addresses', diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index ba9a0e0e9..dc8030f20 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -857,6 +857,20 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertEmpty(ContractSubscriber::$postPersistCalls); } + /** + * @group DDC-1955 + */ + public function testEventListenersLifecycleCallback() + { + $em = $this->_getTestEntityManager(); + $factory = $this->createClassMetadataFactory($em); + $metadata = $factory->getMetadataFor('Doctrine\Tests\Models\CMS\CmsAddress'); + + $this->assertArrayHasKey('prePersist', $metadata->lifecycleCallbacks); + $this->assertCount(1, $metadata->lifecycleCallbacks['prePersist']); + $this->assertEquals('prePersistHandler', $metadata->lifecycleCallbacks['prePersist'][0]); + } + } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php index 964065cbd..fba8c9db8 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php @@ -6,6 +6,29 @@ $metadata->setPrimaryTable(array( 'name' => 'company_person', )); +$metadata->mapField(array ( + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', +)); + +$metadata->mapField(array ( + 'fieldName' => 'zip', + 'length' => 50, +)); + +$metadata->mapField(array ( + 'fieldName' => 'city', + 'length' => 50, +)); + +$metadata->mapOneToOne(array( + 'fieldName' => 'user', + 'targetEntity' => 'CmsUser', + 'joinColumns' => array(array('referencedColumnName' => 'id')) +)); + +$metadata->addLifecycleCallback('prePersistHandler', 'prePersist'); $metadata->addNamedNativeQuery(array ( 'name' => 'find-all', diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml index 0af5facda..2afa95d30 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml @@ -21,6 +21,12 @@ + + + + + + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml index 604acb293..cbff49615 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml @@ -14,6 +14,10 @@ Doctrine\Tests\Models\CMS\CmsAddress: resultSetMapping: mapping-count query: SELECT COUNT(*) AS count FROM cms_addresses + entityListeners: + listener[0]: + prePersist: [prePersistHandler] + sqlResultSetMappings: mapping-find-all: entityResult: @@ -55,7 +59,7 @@ Doctrine\Tests\Models\CMS\CmsAddress: type: string length: 50 oneToOne: - address: + user: targetEntity: CmsUser inversedBy: address joinColumn: diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml index c4e3f3026..bdad810c7 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml @@ -6,19 +6,22 @@ Doctrine\Tests\Models\Company\CompanyContract: fix: CompanyFixContract flexible: CompanyFlexContract flexultra: CompanyFlexUltraContract + entityListeners: - ContractSubscriber: - preFlush: [preFlushHandler] - postLoad: [postLoadHandler] + listener[0]: + class : ContractSubscriber - postPersist: [postPersistHandler] - prePersist: [prePersistHandler] + preFlush: [preFlushHandler] + postLoad: [postLoadHandler] - postUpdate: [postUpdateHandler] - preUpdate: [preUpdateHandler] + postPersist: [postPersistHandler] + prePersist: [prePersistHandler] - postRemove: [postRemoveHandler] - preRemove: [preRemoveHandler] + postUpdate: [postUpdateHandler] + preUpdate: [preUpdateHandler] + + postRemove: [postRemoveHandler] + preRemove: [preRemoveHandler] id: id: diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml index 48a42e649..1621a6a84 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml @@ -1,20 +1,25 @@ Doctrine\Tests\Models\Company\CompanyFlexUltraContract: type: entity + entityListeners: - ContractSubscriber: - preFlush: [preFlushHandler] - postLoad: [postLoadHandler] - - postPersist: [postPersistHandler] - prePersist: [prePersistHandler] - - postUpdate: [postUpdateHandler] - preUpdate: [preUpdateHandler] - - postRemove: [postRemoveHandler] - preRemove: [preRemoveHandler] + listener[0]: + class : ContractSubscriber - FlexUltraContractSubscriber: + preFlush: [preFlushHandler] + postLoad: [postLoadHandler] + + postPersist: [postPersistHandler] + prePersist: [prePersistHandler] + + postUpdate: [postUpdateHandler] + preUpdate: [preUpdateHandler] + + postRemove: [postRemoveHandler] + preRemove: [preRemoveHandler] + + listener[1]: + class : FlexUltraContractSubscriber + prePersist: [prePersistHandler1, prePersistHandler2] fields: From 69bfc71b6a14f8c91901c94b987a32edf5b19453 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Thu, 9 Aug 2012 22:25:16 -0300 Subject: [PATCH 18/41] test event listeners lifecycle callback --- .../Tests/Models/Company/CompanyPerson.php | 11 ----- .../ORM/Functional/LifecycleCallbackTest.php | 43 +++++++++++++++++-- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/tests/Doctrine/Tests/Models/Company/CompanyPerson.php b/tests/Doctrine/Tests/Models/Company/CompanyPerson.php index 0d6a175ad..4636fa4e3 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyPerson.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyPerson.php @@ -15,9 +15,6 @@ namespace Doctrine\Tests\Models\Company; * "manager" = "CompanyManager", * "employee" = "CompanyEmployee" * }) - * @EntityListeners(callbacks = { - * @LifecycleCallback(\Doctrine\ORM\Events::prePersist, method = "prePersistHandler") - * }) * * @NamedNativeQueries({ * @NamedNativeQuery( @@ -82,8 +79,6 @@ class CompanyPerson */ private $friends; - public $prePersistHandlerCalls = array(); - public function __construct() { $this->friends = new \Doctrine\Common\Collections\ArrayCollection; } @@ -122,12 +117,6 @@ class CompanyPerson } } - public function prePersistHandler($event) - { - $this->prePersistHandlerCalls[] = $event; - } - - public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) { diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index 4a740ceca..151da181b 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -11,6 +11,7 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase parent::setUp(); try { $this->_schemaTool->createSchema(array( + $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\EntityListenersLifecycleCallback'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackEventArgEntity'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestUser'), @@ -259,16 +260,22 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase */ public function testEventListenersLifecycleCallback() { - $e = new \Doctrine\Tests\Models\Company\CompanyPerson; - $e->setName('Fabio B. Silva'); + $e = new EntityListenersLifecycleCallback; + $e->value = 'foo'; $this->_em->persist($e); $this->_em->flush(); - $this->assertCount(1, $e->prePersistHandlerCalls); + $this->assertCount(2, $e->calls); + $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - $e->prePersistHandlerCalls[0] + $e->calls['prePersistHandler'] + ); + + $this->assertInstanceOf( + 'Doctrine\ORM\Event\LifecycleEventArgs', + $e->calls['postPersistHandler'] ); } } @@ -400,6 +407,34 @@ class LifecycleListenerPreUpdate } +/** + * @Entity + * @EntityListeners(callbacks = { + * @LifecycleCallback(\Doctrine\ORM\Events::prePersist, method = "prePersistHandler"), + * @LifecycleCallback(\Doctrine\ORM\Events::postPersist, method = "postPersistHandler"), + * }) + */ +class EntityListenersLifecycleCallback +{ + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + + /** @Column() */ + public $value; + + public $calls = array(); + + public function prePersistHandler($event) + { + $this->calls[__FUNCTION__] = $event; + } + + public function postPersistHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) + { + $this->calls[__FUNCTION__] = $event; + } +} + /** @Entity @HasLifecycleCallbacks */ class LifecycleCallbackEventArgEntity { From 46474bf4574f6a04e87046b34ec8a6686c805bad Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Fri, 10 Aug 2012 20:49:13 -0300 Subject: [PATCH 19/41] added doctrine-mapping.xsd --- doctrine-mapping.xsd | 56 +++++++++++++++++++ ...s.Company.CompanyFlexUltraContract.dcm.xml | 9 +-- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index e8b2e26b2..a0fb82f9a 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -98,6 +98,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -137,6 +192,7 @@ + diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml index f699c313c..bbe0899f6 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml @@ -11,15 +11,12 @@ - - - - + - - + + From a2655113689d12f60db6d2dae496a7e68bc0def0 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 11 Aug 2012 23:48:09 -0300 Subject: [PATCH 20/41] rename subscribers to listeners --- .../Tests/Models/Company/CompanyContract.php | 18 ++-- ...criber.php => CompanyContractListener.php} | 2 +- .../Company/CompanyFlexUltraContract.php | 22 ++--- ...p => CompanyFlexUltraContractListener.php} | 2 +- .../ORM/Functional/EntityListenersTest.php | 98 +++++++++---------- .../ORM/Mapping/AbstractMappingDriverTest.php | 50 +++++----- .../Tests/ORM/Mapping/ClassMetadataTest.php | 4 +- ...e.Tests.Models.Company.CompanyContract.php | 16 +-- ...odels.Company.CompanyFlexUltraContract.php | 20 ++-- ...sts.Models.Company.CompanyContract.dcm.xml | 2 +- ...s.Company.CompanyFlexUltraContract.dcm.xml | 4 +- ...sts.Models.Company.CompanyContract.dcm.yml | 2 +- ...s.Company.CompanyFlexUltraContract.dcm.yml | 4 +- 13 files changed, 122 insertions(+), 122 deletions(-) rename tests/Doctrine/Tests/Models/Company/{ContractSubscriber.php => CompanyContractListener.php} (98%) rename tests/Doctrine/Tests/Models/Company/{FlexUltraContractSubscriber.php => CompanyFlexUltraContractListener.php} (94%) diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContract.php b/tests/Doctrine/Tests/Models/Company/CompanyContract.php index 4fd6d92d0..139098274 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyContract.php @@ -7,7 +7,7 @@ namespace Doctrine\Tests\Models\Company; * @Table(name="company_contracts") * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") - * @EntityListeners({"ContractSubscriber"}) + * @EntityListeners({"CompanyContractListener"}) * @DiscriminatorMap({ * "fix" = "CompanyFixContract", * "flexible" = "CompanyFlexContract", @@ -157,16 +157,16 @@ abstract class CompanyContract "flexultra" => "CompanyFlexUltraContract" )); - $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CompanyContractListener', 'postPersistHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyContractListener', 'prePersistHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'CompanyContractListener', 'postUpdateHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'CompanyContractListener', 'preUpdateHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'CompanyContractListener', 'postRemoveHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'CompanyContractListener', 'preRemoveHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'CompanyContractListener', 'preFlushHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'CompanyContractListener', 'postLoadHandler'); } } diff --git a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php similarity index 98% rename from tests/Doctrine/Tests/Models/Company/ContractSubscriber.php rename to tests/Doctrine/Tests/Models/Company/CompanyContractListener.php index 64e953a34..9382660bc 100644 --- a/tests/Doctrine/Tests/Models/Company/ContractSubscriber.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php @@ -2,7 +2,7 @@ namespace Doctrine\Tests\Models\Company; -class ContractSubscriber +class CompanyContractListener { static public $postPersistCalls; static public $prePersistCalls; diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php index d193d07d9..85126bd0e 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php @@ -4,7 +4,7 @@ namespace Doctrine\Tests\Models\Company; /** * @Entity - * @EntityListeners({"ContractSubscriber","FlexUltraContractSubscriber"}) + * @EntityListeners({"CompanyContractListener","CompanyFlexUltraContractListener"}) */ class CompanyFlexUltraContract extends CompanyFlexContract { @@ -36,19 +36,19 @@ class CompanyFlexUltraContract extends CompanyFlexContract 'name' => 'maxPrice', 'fieldName' => 'maxPrice', )); - $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CompanyContractListener', 'postPersistHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyContractListener', 'prePersistHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'CompanyContractListener', 'postUpdateHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'CompanyContractListener', 'preUpdateHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'CompanyContractListener', 'postRemoveHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'CompanyContractListener', 'preRemoveHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'CompanyContractListener', 'preFlushHandler'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'CompanyContractListener', 'postLoadHandler'); - $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler1'); - $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler2'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyFlexUltraContractListener', 'prePersistHandler1'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyFlexUltraContractListener', 'prePersistHandler2'); } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php similarity index 94% rename from tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php rename to tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php index 408bcad70..04f2dd2ea 100644 --- a/tests/Doctrine/Tests/Models/Company/FlexUltraContractSubscriber.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php @@ -4,7 +4,7 @@ namespace Doctrine\Tests\Models\Company; use Doctrine\ORM\Event\LifecycleEventArgs; -class FlexUltraContractSubscriber +class CompanyFlexUltraContractListener { static public $prePersistCalls; static public $instances; diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php index 857fe7383..dcc8393e0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php @@ -3,7 +3,7 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\Company\CompanyFixContract; -use Doctrine\Tests\Models\Company\ContractSubscriber; +use Doctrine\Tests\Models\Company\CompanyContractListener; require_once __DIR__ . '/../../TestInit.php'; @@ -24,24 +24,24 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $fix = new CompanyFixContract(); $fix->setFixPrice(2000); - ContractSubscriber::$preFlushCalls = array(); + CompanyContractListener::$preFlushCalls = array(); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$preFlushCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$preFlushCalls); - $this->assertSame($fix, ContractSubscriber::$preFlushCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$preFlushCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$preFlushCalls[0][0] + CompanyContractListener::$preFlushCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\PreFlushEventArgs', - ContractSubscriber::$preFlushCalls[0][1] + CompanyContractListener::$preFlushCalls[0][1] ); } @@ -54,24 +54,24 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->flush(); $this->_em->clear(); - ContractSubscriber::$postLoadCalls = array(); + CompanyContractListener::$postLoadCalls = array(); $dql = "SELECT f FROM Doctrine\Tests\Models\Company\CompanyFixContract f WHERE f.id = ?1"; $fix = $this->_em->createQuery($dql)->setParameter(1, $fix->getId())->getSingleResult(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$postLoadCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$postLoadCalls); - $this->assertSame($fix, ContractSubscriber::$postLoadCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$postLoadCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$postLoadCalls[0][0] + CompanyContractListener::$postLoadCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - ContractSubscriber::$postLoadCalls[0][1] + CompanyContractListener::$postLoadCalls[0][1] ); } @@ -80,24 +80,24 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $fix = new CompanyFixContract(); $fix->setFixPrice(2000); - ContractSubscriber::$prePersistCalls = array(); + CompanyContractListener::$prePersistCalls = array(); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$prePersistCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$prePersistCalls); - $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$prePersistCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$prePersistCalls[0][0] + CompanyContractListener::$prePersistCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - ContractSubscriber::$prePersistCalls[0][1] + CompanyContractListener::$prePersistCalls[0][1] ); } @@ -106,24 +106,24 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $fix = new CompanyFixContract(); $fix->setFixPrice(2000); - ContractSubscriber::$postPersistCalls = array(); + CompanyContractListener::$postPersistCalls = array(); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$postPersistCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$postPersistCalls); - $this->assertSame($fix, ContractSubscriber::$postPersistCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$postPersistCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$postPersistCalls[0][0] + CompanyContractListener::$postPersistCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - ContractSubscriber::$postPersistCalls[0][1] + CompanyContractListener::$postPersistCalls[0][1] ); } @@ -135,26 +135,26 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - ContractSubscriber::$preUpdateCalls = array(); + CompanyContractListener::$preUpdateCalls = array(); $fix->setFixPrice(2000); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$preUpdateCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$preUpdateCalls); - $this->assertSame($fix, ContractSubscriber::$preUpdateCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$preUpdateCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$preUpdateCalls[0][0] + CompanyContractListener::$preUpdateCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\PreUpdateEventArgs', - ContractSubscriber::$preUpdateCalls[0][1] + CompanyContractListener::$preUpdateCalls[0][1] ); } @@ -166,26 +166,26 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - ContractSubscriber::$postUpdateCalls = array(); + CompanyContractListener::$postUpdateCalls = array(); $fix->setFixPrice(2000); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$postUpdateCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$postUpdateCalls); - $this->assertSame($fix, ContractSubscriber::$postUpdateCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$postUpdateCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$postUpdateCalls[0][0] + CompanyContractListener::$postUpdateCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - ContractSubscriber::$postUpdateCalls[0][1] + CompanyContractListener::$postUpdateCalls[0][1] ); } @@ -197,24 +197,24 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - ContractSubscriber::$preRemoveCalls = array(); + CompanyContractListener::$preRemoveCalls = array(); $this->_em->remove($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$preRemoveCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$preRemoveCalls); - $this->assertSame($fix, ContractSubscriber::$preRemoveCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$preRemoveCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$preRemoveCalls[0][0] + CompanyContractListener::$preRemoveCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - ContractSubscriber::$preRemoveCalls[0][1] + CompanyContractListener::$preRemoveCalls[0][1] ); } @@ -226,24 +226,24 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - ContractSubscriber::$postRemoveCalls = array(); + CompanyContractListener::$postRemoveCalls = array(); $this->_em->remove($fix); $this->_em->flush(); - $this->assertCount(1,ContractSubscriber::$instances); - $this->assertCount(1,ContractSubscriber::$postRemoveCalls); + $this->assertCount(1,CompanyContractListener::$instances); + $this->assertCount(1,CompanyContractListener::$postRemoveCalls); - $this->assertSame($fix, ContractSubscriber::$postRemoveCalls[0][0]); + $this->assertSame($fix, CompanyContractListener::$postRemoveCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - ContractSubscriber::$postRemoveCalls[0][0] + CompanyContractListener::$postRemoveCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - ContractSubscriber::$postRemoveCalls[0][1] + CompanyContractListener::$postRemoveCalls[0][1] ); } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index dc8030f20..e4a9e0530 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -6,8 +6,8 @@ use Doctrine\ORM\Events; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\Tests\Models\Company\CompanyFixContract; use Doctrine\Tests\Models\Company\CompanyFlexContract; -use Doctrine\Tests\Models\Company\ContractSubscriber; -use Doctrine\Tests\Models\Company\FlexUltraContractSubscriber; +use Doctrine\Tests\Models\Company\CompanyContractListener; +use Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataInfo; @@ -774,8 +774,8 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $postPersist = $superClass->entityListeners[Events::postPersist][0]; $prePersist = $superClass->entityListeners[Events::prePersist][0]; - $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $postPersist['class']); - $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $prePersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $postPersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $prePersist['class']); $this->assertEquals('postPersistHandler', $postPersist['method']); $this->assertEquals('prePersistHandler', $prePersist['method']); @@ -793,17 +793,17 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $postPersist = $ultraClass->entityListeners[Events::postPersist][0]; $prePersist = $ultraClass->entityListeners[Events::prePersist][0]; - $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $postPersist['class']); - $this->assertEquals('Doctrine\Tests\Models\Company\ContractSubscriber', $prePersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $postPersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $prePersist['class']); $this->assertEquals('postPersistHandler', $postPersist['method']); $this->assertEquals('prePersistHandler', $prePersist['method']); $prePersist = $ultraClass->entityListeners[Events::prePersist][1]; - $this->assertEquals('Doctrine\Tests\Models\Company\FlexUltraContractSubscriber', $prePersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']); $this->assertEquals('prePersistHandler1', $prePersist['method']); $prePersist = $ultraClass->entityListeners[Events::prePersist][2]; - $this->assertEquals('Doctrine\Tests\Models\Company\FlexUltraContractSubscriber', $prePersist['class']); + $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']); $this->assertEquals('prePersistHandler2', $prePersist['method']); } @@ -818,9 +818,9 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); - ContractSubscriber::$prePersistCalls = array(); - ContractSubscriber::$postPersistCalls = array(); - FlexUltraContractSubscriber::$prePersistCalls = array(); + CompanyContractListener::$prePersistCalls = array(); + CompanyContractListener::$postPersistCalls = array(); + CompanyFlexUltraContractListener::$prePersistCalls = array(); $fix = new CompanyFixContract(); $fixArg = new LifecycleEventArgs($fix, $em); @@ -835,26 +835,26 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $flexClass->dispatchEntityListeners(Events::prePersist, $flex, $flexArg); $ultraClass->dispatchEntityListeners(Events::prePersist, $ultra, $ultraArg); - $this->assertCount(3, ContractSubscriber::$prePersistCalls); - $this->assertCount(2, FlexUltraContractSubscriber::$prePersistCalls); + $this->assertCount(3, CompanyContractListener::$prePersistCalls); + $this->assertCount(2, CompanyFlexUltraContractListener::$prePersistCalls); - $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]); - $this->assertSame($fixArg, ContractSubscriber::$prePersistCalls[0][1]); + $this->assertSame($fix, CompanyContractListener::$prePersistCalls[0][0]); + $this->assertSame($fixArg, CompanyContractListener::$prePersistCalls[0][1]); - $this->assertSame($flex, ContractSubscriber::$prePersistCalls[1][0]); - $this->assertSame($flexArg, ContractSubscriber::$prePersistCalls[1][1]); + $this->assertSame($flex, CompanyContractListener::$prePersistCalls[1][0]); + $this->assertSame($flexArg, CompanyContractListener::$prePersistCalls[1][1]); - $this->assertSame($ultra, ContractSubscriber::$prePersistCalls[2][0]); - $this->assertSame($ultraArg, ContractSubscriber::$prePersistCalls[2][1]); + $this->assertSame($ultra, CompanyContractListener::$prePersistCalls[2][0]); + $this->assertSame($ultraArg, CompanyContractListener::$prePersistCalls[2][1]); - $this->assertSame($ultra, FlexUltraContractSubscriber::$prePersistCalls[0][0]); - $this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[0][1]); + $this->assertSame($ultra, CompanyFlexUltraContractListener::$prePersistCalls[0][0]); + $this->assertSame($ultraArg, CompanyFlexUltraContractListener::$prePersistCalls[0][1]); - $this->assertSame($ultra, FlexUltraContractSubscriber::$prePersistCalls[1][0]); - $this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[1][1]); + $this->assertSame($ultra, CompanyFlexUltraContractListener::$prePersistCalls[1][0]); + $this->assertSame($ultraArg, CompanyFlexUltraContractListener::$prePersistCalls[1][1]); - $this->assertCount(1, ContractSubscriber::$instances); - $this->assertEmpty(ContractSubscriber::$postPersistCalls); + $this->assertCount(1, CompanyContractListener::$instances); + $this->assertEmpty(CompanyContractListener::$postPersistCalls); } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index 2f79b967c..41f2ffa2f 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -1016,14 +1016,14 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase * @group DDC-1955 * * @expectedException Doctrine\ORM\Mapping\MappingException - * @expectedExceptionMessage Entity Listener "\Doctrine\Tests\Models\Company\ContractSubscriber" declared on "Doctrine\Tests\Models\CMS\CmsUser" has no method "invalidMethod". + * @expectedExceptionMessage Entity Listener "\Doctrine\Tests\Models\Company\CompanyContractListener" declared on "Doctrine\Tests\Models\CMS\CmsUser" has no method "invalidMethod". */ public function testInvalidEntityListenerMethodException() { $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); - $cm->addEntityListener(Events::postLoad, '\Doctrine\Tests\Models\Company\ContractSubscriber', 'invalidMethod'); + $cm->addEntityListener(Events::postLoad, '\Doctrine\Tests\Models\Company\CompanyContractListener', 'invalidMethod'); } } diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php index 636b952c9..fdb8d5d02 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php @@ -27,14 +27,14 @@ $metadata->setDiscriminatorMap(array( "flexultra" => "CompanyFlexUltraContract" )); -$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CompanyContractListener', 'postPersistHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyContractListener', 'prePersistHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'CompanyContractListener', 'postUpdateHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'CompanyContractListener', 'preUpdateHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'CompanyContractListener', 'postRemoveHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'CompanyContractListener', 'preRemoveHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); \ No newline at end of file +$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'CompanyContractListener', 'preFlushHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'CompanyContractListener', 'postLoadHandler'); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php index 31e4b60c0..d16d4f3f5 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php @@ -5,17 +5,17 @@ $metadata->mapField(array( 'name' => 'maxPrice', 'fieldName' => 'maxPrice', )); -$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'ContractSubscriber', 'postPersistHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'ContractSubscriber', 'prePersistHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CompanyContractListener', 'postPersistHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyContractListener', 'prePersistHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'ContractSubscriber', 'postUpdateHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'ContractSubscriber', 'preUpdateHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'CompanyContractListener', 'postUpdateHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'CompanyContractListener', 'preUpdateHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'ContractSubscriber', 'postRemoveHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'ContractSubscriber', 'preRemoveHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'CompanyContractListener', 'postRemoveHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'CompanyContractListener', 'preRemoveHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'ContractSubscriber', 'preFlushHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'ContractSubscriber', 'postLoadHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'CompanyContractListener', 'preFlushHandler'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'CompanyContractListener', 'postLoadHandler'); -$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler1'); -$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'FlexUltraContractSubscriber', 'prePersistHandler2'); \ No newline at end of file +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyFlexUltraContractListener', 'prePersistHandler1'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyFlexUltraContractListener', 'prePersistHandler2'); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml index c4fc7adc8..4f5f843eb 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml @@ -14,7 +14,7 @@ - + diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml index bbe0899f6..e76483736 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml @@ -8,7 +8,7 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml index bdad810c7..e738569e5 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml @@ -9,7 +9,7 @@ Doctrine\Tests\Models\Company\CompanyContract: entityListeners: listener[0]: - class : ContractSubscriber + class : CompanyContractListener preFlush: [preFlushHandler] postLoad: [postLoadHandler] diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml index 1621a6a84..a72e5de38 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml @@ -3,7 +3,7 @@ Doctrine\Tests\Models\Company\CompanyFlexUltraContract: entityListeners: listener[0]: - class : ContractSubscriber + class : CompanyContractListener preFlush: [preFlushHandler] postLoad: [postLoadHandler] @@ -18,7 +18,7 @@ Doctrine\Tests\Models\Company\CompanyFlexUltraContract: preRemove: [preRemoveHandler] listener[1]: - class : FlexUltraContractSubscriber + class : CompanyFlexUltraContractListener prePersist: [prePersistHandler1, prePersistHandler2] From 27745bb87b0e9ef5949d26ad94845a124bcb46f3 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 12 Aug 2012 14:53:00 -0300 Subject: [PATCH 21/41] Fix some CS --- lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 6 ++++-- lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 2 +- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 4 ++-- lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php | 2 +- lib/Doctrine/ORM/Mapping/MappingException.php | 10 ++-------- lib/Doctrine/ORM/UnitOfWork.php | 1 - 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 597256ed7..bae46d34a 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2311,6 +2311,7 @@ class ClassMetadataInfo implements ClassMetadata } $entityResult['entityClass'] = $this->fullyQualifiedClassName($entityResult['entityClass']); + $resultMapping['entities'][$key]['entityClass'] = ltrim($entityResult['entityClass'], '\\'); $resultMapping['entities'][$key]['isSelfClass'] = $entityResult['isSelfClass']; @@ -2496,6 +2497,7 @@ class ClassMetadataInfo implements ClassMetadata * * @param string $callback * @param string $eventName + * @throws \Doctrine\ORM\Mapping\MappingException */ public function addEntityListener($eventName, $class, $method) { @@ -2510,8 +2512,8 @@ class ClassMetadataInfo implements ClassMetadata } $this->entityListeners[$eventName][] = array( - 'class' => $class, - 'method' => $method + 'class' => $class, + 'method' => $method ); } diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index b069364ab..3ddf70c86 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -436,7 +436,7 @@ class AnnotationDriver extends AbstractAnnotationDriver } } - // evaluate as lifecycle callback if the listener class is not given. + // Evaluate as lifecycle callback if the listener class is not given. if(empty($entityListenersAnnot->value)) { /* @var $method \Doctrine\ORM\Mapping\LifecycleCallback */ foreach ($entityListenersAnnot->callbacks as $callback) { diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 22bdf1608..95bb49e5c 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -567,8 +567,8 @@ class XmlDriver extends FileDriver $eventName = $prefix . ucfirst($suffix); $methodName = (string) $callbackElement['method']; - $listeners[] = array($eventName, $methodName); + $listeners[] = array($eventName, $methodName); } if (isset($listenerElement['class'])) { @@ -581,7 +581,7 @@ class XmlDriver extends FileDriver continue; } - // evaluate as lifecycle callback if the listener class is not given. + // Evaluate as lifecycle callback if the listener class is not given. foreach ($listeners as $item) { $metadata->addLifecycleCallback($item[1], $item[0]); } diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index dc9fc3829..a4154871e 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -599,7 +599,7 @@ class YamlDriver extends FileDriver continue; } - // evaluate as lifecycle callback if the listener class is not given. + // Evaluate as lifecycle callback if the listener class is not given. foreach ($listeners as $item){ $metadata->addLifecycleCallback($item[1], $item[0]); } diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index a2688a177..61ecb4d11 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -692,10 +692,7 @@ class MappingException extends \Doctrine\ORM\ORMException */ public static function entityListenerClassNotFound($listenerName, $className) { - return new self(sprintf( - 'Entity Listener "%s" declared on "%s" not found.', - $listenerName, $className - )); + return new self(sprintf('Entity Listener "%s" declared on "%s" not found.', $listenerName, $className)); } /** @@ -707,10 +704,7 @@ class MappingException extends \Doctrine\ORM\ORMException */ public static function entityListenerMethodNotFound($listenerName, $methodName, $className) { - return new self(sprintf( - 'Entity Listener "%s" declared on "%s" has no method "%s".', - $listenerName, $className, $methodName - )); + return new self(sprintf('Entity Listener "%s" declared on "%s" has no method "%s".', $listenerName, $className, $methodName)); } /** diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 1c6cbeeb6..4969a31d6 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -977,7 +977,6 @@ class UnitOfWork implements PropertyChangedListener } foreach ($entities as $entity) { - if ($hasListeners || $hasEntityListeners | $hasLifecycleCallbacks) { $event = new LifecycleEventArgs($entity, $this->em); } From a01d6583d3bcb24984b9904d51c135b66b51403a Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 12 Aug 2012 22:10:47 -0300 Subject: [PATCH 22/41] implements a entity listener resolver --- lib/Doctrine/ORM/Configuration.php | 28 ++++++ .../ORM/Mapping/ClassMetadataInfo.php | 20 ++-- .../Mapping/DefaultEntityListenerResolver.php | 76 ++++++++++++++ .../ORM/Mapping/EntityListenerResolver.php | 55 +++++++++++ lib/Doctrine/ORM/UnitOfWork.php | 28 ++++-- .../Company/CompanyContractListener.php | 39 +++----- .../CompanyFlexUltraContractListener.php | 12 +-- .../Doctrine/Tests/ORM/ConfigurationTest.php | 12 +++ .../ORM/Functional/EntityListenersTest.php | 98 +++++++++--------- .../ORM/Mapping/AbstractMappingDriverTest.php | 54 +++++----- .../ORM/Mapping/ListenerResolverTest.php | 99 +++++++++++++++++++ 11 files changed, 390 insertions(+), 131 deletions(-) create mode 100644 lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php create mode 100644 lib/Doctrine/ORM/Mapping/EntityListenerResolver.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index 5e19d29bd..b0a09cbb5 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -29,6 +29,8 @@ use Doctrine\ORM\Mapping\QuoteStrategy; use Doctrine\ORM\Mapping\DefaultQuoteStrategy; use Doctrine\ORM\Mapping\NamingStrategy; use Doctrine\ORM\Mapping\DefaultNamingStrategy; +use Doctrine\ORM\Mapping\EntityListenerResolver; +use Doctrine\ORM\Mapping\DefaultEntityListenerResolver; use Doctrine\Common\Annotations\SimpleAnnotationReader; use Doctrine\Common\Annotations\CachedReader; @@ -763,4 +765,30 @@ class Configuration extends \Doctrine\DBAL\Configuration return $this->_attributes['quoteStrategy']; } + + /** + * Set the entity listener resolver. + * + * @since 2.4 + * @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver + */ + public function setEntityListenerResolver(EntityListenerResolver $resolver) + { + $this->_attributes['entityListenerResolver'] = $resolver; + } + + /** + * Get the entity listener resolver. + * + * @since 2.4 + * @return \Doctrine\ORM\Mapping\EntityListenerResolver + */ + public function getEntityListenerResolver() + { + if ( ! isset($this->_attributes['entityListenerResolver'])) { + $this->_attributes['entityListenerResolver'] = new DefaultEntityListenerResolver(); + } + + return $this->_attributes['entityListenerResolver']; + } } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index bae46d34a..0ec517d20 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -27,6 +27,7 @@ use ReflectionClass; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\ClassLoader; use Doctrine\Common\EventArgs; +use Doctrine\ORM\Mapping\EntityListenerResolver; /** * A ClassMetadata instance holds all the object-relational mapping metadata @@ -444,11 +445,6 @@ class ClassMetadataInfo implements ClassMetadata */ public $entityListeners = array(); - /** - * @var array entity listeners instances. - */ - static private $entityListenerInstances = array(); - /** * READ-ONLY: The association mappings of this class. * @@ -2520,21 +2516,19 @@ class ClassMetadataInfo implements ClassMetadata /** * Call the entity listeners. * + * @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver The Entity listener resolver. * @param string $eventName The event name. * @param object $entity An instance of the mapped entity * @param \Doctrine\Common\EventArgs $arg The Event args */ - public function dispatchEntityListeners($eventName, $entity, EventArgs $arg) + public function dispatchEntityListeners(EntityListenerResolver $resolver, $eventName, $entity, EventArgs $arg) { foreach ($this->entityListeners[$eventName] as $listener) { - $class = $listener['class']; - $method = $listener['method']; + $class = $listener['class']; + $method = $listener['method']; + $instance = $resolver->resolve($class); - if ( ! isset(self::$entityListenerInstances[$class])) { - self::$entityListenerInstances[$class] = new $class(); - } - - self::$entityListenerInstances[$class]->{$method}($entity, $arg); + $instance->{$method}($entity, $arg); } } diff --git a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php new file mode 100644 index 000000000..75657e237 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php @@ -0,0 +1,76 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * The default DefaultEntityListene + * + * @since 2.4 + * @author Fabio B. Silva + */ +class DefaultEntityListenerResolver implements EntityListenerResolver +{ + /** + * @var array Map to store entity listener instances. + */ + private $instances = array(); + + /** + * {@inheritdoc} + */ + public function clear($className = null) + { + if ($className !== null) { + + if (isset($this->instances[$className = trim($className, '\\')])) { + unset($this->instances[$className]); + } + + return; + } + + $this->instances = array(); + } + + /** + * {@inheritdoc}" + */ + public function register($object) + { + if ( ! is_object($object)) { + throw new \InvalidArgumentException(sprintf('An object was expected, but got "%s.', gettype($object))); + } + + $this->instances[get_class($object)] = $object; + } + + /** + * {@inheritdoc} + */ + public function resolve($className) + { + if (isset($this->instances[$className = trim($className, '\\')])) { + return $this->instances[$className]; + } + + return $this->instances[$className] = new $className(); + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php new file mode 100644 index 000000000..bbf498dc3 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php @@ -0,0 +1,55 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * A resolver is used to instantiate an entity listener. + * + * @since 2.4 + * @author Fabio B. Silva + */ +interface EntityListenerResolver +{ + /** + * Clear all instances from the set, or a specific class when given. + * + * @param string $className The fully-qualified class name + * + * @return void + */ + function clear($className = null); + + /** + * Returns a entity listener instance for the given class name. + * + * @param string $className The fully-qualified class name + * + * @return object An entity listener + */ + function resolve($className); + + /** + * Register a entity listener instance. + * + * @return object An entity listener + */ + function register($object); +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 4969a31d6..b3904c981 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -218,6 +218,13 @@ class UnitOfWork implements PropertyChangedListener */ private $evm; + /** + * The EntityListenerResolver used for dispatching events. + * + * @var \Doctrine\ORM\Mapping\EntityListenerResolver + */ + private $entityListenerResolver; + /** * Orphaned entities that are scheduled for removal. * @@ -246,8 +253,9 @@ class UnitOfWork implements PropertyChangedListener */ public function __construct(EntityManager $em) { - $this->em = $em; - $this->evm = $em->getEventManager(); + $this->em = $em; + $this->evm = $em->getEventManager(); + $this->entityListenerResolver = $em->getConfiguration()->getEntityListenerResolver(); } /** @@ -525,7 +533,7 @@ class UnitOfWork implements PropertyChangedListener // Fire PreFlush entity listeners if ($hasEntityListeners) { - $class->dispatchEntityListeners(Events::preFlush, $entity, $event); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::preFlush, $entity, $event); } $actualData = array(); @@ -836,7 +844,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasEntityListeners) { - $class->dispatchEntityListeners(Events::prePersist, $entity, $event); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::prePersist, $entity, $event); } if ($hasListeners) { @@ -986,7 +994,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasEntityListeners) { - $class->dispatchEntityListeners(Events::postPersist, $entity, $event); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::postPersist, $entity, $event); } if ($hasListeners) { @@ -1035,7 +1043,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasPreUpdateEntityListeners) { - $class->dispatchEntityListeners(Events::preUpdate, $entity, $preEvent); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::preUpdate, $entity, $preEvent); } if ($hasPreUpdateListeners) { @@ -1053,7 +1061,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasPostUpdateEntityListeners) { - $class->dispatchEntityListeners(Events::postUpdate, $entity, $postEvent); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::postUpdate, $entity, $postEvent); } if ($hasPostUpdateListeners) { @@ -1108,7 +1116,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasEntityListeners) { - $class->dispatchEntityListeners(Events::postRemove, $entity, $event); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::postRemove, $entity, $event); } if ($hasListeners) { @@ -1765,7 +1773,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasEntityListeners) { - $class->dispatchEntityListeners(Events::preRemove, $entity, $event); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::preRemove, $entity, $event); } if ($hasListeners) { @@ -2781,7 +2789,7 @@ class UnitOfWork implements PropertyChangedListener } if ($hasEntityListeners) { - $class->dispatchEntityListeners(Events::postLoad, $entity, $event); + $class->dispatchEntityListeners($this->entityListenerResolver, Events::postLoad, $entity, $event); } if ($hasListeners) { diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php b/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php index 9382660bc..61c1d4719 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php @@ -4,32 +4,25 @@ namespace Doctrine\Tests\Models\Company; class CompanyContractListener { - static public $postPersistCalls; - static public $prePersistCalls; + public $postPersistCalls; + public $prePersistCalls; - static public $postUpdateCalls; - static public $preUpdateCalls; + public $postUpdateCalls; + public $preUpdateCalls; - static public $postRemoveCalls; - static public $preRemoveCalls; + public $postRemoveCalls; + public $preRemoveCalls; - static public $preFlushCalls; + public $preFlushCalls; - static public $postLoadCalls; + public $postLoadCalls; - static public $instances; - - public function __construct() - { - self::$instances[] = $this; - } - /** * @PostPersist */ public function postPersistHandler(CompanyContract $contract) { - self::$postPersistCalls[] = func_get_args(); + $this->postPersistCalls[] = func_get_args(); } /** @@ -37,7 +30,7 @@ class CompanyContractListener */ public function prePersistHandler(CompanyContract $contract) { - self::$prePersistCalls[] = func_get_args(); + $this->prePersistCalls[] = func_get_args(); } /** @@ -45,7 +38,7 @@ class CompanyContractListener */ public function postUpdateHandler(CompanyContract $contract) { - self::$postUpdateCalls[] = func_get_args(); + $this->postUpdateCalls[] = func_get_args(); } /** @@ -53,7 +46,7 @@ class CompanyContractListener */ public function preUpdateHandler(CompanyContract $contract) { - self::$preUpdateCalls[] = func_get_args(); + $this->preUpdateCalls[] = func_get_args(); } /** @@ -61,7 +54,7 @@ class CompanyContractListener */ public function postRemoveHandler(CompanyContract $contract) { - self::$postRemoveCalls[] = func_get_args(); + $this->postRemoveCalls[] = func_get_args(); } /** @@ -69,7 +62,7 @@ class CompanyContractListener */ public function preRemoveHandler(CompanyContract $contract) { - self::$preRemoveCalls[] = func_get_args(); + $this->preRemoveCalls[] = func_get_args(); } /** @@ -77,7 +70,7 @@ class CompanyContractListener */ public function preFlushHandler(CompanyContract $contract) { - self::$preFlushCalls[] = func_get_args(); + $this->preFlushCalls[] = func_get_args(); } /** @@ -85,7 +78,7 @@ class CompanyContractListener */ public function postLoadHandler(CompanyContract $contract) { - self::$postLoadCalls[] = func_get_args(); + $this->postLoadCalls[] = func_get_args(); } } diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php index 04f2dd2ea..2f028e35f 100644 --- a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php +++ b/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php @@ -6,20 +6,14 @@ use Doctrine\ORM\Event\LifecycleEventArgs; class CompanyFlexUltraContractListener { - static public $prePersistCalls; - static public $instances; - - public function __construct() - { - self::$instances[] = $this; - } + public $prePersistCalls; /** * @PrePersist */ public function prePersistHandler1(CompanyContract $contract, LifecycleEventArgs $args) { - self::$prePersistCalls[] = func_get_args(); + $this->prePersistCalls[] = func_get_args(); } /** @@ -27,6 +21,6 @@ class CompanyFlexUltraContractListener */ public function prePersistHandler2(CompanyContract $contract, LifecycleEventArgs $args) { - self::$prePersistCalls[] = func_get_args(); + $this->prePersistCalls[] = func_get_args(); } } diff --git a/tests/Doctrine/Tests/ORM/ConfigurationTest.php b/tests/Doctrine/Tests/ORM/ConfigurationTest.php index 1caaf5701..57ec1ce1c 100644 --- a/tests/Doctrine/Tests/ORM/ConfigurationTest.php +++ b/tests/Doctrine/Tests/ORM/ConfigurationTest.php @@ -260,6 +260,18 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase $this->configuration->setQuoteStrategy($quoteStrategy); $this->assertSame($quoteStrategy, $this->configuration->getQuoteStrategy()); } + + /** + * @group DDC-1955 + */ + public function testSetGetEntityListenerResolver() + { + $this->assertInstanceOf('Doctrine\ORM\Mapping\EntityListenerResolver', $this->configuration->getEntityListenerResolver()); + $this->assertInstanceOf('Doctrine\ORM\Mapping\DefaultEntityListenerResolver', $this->configuration->getEntityListenerResolver()); + $quoteStrategy = $this->getMock('Doctrine\ORM\Mapping\EntityListenerResolver'); + $this->configuration->setEntityListenerResolver($quoteStrategy); + $this->assertSame($quoteStrategy, $this->configuration->getEntityListenerResolver()); + } } class ConfigurationTestAnnotationReaderChecker diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php index dcc8393e0..fc6048e60 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php @@ -3,7 +3,6 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\Company\CompanyFixContract; -use Doctrine\Tests\Models\Company\CompanyContractListener; require_once __DIR__ . '/../../TestInit.php'; @@ -13,10 +12,19 @@ require_once __DIR__ . '/../../TestInit.php'; class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase { + /** + * @var \Doctrine\Tests\Models\Company\CompanyContractListener + */ + private $listener; + protected function setUp() { $this->useModelSet('company'); parent::setUp(); + + $this->listener = $this->_em->getConfiguration() + ->getEntityListenerResolver() + ->resolve('Doctrine\Tests\Models\Company\CompanyContractListener'); } public function testPreFlushListeners() @@ -24,24 +32,23 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $fix = new CompanyFixContract(); $fix->setFixPrice(2000); - CompanyContractListener::$preFlushCalls = array(); + $this->listener->preFlushCalls = array(); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$preFlushCalls); + $this->assertCount(1,$this->listener->preFlushCalls); - $this->assertSame($fix, CompanyContractListener::$preFlushCalls[0][0]); + $this->assertSame($fix, $this->listener->preFlushCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$preFlushCalls[0][0] + $this->listener->preFlushCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\PreFlushEventArgs', - CompanyContractListener::$preFlushCalls[0][1] + $this->listener->preFlushCalls[0][1] ); } @@ -54,24 +61,23 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->flush(); $this->_em->clear(); - CompanyContractListener::$postLoadCalls = array(); + $this->listener->postLoadCalls = array(); $dql = "SELECT f FROM Doctrine\Tests\Models\Company\CompanyFixContract f WHERE f.id = ?1"; $fix = $this->_em->createQuery($dql)->setParameter(1, $fix->getId())->getSingleResult(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$postLoadCalls); + $this->assertCount(1,$this->listener->postLoadCalls); - $this->assertSame($fix, CompanyContractListener::$postLoadCalls[0][0]); + $this->assertSame($fix, $this->listener->postLoadCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$postLoadCalls[0][0] + $this->listener->postLoadCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - CompanyContractListener::$postLoadCalls[0][1] + $this->listener->postLoadCalls[0][1] ); } @@ -80,24 +86,23 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $fix = new CompanyFixContract(); $fix->setFixPrice(2000); - CompanyContractListener::$prePersistCalls = array(); + $this->listener->prePersistCalls = array(); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$prePersistCalls); + $this->assertCount(1,$this->listener->prePersistCalls); - $this->assertSame($fix, CompanyContractListener::$prePersistCalls[0][0]); + $this->assertSame($fix, $this->listener->prePersistCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$prePersistCalls[0][0] + $this->listener->prePersistCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - CompanyContractListener::$prePersistCalls[0][1] + $this->listener->prePersistCalls[0][1] ); } @@ -106,24 +111,23 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $fix = new CompanyFixContract(); $fix->setFixPrice(2000); - CompanyContractListener::$postPersistCalls = array(); + $this->listener->postPersistCalls = array(); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$postPersistCalls); + $this->assertCount(1,$this->listener->postPersistCalls); - $this->assertSame($fix, CompanyContractListener::$postPersistCalls[0][0]); + $this->assertSame($fix, $this->listener->postPersistCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$postPersistCalls[0][0] + $this->listener->postPersistCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - CompanyContractListener::$postPersistCalls[0][1] + $this->listener->postPersistCalls[0][1] ); } @@ -135,26 +139,25 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - CompanyContractListener::$preUpdateCalls = array(); + $this->listener->preUpdateCalls = array(); $fix->setFixPrice(2000); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$preUpdateCalls); + $this->assertCount(1,$this->listener->preUpdateCalls); - $this->assertSame($fix, CompanyContractListener::$preUpdateCalls[0][0]); + $this->assertSame($fix, $this->listener->preUpdateCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$preUpdateCalls[0][0] + $this->listener->preUpdateCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\PreUpdateEventArgs', - CompanyContractListener::$preUpdateCalls[0][1] + $this->listener->preUpdateCalls[0][1] ); } @@ -166,26 +169,25 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - CompanyContractListener::$postUpdateCalls = array(); + $this->listener->postUpdateCalls = array(); $fix->setFixPrice(2000); $this->_em->persist($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$postUpdateCalls); + $this->assertCount(1,$this->listener->postUpdateCalls); - $this->assertSame($fix, CompanyContractListener::$postUpdateCalls[0][0]); + $this->assertSame($fix, $this->listener->postUpdateCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$postUpdateCalls[0][0] + $this->listener->postUpdateCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - CompanyContractListener::$postUpdateCalls[0][1] + $this->listener->postUpdateCalls[0][1] ); } @@ -197,24 +199,23 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - CompanyContractListener::$preRemoveCalls = array(); + $this->listener->preRemoveCalls = array(); $this->_em->remove($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$preRemoveCalls); + $this->assertCount(1,$this->listener->preRemoveCalls); - $this->assertSame($fix, CompanyContractListener::$preRemoveCalls[0][0]); + $this->assertSame($fix, $this->listener->preRemoveCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$preRemoveCalls[0][0] + $this->listener->preRemoveCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - CompanyContractListener::$preRemoveCalls[0][1] + $this->listener->preRemoveCalls[0][1] ); } @@ -226,24 +227,23 @@ class EntityListenersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->persist($fix); $this->_em->flush(); - CompanyContractListener::$postRemoveCalls = array(); + $this->listener->postRemoveCalls = array(); $this->_em->remove($fix); $this->_em->flush(); - $this->assertCount(1,CompanyContractListener::$instances); - $this->assertCount(1,CompanyContractListener::$postRemoveCalls); + $this->assertCount(1,$this->listener->postRemoveCalls); - $this->assertSame($fix, CompanyContractListener::$postRemoveCalls[0][0]); + $this->assertSame($fix, $this->listener->postRemoveCalls[0][0]); $this->assertInstanceOf( 'Doctrine\Tests\Models\Company\CompanyFixContract', - CompanyContractListener::$postRemoveCalls[0][0] + $this->listener->postRemoveCalls[0][0] ); $this->assertInstanceOf( 'Doctrine\ORM\Event\LifecycleEventArgs', - CompanyContractListener::$postRemoveCalls[0][1] + $this->listener->postRemoveCalls[0][1] ); } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index e4a9e0530..41df5127f 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -6,8 +6,6 @@ use Doctrine\ORM\Events; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\Tests\Models\Company\CompanyFixContract; use Doctrine\Tests\Models\Company\CompanyFlexContract; -use Doctrine\Tests\Models\Company\CompanyContractListener; -use Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataInfo; @@ -812,15 +810,18 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase */ public function testCallEntityListeners() { - $em = $this->_getTestEntityManager(); - $factory = $this->createClassMetadataFactory($em); - $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); - $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); - $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); + $em = $this->_getTestEntityManager(); + $factory = $this->createClassMetadataFactory($em); + $resolver = $em->getConfiguration()->getEntityListenerResolver(); + $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); + $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); + $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); + $contractListener = $resolver->resolve('Doctrine\Tests\Models\Company\CompanyContractListener'); + $ultraContractListener = $resolver->resolve('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener'); - CompanyContractListener::$prePersistCalls = array(); - CompanyContractListener::$postPersistCalls = array(); - CompanyFlexUltraContractListener::$prePersistCalls = array(); + $contractListener->prePersistCalls = array(); + $contractListener->postPersistCalls = array(); + $ultraContractListener->prePersistCalls = array(); $fix = new CompanyFixContract(); $fixArg = new LifecycleEventArgs($fix, $em); @@ -831,30 +832,29 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $ultra = new CompanyFlexContract(); $ultraArg = new LifecycleEventArgs($ultra, $em); - $fixClass->dispatchEntityListeners(Events::prePersist, $fix, $fixArg); - $flexClass->dispatchEntityListeners(Events::prePersist, $flex, $flexArg); - $ultraClass->dispatchEntityListeners(Events::prePersist, $ultra, $ultraArg); + $fixClass->dispatchEntityListeners($resolver, Events::prePersist, $fix, $fixArg); + $flexClass->dispatchEntityListeners($resolver, Events::prePersist, $flex, $flexArg); + $ultraClass->dispatchEntityListeners($resolver, Events::prePersist, $ultra, $ultraArg); - $this->assertCount(3, CompanyContractListener::$prePersistCalls); - $this->assertCount(2, CompanyFlexUltraContractListener::$prePersistCalls); + $this->assertCount(3, $contractListener->prePersistCalls); + $this->assertCount(2, $ultraContractListener->prePersistCalls); - $this->assertSame($fix, CompanyContractListener::$prePersistCalls[0][0]); - $this->assertSame($fixArg, CompanyContractListener::$prePersistCalls[0][1]); + $this->assertSame($fix, $contractListener->prePersistCalls[0][0]); + $this->assertSame($fixArg, $contractListener->prePersistCalls[0][1]); - $this->assertSame($flex, CompanyContractListener::$prePersistCalls[1][0]); - $this->assertSame($flexArg, CompanyContractListener::$prePersistCalls[1][1]); + $this->assertSame($flex, $contractListener->prePersistCalls[1][0]); + $this->assertSame($flexArg, $contractListener->prePersistCalls[1][1]); - $this->assertSame($ultra, CompanyContractListener::$prePersistCalls[2][0]); - $this->assertSame($ultraArg, CompanyContractListener::$prePersistCalls[2][1]); + $this->assertSame($ultra, $contractListener->prePersistCalls[2][0]); + $this->assertSame($ultraArg, $contractListener->prePersistCalls[2][1]); - $this->assertSame($ultra, CompanyFlexUltraContractListener::$prePersistCalls[0][0]); - $this->assertSame($ultraArg, CompanyFlexUltraContractListener::$prePersistCalls[0][1]); + $this->assertSame($ultra, $ultraContractListener->prePersistCalls[0][0]); + $this->assertSame($ultraArg, $ultraContractListener->prePersistCalls[0][1]); - $this->assertSame($ultra, CompanyFlexUltraContractListener::$prePersistCalls[1][0]); - $this->assertSame($ultraArg, CompanyFlexUltraContractListener::$prePersistCalls[1][1]); + $this->assertSame($ultra, $ultraContractListener->prePersistCalls[1][0]); + $this->assertSame($ultraArg, $ultraContractListener->prePersistCalls[1][1]); - $this->assertCount(1, CompanyContractListener::$instances); - $this->assertEmpty(CompanyContractListener::$postPersistCalls); + $this->assertEmpty($contractListener->postPersistCalls); } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php b/tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php new file mode 100644 index 000000000..f54709097 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php @@ -0,0 +1,99 @@ +resolver = new DefaultEntityListenerResolver(); + } + + public function testResolve() + { + $className = '\Doctrine\Tests\Models\Company\CompanyContractListener'; + $object = $this->resolver->resolve($className); + + $this->assertInstanceOf($className, $object); + $this->assertSame($object, $this->resolver->resolve($className)); + } + + public function testRegisterAndResolve() + { + $className = '\Doctrine\Tests\Models\Company\CompanyContractListener'; + $object = new $className(); + + $this->resolver->register($object); + + $this->assertSame($object, $this->resolver->resolve($className)); + } + + public function testClearOne() + { + $className1 = '\Doctrine\Tests\Models\Company\CompanyContractListener'; + $className2 = '\Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener'; + + $obj1 = $this->resolver->resolve($className1); + $obj2 = $this->resolver->resolve($className2); + + $this->assertInstanceOf($className1, $obj1); + $this->assertInstanceOf($className2, $obj2); + + $this->assertSame($obj1, $this->resolver->resolve($className1)); + $this->assertSame($obj2, $this->resolver->resolve($className2)); + + $this->resolver->clear($className1); + + $this->assertInstanceOf($className1, $this->resolver->resolve($className1)); + $this->assertInstanceOf($className2, $this->resolver->resolve($className2)); + + $this->assertNotSame($obj1, $this->resolver->resolve($className1)); + $this->assertSame($obj2, $this->resolver->resolve($className2)); + } + + public function testClearAll() + { + $className1 = '\Doctrine\Tests\Models\Company\CompanyContractListener'; + $className2 = '\Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener'; + + $obj1 = $this->resolver->resolve($className1); + $obj2 = $this->resolver->resolve($className2); + + $this->assertInstanceOf($className1, $obj1); + $this->assertInstanceOf($className2, $obj2); + + $this->assertSame($obj1, $this->resolver->resolve($className1)); + $this->assertSame($obj2, $this->resolver->resolve($className2)); + + $this->resolver->clear(); + + $this->assertInstanceOf($className1, $this->resolver->resolve($className1)); + $this->assertInstanceOf($className2, $this->resolver->resolve($className2)); + + $this->assertNotSame($obj1, $this->resolver->resolve($className1)); + $this->assertNotSame($obj2, $this->resolver->resolve($className2)); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage An object was expected, but got "string. + */ + public function testRegisterStringException() + { + $this->resolver->register('CompanyContractListener'); + } +} \ No newline at end of file From 8495eca1a4836ed2233c1f12e32d4e9c4044f6ba Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 12 Aug 2012 22:20:03 -0300 Subject: [PATCH 23/41] rename test --- lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php | 2 +- ...istenerResolverTest.php => EntityListenerResolverTest.php} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename tests/Doctrine/Tests/ORM/Mapping/{ListenerResolverTest.php => EntityListenerResolverTest.php} (97%) diff --git a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php index 75657e237..5f7d70410 100644 --- a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php +++ b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php @@ -56,7 +56,7 @@ class DefaultEntityListenerResolver implements EntityListenerResolver public function register($object) { if ( ! is_object($object)) { - throw new \InvalidArgumentException(sprintf('An object was expected, but got "%s.', gettype($object))); + throw new \InvalidArgumentException(sprintf('An object was expected, but got "%s".', gettype($object))); } $this->instances[get_class($object)] = $object; diff --git a/tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php b/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php similarity index 97% rename from tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php rename to tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php index f54709097..a17103391 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ListenerResolverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php @@ -9,7 +9,7 @@ require_once __DIR__ . '/../../TestInit.php'; /** * @group DDC-1955 */ -class ListenerResolverTest extends \Doctrine\Tests\OrmTestCase +class EntityListenerResolverTest extends \Doctrine\Tests\OrmTestCase { /** @@ -90,7 +90,7 @@ class ListenerResolverTest extends \Doctrine\Tests\OrmTestCase /** * @expectedException InvalidArgumentException - * @expectedExceptionMessage An object was expected, but got "string. + * @expectedExceptionMessage An object was expected, but got "string". */ public function testRegisterStringException() { From 4be25cb3308e60d4d0ccfb6828fb656a4225cbb0 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 12 Aug 2012 22:35:06 -0300 Subject: [PATCH 24/41] small refactoring --- .../ORM/Mapping/DefaultEntityListenerResolver.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php index 5f7d70410..2a68112b3 100644 --- a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php +++ b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php @@ -38,16 +38,15 @@ class DefaultEntityListenerResolver implements EntityListenerResolver */ public function clear($className = null) { - if ($className !== null) { - - if (isset($this->instances[$className = trim($className, '\\')])) { - unset($this->instances[$className]); - } + if ($className === null) { + $this->instances = array(); return; } - $this->instances = array(); + if (isset($this->instances[$className = trim($className, '\\')])) { + unset($this->instances[$className]); + } } /** From 6b7e588da5b0bfa949d86d5dd2263348aaee03d6 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 19 Aug 2012 22:43:27 -0300 Subject: [PATCH 25/41] fix CS --- lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php | 4 ++-- lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 718105748..4ea082d31 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -415,7 +415,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory } } - /** + /** * Completes the ID generator mapping. If "auto" is specified we choose the generator * most appropriate for the targeted database platform. * @@ -462,7 +462,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory $sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform); } - $generator = ($fieldName && $class->fieldMappings[$fieldName]['type'] === "bigint") + $generator = ($fieldName && $class->fieldMappings[$fieldName]['type'] === 'bigint') ? new BigIntegerIdentityGenerator($sequenceName) : new IdentityGenerator($sequenceName); diff --git a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php index 2a68112b3..78c93791b 100644 --- a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php +++ b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php @@ -50,7 +50,7 @@ class DefaultEntityListenerResolver implements EntityListenerResolver } /** - * {@inheritdoc}" + * {@inheritdoc} */ public function register($object) { From 195b63934458377554aa51eaa1a245177aad7850 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 21 Aug 2012 21:01:08 -0300 Subject: [PATCH 26/41] change xml driver to use --- doctrine-mapping.xsd | 43 +------------------ lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 6 +-- ...ctrine.Tests.Models.CMS.CmsAddress.dcm.xml | 2 +- ...sts.Models.Company.CompanyContract.dcm.xml | 16 +++---- ...s.Company.CompanyFlexUltraContract.dcm.xml | 23 +++++----- 5 files changed, 25 insertions(+), 65 deletions(-) diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index a0fb82f9a..1d97fd688 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -98,50 +98,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 95bb49e5c..11d579a35 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -562,10 +562,8 @@ class XmlDriver extends FileDriver foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { $listeners = array(); - foreach ($listenerElement as $type => $callbackElement) { - list($prefix, $suffix) = explode('-', $type); - - $eventName = $prefix . ucfirst($suffix); + foreach ($listenerElement as $callbackElement) { + $eventName = (string) $callbackElement['type']; $methodName = (string) $callbackElement['method']; $listeners[] = array($eventName, $methodName); diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml index 2afa95d30..9df9e9ae5 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml @@ -23,7 +23,7 @@ - + diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml index 4f5f843eb..4fa0c23e1 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml @@ -15,17 +15,17 @@ - - + + - - + + - - + + - - + + diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml index e76483736..729bdfda0 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml @@ -9,19 +9,22 @@ - - - - - - - - + + + + + + + + + + + - - + + From ffc8d032c7e3926433bf2a605e4dba4d5558e0d3 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 9 Sep 2012 16:57:03 -0300 Subject: [PATCH 27/41] Fix typo --- lib/Doctrine/ORM/Mapping/EntityListeners.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Mapping/EntityListeners.php b/lib/Doctrine/ORM/Mapping/EntityListeners.php index eef6fc43b..fda08c4c9 100644 --- a/lib/Doctrine/ORM/Mapping/EntityListeners.php +++ b/lib/Doctrine/ORM/Mapping/EntityListeners.php @@ -40,7 +40,7 @@ final class EntityListeners implements Annotation public $value = array(); /** - * Specifies the entity the entity lifecycle callbacks. + * Specifies the entity lifecycle callbacks. * * @var array<\Doctrine\ORM\Mapping\LifecycleCallback> */ From c60e3e4ba4363d1201b45c8906c1d394c97051b3 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 6 Oct 2012 18:13:51 -0300 Subject: [PATCH 28/41] remove @LifecycleCallback --- doctrine-mapping.xsd | 1 + .../ORM/Mapping/Driver/AnnotationDriver.php | 8 --- .../Mapping/Driver/DoctrineAnnotations.php | 3 +- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 28 +++------- .../ORM/Mapping/Driver/YamlDriver.php | 26 +-------- lib/Doctrine/ORM/Mapping/EntityListeners.php | 7 --- .../ORM/Mapping/LifecycleCallback.php | 41 -------------- .../Doctrine/Tests/Models/CMS/CmsAddress.php | 11 ---- .../ORM/Functional/LifecycleCallbackTest.php | 53 ------------------- .../ORM/Mapping/AbstractMappingDriverTest.php | 15 ------ ...ctrine.Tests.Models.CMS.CmsAddress.dcm.xml | 6 --- ...ctrine.Tests.Models.CMS.CmsAddress.dcm.yml | 4 -- ...sts.Models.Company.CompanyContract.dcm.yml | 3 +- ...s.Company.CompanyFlexUltraContract.dcm.yml | 6 +-- 14 files changed, 13 insertions(+), 199 deletions(-) delete mode 100644 lib/Doctrine/ORM/Mapping/LifecycleCallback.php diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index 1d97fd688..243bfcd5b 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -51,6 +51,7 @@ + diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 3ddf70c86..30f664104 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -435,14 +435,6 @@ class AnnotationDriver extends AbstractAnnotationDriver } } } - - // Evaluate as lifecycle callback if the listener class is not given. - if(empty($entityListenersAnnot->value)) { - /* @var $method \Doctrine\ORM\Mapping\LifecycleCallback */ - foreach ($entityListenersAnnot->callbacks as $callback) { - $metadata->addLifecycleCallback($callback->method, $callback->event); - } - } } // Evaluate @HasLifecycleCallbacks annotation diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php index 9a5f33448..14abadb9e 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php +++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php @@ -64,5 +64,4 @@ require_once __DIR__.'/../AssociationOverride.php'; require_once __DIR__.'/../AssociationOverrides.php'; require_once __DIR__.'/../AttributeOverride.php'; require_once __DIR__.'/../AttributeOverrides.php'; -require_once __DIR__.'/../EntityListeners.php'; -require_once __DIR__.'/../LifecycleCallback.php'; +require_once __DIR__.'/../EntityListeners.php'; \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 11d579a35..625940d6d 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -19,10 +19,10 @@ namespace Doctrine\ORM\Mapping\Driver; -use SimpleXMLElement, - Doctrine\Common\Persistence\Mapping\Driver\FileDriver, - Doctrine\Common\Persistence\Mapping\ClassMetadata, - Doctrine\ORM\Mapping\MappingException; +use SimpleXMLElement; +use Doctrine\Common\Persistence\Mapping\Driver\FileDriver; +use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\MappingException; /** * XmlDriver is a metadata driver that enables mapping through XML files. @@ -560,28 +560,12 @@ class XmlDriver extends FileDriver // Evaluate entity listener if (isset($xmlRoot->{'entity-listeners'})) { foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { - $listeners = array(); - foreach ($listenerElement as $callbackElement) { $eventName = (string) $callbackElement['type']; $methodName = (string) $callbackElement['method']; + $className = (string) $listenerElement['class']; - $listeners[] = array($eventName, $methodName); - } - - if (isset($listenerElement['class'])) { - $className = (string) $listenerElement['class']; - - foreach ($listeners as $item) { - $metadata->addEntityListener($item[0], $className, $item[1]); - } - - continue; - } - - // Evaluate as lifecycle callback if the listener class is not given. - foreach ($listeners as $item) { - $metadata->addLifecycleCallback($item[1], $item[0]); + $metadata->addEntityListener($eventName, $className, $methodName); } } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index a4154871e..e53de341c 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -575,34 +575,12 @@ class YamlDriver extends FileDriver // Evaluate entityListeners if (isset($element['entityListeners'])) { - foreach ($element['entityListeners'] as $entityListener) { - $listeners = array(); - $className = null; - - if (isset($entityListener['class'])) { - $className = $entityListener['class']; - - unset($entityListener['class']); - } - + foreach ($element['entityListeners'] as $className => $entityListener) { foreach ($entityListener as $eventName => $callbackElement){ foreach ($callbackElement as $methodName){ - $listeners[] = array($eventName, $methodName); + $metadata->addEntityListener($eventName, $className, $methodName); } } - - if (null !== $className) { - foreach ($listeners as $item){ - $metadata->addEntityListener($item[0], $className, $item[1]); - } - - continue; - } - - // Evaluate as lifecycle callback if the listener class is not given. - foreach ($listeners as $item){ - $metadata->addLifecycleCallback($item[1], $item[0]); - } } } } diff --git a/lib/Doctrine/ORM/Mapping/EntityListeners.php b/lib/Doctrine/ORM/Mapping/EntityListeners.php index fda08c4c9..d9478a497 100644 --- a/lib/Doctrine/ORM/Mapping/EntityListeners.php +++ b/lib/Doctrine/ORM/Mapping/EntityListeners.php @@ -38,11 +38,4 @@ final class EntityListeners implements Annotation * @var array */ public $value = array(); - - /** - * Specifies the entity lifecycle callbacks. - * - * @var array<\Doctrine\ORM\Mapping\LifecycleCallback> - */ - public $callbacks = array(); } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/LifecycleCallback.php b/lib/Doctrine/ORM/Mapping/LifecycleCallback.php deleted file mode 100644 index 0b1b39585..000000000 --- a/lib/Doctrine/ORM/Mapping/LifecycleCallback.php +++ /dev/null @@ -1,41 +0,0 @@ -. - */ - -namespace Doctrine\ORM\Mapping; - -/** - * @author Fabio B. Silva - * @since 2.4 - * - * @Annotation - * @Target("ANNOTATION") - */ -final class LifecycleCallback implements Annotation -{ - /** - * @var string - */ - public $event; - - /** - * @var string - */ - public $method; -} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php index 16394fd87..7d22275b2 100644 --- a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php +++ b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php @@ -59,9 +59,6 @@ namespace Doctrine\Tests\Models\CMS; * ) * }) * - * @EntityListeners(callbacks = { - * @LifecycleCallback(\Doctrine\ORM\Events::prePersist, method = "prePersistHandler") - * }) */ class CmsAddress { @@ -129,11 +126,6 @@ class CmsAddress } } - public function prePersistHandler($event) - { - $this->prePersistHandlerCalls[] = $event; - } - public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) { $metadata->setPrimaryTable(array( @@ -162,8 +154,6 @@ class CmsAddress 'joinColumns' => array(array('referencedColumnName' => 'id')) )); - $metadata->addLifecycleCallback('prePersistHandler', 'prePersist'); - $metadata->addNamedNativeQuery(array ( 'name' => 'find-all', 'query' => 'SELECT id, country, city FROM cms_addresses', @@ -182,7 +172,6 @@ class CmsAddress 'resultSetMapping' => 'mapping-count', )); - $metadata->addSqlResultSetMapping(array ( 'name' => 'mapping-find-all', 'columns' => array(), diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index 151da181b..c19675b6d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -11,7 +11,6 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase parent::setUp(); try { $this->_schemaTool->createSchema(array( - $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\EntityListenersLifecycleCallback'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackEventArgEntity'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity'), $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestUser'), @@ -255,29 +254,6 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase $e->calls['postRemoveHandler'] ); } - /** - * @group DDC-1955 - */ - public function testEventListenersLifecycleCallback() - { - $e = new EntityListenersLifecycleCallback; - $e->value = 'foo'; - - $this->_em->persist($e); - $this->_em->flush(); - - $this->assertCount(2, $e->calls); - - $this->assertInstanceOf( - 'Doctrine\ORM\Event\LifecycleEventArgs', - $e->calls['prePersistHandler'] - ); - - $this->assertInstanceOf( - 'Doctrine\ORM\Event\LifecycleEventArgs', - $e->calls['postPersistHandler'] - ); - } } /** @Entity @HasLifecycleCallbacks */ @@ -406,35 +382,6 @@ class LifecycleListenerPreUpdate } } - -/** - * @Entity - * @EntityListeners(callbacks = { - * @LifecycleCallback(\Doctrine\ORM\Events::prePersist, method = "prePersistHandler"), - * @LifecycleCallback(\Doctrine\ORM\Events::postPersist, method = "postPersistHandler"), - * }) - */ -class EntityListenersLifecycleCallback -{ - /** @Id @Column(type="integer") @GeneratedValue */ - public $id; - - /** @Column() */ - public $value; - - public $calls = array(); - - public function prePersistHandler($event) - { - $this->calls[__FUNCTION__] = $event; - } - - public function postPersistHandler(\Doctrine\ORM\Event\LifecycleEventArgs $event) - { - $this->calls[__FUNCTION__] = $event; - } -} - /** @Entity @HasLifecycleCallbacks */ class LifecycleCallbackEventArgEntity { diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 41df5127f..55c9d6ba8 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -856,21 +856,6 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertEmpty($contractListener->postPersistCalls); } - - /** - * @group DDC-1955 - */ - public function testEventListenersLifecycleCallback() - { - $em = $this->_getTestEntityManager(); - $factory = $this->createClassMetadataFactory($em); - $metadata = $factory->getMetadataFor('Doctrine\Tests\Models\CMS\CmsAddress'); - - $this->assertArrayHasKey('prePersist', $metadata->lifecycleCallbacks); - $this->assertCount(1, $metadata->lifecycleCallbacks['prePersist']); - $this->assertEquals('prePersistHandler', $metadata->lifecycleCallbacks['prePersist'][0]); - } - } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml index 9df9e9ae5..0af5facda 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml @@ -21,12 +21,6 @@ - - - - - - diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml index cbff49615..696627c3c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml @@ -14,10 +14,6 @@ Doctrine\Tests\Models\CMS\CmsAddress: resultSetMapping: mapping-count query: SELECT COUNT(*) AS count FROM cms_addresses - entityListeners: - listener[0]: - prePersist: [prePersistHandler] - sqlResultSetMappings: mapping-find-all: entityResult: diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml index e738569e5..03b9d3bed 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml @@ -8,8 +8,7 @@ Doctrine\Tests\Models\Company\CompanyContract: flexultra: CompanyFlexUltraContract entityListeners: - listener[0]: - class : CompanyContractListener + CompanyContractListener: preFlush: [preFlushHandler] postLoad: [postLoadHandler] diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml index a72e5de38..26ce8f3d5 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml @@ -2,8 +2,7 @@ Doctrine\Tests\Models\Company\CompanyFlexUltraContract: type: entity entityListeners: - listener[0]: - class : CompanyContractListener + CompanyContractListener: preFlush: [preFlushHandler] postLoad: [postLoadHandler] @@ -17,8 +16,7 @@ Doctrine\Tests\Models\Company\CompanyFlexUltraContract: postRemove: [postRemoveHandler] preRemove: [preRemoveHandler] - listener[1]: - class : CompanyFlexUltraContractListener + CompanyFlexUltraContractListener: prePersist: [prePersistHandler1, prePersistHandler2] From 0d0f91a807e61dd3ce710acbc2f9f18d0e76a83c Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 13 Oct 2012 21:46:24 -0300 Subject: [PATCH 29/41] move listeners invocation from ClassMetadataInfo to ListenerInvoker --- lib/Doctrine/ORM/Event/ListenersInvoker.php | 78 +++++++++++++++++++ .../ORM/Mapping/ClassMetadataInfo.php | 22 +----- lib/Doctrine/ORM/UnitOfWork.php | 45 +++++------ .../ORM/Mapping/AbstractMappingDriverTest.php | 52 ------------- 4 files changed, 103 insertions(+), 94 deletions(-) create mode 100644 lib/Doctrine/ORM/Event/ListenersInvoker.php diff --git a/lib/Doctrine/ORM/Event/ListenersInvoker.php b/lib/Doctrine/ORM/Event/ListenersInvoker.php new file mode 100644 index 000000000..7ef6bb51d --- /dev/null +++ b/lib/Doctrine/ORM/Event/ListenersInvoker.php @@ -0,0 +1,78 @@ +. + */ + +namespace Doctrine\ORM\Event; + +use Doctrine\ORM\Mapping\EntityListenerResolver; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\Common\EventArgs; + +/** + * A method invoker based on entity lifecycle. + * + * @author Fabio B. Silva + * @since 2.4 + */ +class ListenersInvoker +{ + /** + * @var \Doctrine\ORM\Mapping\EntityListenerResolver The Entity listener resolver. + */ + private $resolver; + + /** + * @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver + */ + public function __construct(EntityListenerResolver $resolver) + { + $this->resolver = $resolver; + } + + /** + * Dispatches the lifecycle event of the given entity to the registered lifecycle callbacks. + * + * @param string $eventName The entity lifecycle event. + * @param \Object $entity The Entity on which the event occured. + * @param \Doctrine\Common\EventArgs $event The Event args. + */ + public function invokeLifecycleCallbacks(ClassMetadata $metadata, $eventName, $entity, EventArgs $event) + { + foreach ($metadata->lifecycleCallbacks[$eventName] as $callback) { + $entity->$callback($event); + } + } + + /** + * Dispatches the lifecycle event of the given entity to the registered entity listeners. + * + * @param string $eventName The entity lifecycle event. + * @param object $entity The Entity on which the event occured. + * @param \Doctrine\Common\EventArgs $event The Event args. + */ + public function invokeEntityListeners(ClassMetadata $metadata, $eventName, $entity, EventArgs $event) + { + foreach ($metadata->entityListeners[$eventName] as $listener) { + $class = $listener['class']; + $method = $listener['method']; + $instance = $this->resolver->resolve($class); + + $instance->{$method}($entity, $event); + } + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 0ec517d20..9ba6e0d7b 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -27,7 +27,6 @@ use ReflectionClass; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\ClassLoader; use Doctrine\Common\EventArgs; -use Doctrine\ORM\Mapping\EntityListenerResolver; /** * A ClassMetadata instance holds all the object-relational mapping metadata @@ -2426,6 +2425,8 @@ class ClassMetadataInfo implements ClassMetadata * Dispatches the lifecycle event of the given entity to the registered * lifecycle callbacks and lifecycle listeners. * + * @deprecated Deprecated since version 2.4 in favor of \Doctrine\ORM\Event\ListenersInvoker + * * @param string $lifecycleEvent The lifecycle event. * @param object $entity The Entity on which the event occured. * @@ -2513,25 +2514,6 @@ class ClassMetadataInfo implements ClassMetadata ); } - /** - * Call the entity listeners. - * - * @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver The Entity listener resolver. - * @param string $eventName The event name. - * @param object $entity An instance of the mapped entity - * @param \Doctrine\Common\EventArgs $arg The Event args - */ - public function dispatchEntityListeners(EntityListenerResolver $resolver, $eventName, $entity, EventArgs $arg) - { - foreach ($this->entityListeners[$eventName] as $listener) { - $class = $listener['class']; - $method = $listener['method']; - $instance = $resolver->resolve($class); - - $instance->{$method}($entity, $arg); - } - } - /** * Sets the discriminator column definition. * diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index b3904c981..d5efdc058 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -36,6 +36,7 @@ use Doctrine\ORM\Event\PreUpdateEventArgs; use Doctrine\ORM\Event\PreFlushEventArgs; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Event\PostFlushEventArgs; +use Doctrine\ORM\Event\ListenersInvoker; /** * The UnitOfWork is responsible for tracking changes to objects during an @@ -219,11 +220,11 @@ class UnitOfWork implements PropertyChangedListener private $evm; /** - * The EntityListenerResolver used for dispatching events. + * The ListenersInvoker used for dispatching events. * - * @var \Doctrine\ORM\Mapping\EntityListenerResolver + * @var \Doctrine\ORM\Event\ListenersInvoker */ - private $entityListenerResolver; + private $listenersInvoker; /** * Orphaned entities that are scheduled for removal. @@ -253,9 +254,9 @@ class UnitOfWork implements PropertyChangedListener */ public function __construct(EntityManager $em) { - $this->em = $em; - $this->evm = $em->getEventManager(); - $this->entityListenerResolver = $em->getConfiguration()->getEntityListenerResolver(); + $this->em = $em; + $this->evm = $em->getEventManager(); + $this->listenersInvoker = new ListenersInvoker($em->getConfiguration()->getEntityListenerResolver()); } /** @@ -528,12 +529,12 @@ class UnitOfWork implements PropertyChangedListener // Fire PreFlush lifecycle callbacks if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::preFlush, $entity, $event); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preFlush, $entity, $event); } // Fire PreFlush entity listeners if ($hasEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::preFlush, $entity, $event); + $this->listenersInvoker->invokeEntityListeners($class, Events::preFlush, $entity, $event); } $actualData = array(); @@ -840,11 +841,11 @@ class UnitOfWork implements PropertyChangedListener } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::prePersist, $entity, $event); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::prePersist, $entity, $event); } if ($hasEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::prePersist, $entity, $event); + $this->listenersInvoker->invokeEntityListeners($class, Events::prePersist, $entity, $event); } if ($hasListeners) { @@ -990,11 +991,11 @@ class UnitOfWork implements PropertyChangedListener } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postPersist, $entity, $event); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postPersist, $entity, $event); } if ($hasEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::postPersist, $entity, $event); + $this->listenersInvoker->invokeEntityListeners($class, Events::postPersist, $entity, $event); } if ($hasListeners) { @@ -1037,13 +1038,13 @@ class UnitOfWork implements PropertyChangedListener } if ($hasPreUpdateLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::preUpdate, $entity, $preEvent); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preUpdate, $entity, $preEvent); $this->recomputeSingleEntityChangeSet($class, $entity); } if ($hasPreUpdateEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::preUpdate, $entity, $preEvent); + $this->listenersInvoker->invokeEntityListeners($class, Events::preUpdate, $entity, $preEvent); } if ($hasPreUpdateListeners) { @@ -1057,11 +1058,11 @@ class UnitOfWork implements PropertyChangedListener unset($this->entityUpdates[$oid]); if ($hasPostUpdateLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postUpdate, $entity, $postEvent); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postUpdate, $entity, $postEvent); } if ($hasPostUpdateEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::postUpdate, $entity, $postEvent); + $this->listenersInvoker->invokeEntityListeners($class, Events::postUpdate, $entity, $postEvent); } if ($hasPostUpdateListeners) { @@ -1112,11 +1113,11 @@ class UnitOfWork implements PropertyChangedListener } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postRemove, $entity, $event); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postRemove, $entity, $event); } if ($hasEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::postRemove, $entity, $event); + $this->listenersInvoker->invokeEntityListeners($class, Events::postRemove, $entity, $event); } if ($hasListeners) { @@ -1769,11 +1770,11 @@ class UnitOfWork implements PropertyChangedListener } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::preRemove, $entity, $event); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preRemove, $entity, $event); } if ($hasEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::preRemove, $entity, $event); + $this->listenersInvoker->invokeEntityListeners($class, Events::preRemove, $entity, $event); } if ($hasListeners) { @@ -2785,11 +2786,11 @@ class UnitOfWork implements PropertyChangedListener } if ($hasLifecycleCallbacks) { - $class->invokeLifecycleCallbacks(Events::postLoad, $entity, $event); + $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postLoad, $entity, $event); } if ($hasEntityListeners) { - $class->dispatchEntityListeners($this->entityListenerResolver, Events::postLoad, $entity, $event); + $this->listenersInvoker->invokeEntityListeners($class, Events::postLoad, $entity, $event); } if ($hasListeners) { diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 55c9d6ba8..7be69c1f0 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -804,58 +804,6 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']); $this->assertEquals('prePersistHandler2', $prePersist['method']); } - - /** - * @group DDC-1955 - */ - public function testCallEntityListeners() - { - $em = $this->_getTestEntityManager(); - $factory = $this->createClassMetadataFactory($em); - $resolver = $em->getConfiguration()->getEntityListenerResolver(); - $flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract'); - $fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract'); - $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); - $contractListener = $resolver->resolve('Doctrine\Tests\Models\Company\CompanyContractListener'); - $ultraContractListener = $resolver->resolve('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener'); - - $contractListener->prePersistCalls = array(); - $contractListener->postPersistCalls = array(); - $ultraContractListener->prePersistCalls = array(); - - $fix = new CompanyFixContract(); - $fixArg = new LifecycleEventArgs($fix, $em); - - $flex = new CompanyFlexContract(); - $flexArg = new LifecycleEventArgs($fix, $em); - - $ultra = new CompanyFlexContract(); - $ultraArg = new LifecycleEventArgs($ultra, $em); - - $fixClass->dispatchEntityListeners($resolver, Events::prePersist, $fix, $fixArg); - $flexClass->dispatchEntityListeners($resolver, Events::prePersist, $flex, $flexArg); - $ultraClass->dispatchEntityListeners($resolver, Events::prePersist, $ultra, $ultraArg); - - $this->assertCount(3, $contractListener->prePersistCalls); - $this->assertCount(2, $ultraContractListener->prePersistCalls); - - $this->assertSame($fix, $contractListener->prePersistCalls[0][0]); - $this->assertSame($fixArg, $contractListener->prePersistCalls[0][1]); - - $this->assertSame($flex, $contractListener->prePersistCalls[1][0]); - $this->assertSame($flexArg, $contractListener->prePersistCalls[1][1]); - - $this->assertSame($ultra, $contractListener->prePersistCalls[2][0]); - $this->assertSame($ultraArg, $contractListener->prePersistCalls[2][1]); - - $this->assertSame($ultra, $ultraContractListener->prePersistCalls[0][0]); - $this->assertSame($ultraArg, $ultraContractListener->prePersistCalls[0][1]); - - $this->assertSame($ultra, $ultraContractListener->prePersistCalls[1][0]); - $this->assertSame($ultraArg, $ultraContractListener->prePersistCalls[1][1]); - - $this->assertEmpty($contractListener->postPersistCalls); - } } /** From 0d0fc320b45ac085c6254b30a9879ca611084495 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 20 Oct 2012 21:53:08 -0300 Subject: [PATCH 30/41] Fix DocBlock --- lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 30f664104..a5c01fedb 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -476,6 +476,7 @@ class AnnotationDriver extends AbstractAnnotationDriver * Parses the given method. * * @param \ReflectionMethod $method + * * @return array */ private function getMethodCallbacks(\ReflectionMethod $method) From 7b0f59ed7c2a787193bd509808f36e3f2311143f Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Fri, 9 Nov 2012 15:47:57 -0200 Subject: [PATCH 31/41] split override test --- lib/Doctrine/ORM/Event/ListenersInvoker.php | 2 +- .../Tests/ORM/Functional/EntityListenersTest.php | 2 -- .../Tests/ORM/Mapping/AbstractMappingDriverTest.php | 12 +++++++++++- .../Tests/ORM/Mapping/EntityListenerResolverTest.php | 2 -- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/Doctrine/ORM/Event/ListenersInvoker.php b/lib/Doctrine/ORM/Event/ListenersInvoker.php index 7ef6bb51d..ae16856cb 100644 --- a/lib/Doctrine/ORM/Event/ListenersInvoker.php +++ b/lib/Doctrine/ORM/Event/ListenersInvoker.php @@ -72,7 +72,7 @@ class ListenersInvoker $method = $listener['method']; $instance = $this->resolver->resolve($class); - $instance->{$method}($entity, $event); + $instance->$method($entity, $event); } } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php index fc6048e60..584795263 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php @@ -4,8 +4,6 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\Company\CompanyFixContract; -require_once __DIR__ . '/../../TestInit.php'; - /** * @group DDC-1955 */ diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 7be69c1f0..bfbab9e32 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -780,6 +780,16 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase //Inherited listeners $this->assertEquals($fixClass->entityListeners, $superClass->entityListeners); $this->assertEquals($flexClass->entityListeners, $superClass->entityListeners); + } + + /** + * @group DDC-1955 + */ + public function testEntityListenersOverride() + { + $em = $this->_getTestEntityManager(); + $factory = $this->createClassMetadataFactory($em); + $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract'); //overrited listeners $this->assertArrayHasKey(Events::postPersist, $ultraClass->entityListeners); @@ -799,7 +809,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $prePersist = $ultraClass->entityListeners[Events::prePersist][1]; $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']); $this->assertEquals('prePersistHandler1', $prePersist['method']); - + $prePersist = $ultraClass->entityListeners[Events::prePersist][2]; $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']); $this->assertEquals('prePersistHandler2', $prePersist['method']); diff --git a/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php b/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php index a17103391..64007b031 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php @@ -4,8 +4,6 @@ namespace Doctrine\Tests\ORM\Mapping; use Doctrine\ORM\Mapping\DefaultEntityListenerResolver; -require_once __DIR__ . '/../../TestInit.php'; - /** * @group DDC-1955 */ From 6d7b3863b57cbc6f1438aa42a9a758ae1512b4e9 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Fri, 9 Nov 2012 16:46:56 -0200 Subject: [PATCH 32/41] Use bitmask of subscribed event systems. --- lib/Doctrine/ORM/Event/ListenersInvoker.php | 84 ++++++-- .../ORM/Mapping/ClassMetadataInfo.php | 4 +- lib/Doctrine/ORM/UnitOfWork.php | 187 ++++-------------- 3 files changed, 101 insertions(+), 174 deletions(-) diff --git a/lib/Doctrine/ORM/Event/ListenersInvoker.php b/lib/Doctrine/ORM/Event/ListenersInvoker.php index ae16856cb..96fa4e67a 100644 --- a/lib/Doctrine/ORM/Event/ListenersInvoker.php +++ b/lib/Doctrine/ORM/Event/ListenersInvoker.php @@ -19,8 +19,8 @@ namespace Doctrine\ORM\Event; -use Doctrine\ORM\Mapping\EntityListenerResolver; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\EntityManager; use Doctrine\Common\EventArgs; /** @@ -31,48 +31,90 @@ use Doctrine\Common\EventArgs; */ class ListenersInvoker { + const INVOKE_NONE = 0; + const INVOKE_LISTENERS = 1; + const INVOKE_CALLBACKS = 2; + const INVOKE_MANAGER = 4; + /** * @var \Doctrine\ORM\Mapping\EntityListenerResolver The Entity listener resolver. */ private $resolver; /** - * @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver + * The EventManager used for dispatching events. + * + * @var \Doctrine\Common\EventManager */ - public function __construct(EntityListenerResolver $resolver) + private $eventManager; + + /** + * Initializes a new ListenersInvoker instance. + * + * @param \Doctrine\ORM\EntityManager $em + */ + public function __construct(EntityManager $em) { - $this->resolver = $resolver; + $this->eventManager = $em->getEventManager(); + $this->resolver = $em->getConfiguration()->getEntityListenerResolver(); } /** - * Dispatches the lifecycle event of the given entity to the registered lifecycle callbacks. + * Get the subscribed event systems * - * @param string $eventName The entity lifecycle event. - * @param \Object $entity The Entity on which the event occured. - * @param \Doctrine\Common\EventArgs $event The Event args. + * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata. + * @param string $eventName The entity lifecycle event. + * + * @return integer Bitmask of subscribed event systems. */ - public function invokeLifecycleCallbacks(ClassMetadata $metadata, $eventName, $entity, EventArgs $event) + public function getSubscribedSystems(ClassMetadata $metadata, $eventName) { - foreach ($metadata->lifecycleCallbacks[$eventName] as $callback) { - $entity->$callback($event); + $invoke = self::INVOKE_NONE; + + if (isset($metadata->lifecycleCallbacks[$eventName])) { + $invoke |= self::INVOKE_CALLBACKS; } + + if (isset($metadata->entityListeners[$eventName])) { + $invoke |= self::INVOKE_LISTENERS; + } + + if ($this->eventManager->hasListeners($eventName)) { + $invoke |= self::INVOKE_MANAGER; + } + + return $invoke; } /** - * Dispatches the lifecycle event of the given entity to the registered entity listeners. + * Dispatches the lifecycle event of the given entity. * - * @param string $eventName The entity lifecycle event. - * @param object $entity The Entity on which the event occured. - * @param \Doctrine\Common\EventArgs $event The Event args. + * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata. + * @param string $eventName The entity lifecycle event. + * @param object $entity The Entity on which the event occured. + * @param \Doctrine\Common\EventArgs $event The Event args. + * @param integer $invoke Bitmask to invoke listeners. */ - public function invokeEntityListeners(ClassMetadata $metadata, $eventName, $entity, EventArgs $event) + public function invoke(ClassMetadata $metadata, $eventName, $entity, EventArgs $event, $invoke) { - foreach ($metadata->entityListeners[$eventName] as $listener) { - $class = $listener['class']; - $method = $listener['method']; - $instance = $this->resolver->resolve($class); + if($invoke & self::INVOKE_CALLBACKS) { + foreach ($metadata->lifecycleCallbacks[$eventName] as $callback) { + $entity->$callback($event); + } + } - $instance->$method($entity, $event); + if($invoke & self::INVOKE_LISTENERS) { + foreach ($metadata->entityListeners[$eventName] as $listener) { + $class = $listener['class']; + $method = $listener['method']; + $instance = $this->resolver->resolve($class); + + $instance->$method($entity, $event); + } + } + + if($invoke & self::INVOKE_MANAGER) { + $this->eventManager->dispatchEvent($eventName, $event); } } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 9ba6e0d7b..d16aba1b4 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2432,10 +2432,10 @@ class ClassMetadataInfo implements ClassMetadata * * @return void */ - public function invokeLifecycleCallbacks($lifecycleEvent, $entity, EventArgs $event) + public function invokeLifecycleCallbacks($lifecycleEvent, $entity) { foreach ($this->lifecycleCallbacks[$lifecycleEvent] as $callback) { - $entity->$callback($event); + $entity->$callback(); } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index d5efdc058..993e4a55d 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -256,7 +256,7 @@ class UnitOfWork implements PropertyChangedListener { $this->em = $em; $this->evm = $em->getEventManager(); - $this->listenersInvoker = new ListenersInvoker($em->getConfiguration()->getEntityListenerResolver()); + $this->listenersInvoker = new ListenersInvoker($em); } /** @@ -511,13 +511,7 @@ class UnitOfWork implements PropertyChangedListener */ public function computeChangeSet(ClassMetadata $class, $entity) { - $oid = spl_object_hash($entity); - $hasEntityListeners = isset($class->entityListeners[Events::preFlush]); - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preFlush]); - - if ($hasEntityListeners || $hasLifecycleCallbacks) { - $event = new PreFlushEventArgs($entity, $this->em); - } + $oid = spl_object_hash($entity); if (isset($this->readOnlyObjects[$oid])) { return; @@ -527,14 +521,10 @@ class UnitOfWork implements PropertyChangedListener $class = $this->em->getClassMetadata(get_class($entity)); } - // Fire PreFlush lifecycle callbacks - if ($hasLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preFlush, $entity, $event); - } + $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::preFlush); - // Fire PreFlush entity listeners - if ($hasEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::preFlush, $entity, $event); + if ($invoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::preFlush, $entity, new PreFlushEventArgs($entity, $this->em), $invoke); } $actualData = array(); @@ -831,25 +821,11 @@ class UnitOfWork implements PropertyChangedListener */ private function persistNew($class, $entity) { - $oid = spl_object_hash($entity); - $hasListeners = $this->evm->hasListeners(Events::prePersist); - $hasEntityListeners = isset($class->entityListeners[Events::prePersist]); - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::prePersist]); + $oid = spl_object_hash($entity); + $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::prePersist); - if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { - $event = new LifecycleEventArgs($entity, $this->em); - } - - if ($hasLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::prePersist, $entity, $event); - } - - if ($hasEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::prePersist, $entity, $event); - } - - if ($hasListeners) { - $this->evm->dispatchEvent(Events::prePersist, $event); + if ($invoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::prePersist, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } $idGen = $class->idGenerator; @@ -945,13 +921,10 @@ class UnitOfWork implements PropertyChangedListener */ private function executeInserts($class) { - $className = $class->name; - $persister = $this->getEntityPersister($className); - $entities = array(); - - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]); - $hasEntityListeners = isset($class->entityListeners[Events::postPersist]); - $hasListeners = $this->evm->hasListeners(Events::postPersist); + $entities = array(); + $className = $class->name; + $persister = $this->getEntityPersister($className); + $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postPersist); foreach ($this->entityInsertions as $oid => $entity) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) { @@ -962,7 +935,7 @@ class UnitOfWork implements PropertyChangedListener unset($this->entityInsertions[$oid]); - if ($hasLifecycleCallbacks || $hasEntityListeners || $hasListeners) { + if ($invoke != ListenersInvoker::INVOKE_NONE) { $entities[] = $entity; } } @@ -984,23 +957,9 @@ class UnitOfWork implements PropertyChangedListener $this->addToIdentityMap($entity); } } - + foreach ($entities as $entity) { - if ($hasListeners || $hasEntityListeners | $hasLifecycleCallbacks) { - $event = new LifecycleEventArgs($entity, $this->em); - } - - if ($hasLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postPersist, $entity, $event); - } - - if ($hasEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::postPersist, $entity, $event); - } - - if ($hasListeners) { - $this->evm->dispatchEvent(Events::postPersist, $event); - } + $this->listenersInvoker->invoke($class, Events::postPersist, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } } @@ -1013,60 +972,29 @@ class UnitOfWork implements PropertyChangedListener */ private function executeUpdates($class) { - $className = $class->name; - $persister = $this->getEntityPersister($className); - - $hasPreUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preUpdate]); - $hasPreUpdateEntityListeners = isset($class->entityListeners[Events::preUpdate]); - $hasPreUpdateListeners = $this->evm->hasListeners(Events::preUpdate); - - $hasPostUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postUpdate]); - $hasPostUpdateEntityListeners = isset($class->entityListeners[Events::postUpdate]); - $hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate); + $className = $class->name; + $persister = $this->getEntityPersister($className); + $preUpdateInvoke = $this->listenersInvoker->getSubscribedSystems($class, Events::preUpdate); + $postUpdateInvoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postUpdate); foreach ($this->entityUpdates as $oid => $entity) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) { continue; } - if ($hasPreUpdateListeners || $hasPreUpdateEntityListeners || $hasPreUpdateLifecycleCallbacks) { - $preEvent = new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]); - } - - if ($hasPostUpdateListeners || $hasPostUpdateEntityListeners || $hasPostUpdateLifecycleCallbacks) { - $postEvent = new LifecycleEventArgs($entity, $this->em); - } - - if ($hasPreUpdateLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preUpdate, $entity, $preEvent); - + if ($preUpdateInvoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::preUpdate, $entity, new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]), $preUpdateInvoke); $this->recomputeSingleEntityChangeSet($class, $entity); } - if ($hasPreUpdateEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::preUpdate, $entity, $preEvent); - } - - if ($hasPreUpdateListeners) { - $this->evm->dispatchEvent(Events::preUpdate, $preEvent); - } - - if (!empty($this->entityChangeSets[$oid])) { + if ( ! empty($this->entityChangeSets[$oid])) { $persister->update($entity); } unset($this->entityUpdates[$oid]); - if ($hasPostUpdateLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postUpdate, $entity, $postEvent); - } - - if ($hasPostUpdateEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::postUpdate, $entity, $postEvent); - } - - if ($hasPostUpdateListeners) { - $this->evm->dispatchEvent(Events::postUpdate, $postEvent); + if ($postUpdateInvoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::postUpdate, $entity, new LifecycleEventArgs($entity, $this->em), $postUpdateInvoke); } } } @@ -1080,12 +1008,9 @@ class UnitOfWork implements PropertyChangedListener */ private function executeDeletions($class) { - $className = $class->name; - $persister = $this->getEntityPersister($className); - - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]); - $hasEntityListeners = isset($class->entityListeners[Events::postRemove]); - $hasListeners = $this->evm->hasListeners(Events::postRemove); + $className = $class->name; + $persister = $this->getEntityPersister($className); + $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postRemove); foreach ($this->entityDeletions as $oid => $entity) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) { @@ -1108,20 +1033,8 @@ class UnitOfWork implements PropertyChangedListener $class->reflFields[$class->identifier[0]]->setValue($entity, null); } - if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { - $event = new LifecycleEventArgs($entity, $this->em); - } - - if ($hasLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postRemove, $entity, $event); - } - - if ($hasEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::postRemove, $entity, $event); - } - - if ($hasListeners) { - $this->evm->dispatchEvent(Events::postRemove, $event); + if ($invoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::postRemove, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } } } @@ -1761,24 +1674,10 @@ class UnitOfWork implements PropertyChangedListener break; case self::STATE_MANAGED: - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preRemove]); - $hasEntityListeners = isset($class->entityListeners[Events::preRemove]); - $hasListeners = $this->evm->hasListeners(Events::preRemove); + $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::preRemove); - if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { - $event = new LifecycleEventArgs($entity, $this->em); - } - - if ($hasLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preRemove, $entity, $event); - } - - if ($hasEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::preRemove, $entity, $event); - } - - if ($hasListeners) { - $this->evm->dispatchEvent(Events::preRemove, $event); + if ($invoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::preRemove, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } $this->scheduleForDelete($entity); @@ -2777,24 +2676,10 @@ class UnitOfWork implements PropertyChangedListener } if ($overrideLocalValues) { - $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postLoad]); - $hasEntityListeners = isset($class->entityListeners[Events::postLoad]); - $hasListeners = $this->evm->hasListeners(Events::postLoad); + $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postLoad); - if ($hasListeners || $hasEntityListeners || $hasLifecycleCallbacks) { - $event = new LifecycleEventArgs($entity, $this->em); - } - - if ($hasLifecycleCallbacks) { - $this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postLoad, $entity, $event); - } - - if ($hasEntityListeners) { - $this->listenersInvoker->invokeEntityListeners($class, Events::postLoad, $entity, $event); - } - - if ($hasListeners) { - $this->evm->dispatchEvent(Events::postLoad, $event); + if ($invoke != ListenersInvoker::INVOKE_NONE) { + $this->listenersInvoker->invoke($class, Events::postLoad, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } } From 3f9a4c82b0e28f0d89a7c15f63979b17d68e4510 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Fri, 9 Nov 2012 16:57:30 -0200 Subject: [PATCH 33/41] Fix typo --- tests/Doctrine/Tests/ORM/ConfigurationTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/ConfigurationTest.php b/tests/Doctrine/Tests/ORM/ConfigurationTest.php index 57ec1ce1c..5f805fb86 100644 --- a/tests/Doctrine/Tests/ORM/ConfigurationTest.php +++ b/tests/Doctrine/Tests/ORM/ConfigurationTest.php @@ -268,9 +268,9 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase { $this->assertInstanceOf('Doctrine\ORM\Mapping\EntityListenerResolver', $this->configuration->getEntityListenerResolver()); $this->assertInstanceOf('Doctrine\ORM\Mapping\DefaultEntityListenerResolver', $this->configuration->getEntityListenerResolver()); - $quoteStrategy = $this->getMock('Doctrine\ORM\Mapping\EntityListenerResolver'); - $this->configuration->setEntityListenerResolver($quoteStrategy); - $this->assertSame($quoteStrategy, $this->configuration->getEntityListenerResolver()); + $resolver = $this->getMock('Doctrine\ORM\Mapping\EntityListenerResolver'); + $this->configuration->setEntityListenerResolver($resolver); + $this->assertSame($resolver, $this->configuration->getEntityListenerResolver()); } } From e9c89cafb9e9fc43e9476afc463a2df8e641c2c6 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Fri, 9 Nov 2012 17:05:14 -0200 Subject: [PATCH 34/41] Fix DocBlock --- lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index d16aba1b4..ec5d44759 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2492,8 +2492,10 @@ class ClassMetadataInfo implements ClassMetadata /** * Adds a entity listener for entities of this class. * - * @param string $callback - * @param string $eventName + * @param string $eventName The entity lifecycle event. + * @param string $class The listener class. + * @param string $method The listener callback method. + * * @throws \Doctrine\ORM\Mapping\MappingException */ public function addEntityListener($eventName, $class, $method) From 46fea51622d253ed7c9c600945353bc8288a4ae4 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Fri, 9 Nov 2012 18:14:51 -0200 Subject: [PATCH 35/41] use '!==' instead of '!=' --- lib/Doctrine/ORM/UnitOfWork.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 993e4a55d..1d2919611 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -523,7 +523,7 @@ class UnitOfWork implements PropertyChangedListener $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::preFlush); - if ($invoke != ListenersInvoker::INVOKE_NONE) { + if ($invoke !== ListenersInvoker::INVOKE_NONE) { $this->listenersInvoker->invoke($class, Events::preFlush, $entity, new PreFlushEventArgs($entity, $this->em), $invoke); } @@ -824,7 +824,7 @@ class UnitOfWork implements PropertyChangedListener $oid = spl_object_hash($entity); $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::prePersist); - if ($invoke != ListenersInvoker::INVOKE_NONE) { + if ($invoke !== ListenersInvoker::INVOKE_NONE) { $this->listenersInvoker->invoke($class, Events::prePersist, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } @@ -935,7 +935,7 @@ class UnitOfWork implements PropertyChangedListener unset($this->entityInsertions[$oid]); - if ($invoke != ListenersInvoker::INVOKE_NONE) { + if ($invoke !== ListenersInvoker::INVOKE_NONE) { $entities[] = $entity; } } @@ -1033,7 +1033,7 @@ class UnitOfWork implements PropertyChangedListener $class->reflFields[$class->identifier[0]]->setValue($entity, null); } - if ($invoke != ListenersInvoker::INVOKE_NONE) { + if ($invoke !== ListenersInvoker::INVOKE_NONE) { $this->listenersInvoker->invoke($class, Events::postRemove, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } } @@ -1676,7 +1676,7 @@ class UnitOfWork implements PropertyChangedListener case self::STATE_MANAGED: $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::preRemove); - if ($invoke != ListenersInvoker::INVOKE_NONE) { + if ($invoke !== ListenersInvoker::INVOKE_NONE) { $this->listenersInvoker->invoke($class, Events::preRemove, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } @@ -2678,7 +2678,7 @@ class UnitOfWork implements PropertyChangedListener if ($overrideLocalValues) { $invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postLoad); - if ($invoke != ListenersInvoker::INVOKE_NONE) { + if ($invoke !== ListenersInvoker::INVOKE_NONE) { $this->listenersInvoker->invoke($class, Events::postLoad, $entity, new LifecycleEventArgs($entity, $this->em), $invoke); } } From e6d9d1de47ff5a085e84d73dc3738bfecef2ab5f Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Wed, 5 Dec 2012 18:47:48 -0200 Subject: [PATCH 36/41] support naming convention for listeners without mapping. --- .../ORM/Mapping/Driver/AnnotationDriver.php | 13 ++++- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 10 +++- .../ORM/Mapping/Driver/YamlDriver.php | 8 +++ .../Doctrine/Tests/Models/CMS/CmsAddress.php | 18 ++++-- .../Tests/Models/CMS/CmsAddressListener.php | 58 +++++++++++++++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 57 ++++++++++++++++++ .../Doctrine.Tests.Models.CMS.CmsAddress.php | 16 ++++- ...ctrine.Tests.Models.CMS.CmsAddress.dcm.xml | 4 ++ ...ctrine.Tests.Models.CMS.CmsAddress.dcm.yml | 2 + 9 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 tests/Doctrine/Tests/Models/CMS/CmsAddressListener.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index a5c01fedb..a4bea98ea 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -23,6 +23,7 @@ use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\ORM\Mapping\MappingException; use Doctrine\ORM\Mapping\JoinColumn; use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver; use Doctrine\ORM\Events; @@ -426,14 +427,22 @@ class AnnotationDriver extends AbstractAnnotationDriver throw MappingException::entityListenerClassNotFound($listenerClassName, $className); } - $listenerClass = new \ReflectionClass($listenerClassName); + $hasMapping = false; + $listenerClass = new \ReflectionClass($listenerClassName); /* @var $method \ReflectionMethod */ foreach ($listenerClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { // find method callbacks. - foreach ($this->getMethodCallbacks($method) as $value) { + $callbacks = $this->getMethodCallbacks($method); + $hasMapping = $hasMapping ?: ( ! empty($callbacks)); + + foreach ($callbacks as $value) { $metadata->addEntityListener($value[1], $listenerClassName, $value[0]); } } + // Evaluate the listener using naming convention. + if ( ! $hasMapping ) { + EntityListenerBuilder::bindEntityListener($metadata, $listenerClassName); + } } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 625940d6d..26d1becd0 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -21,6 +21,7 @@ namespace Doctrine\ORM\Mapping\Driver; use SimpleXMLElement; use Doctrine\Common\Persistence\Mapping\Driver\FileDriver; +use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; @@ -560,10 +561,17 @@ class XmlDriver extends FileDriver // Evaluate entity listener if (isset($xmlRoot->{'entity-listeners'})) { foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { + $className = (string) $listenerElement['class']; + // Evaluate the listener using naming convention. + if($listenerElement->count() === 0) { + EntityListenerBuilder::bindEntityListener($metadata, $className); + + continue; + } + foreach ($listenerElement as $callbackElement) { $eventName = (string) $callbackElement['type']; $methodName = (string) $callbackElement['method']; - $className = (string) $listenerElement['class']; $metadata->addEntityListener($eventName, $className, $methodName); } diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index e53de341c..bf97f19fb 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -20,6 +20,7 @@ namespace Doctrine\ORM\Mapping\Driver; use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\Common\Persistence\Mapping\Driver\FileDriver; use Doctrine\ORM\Mapping\MappingException; use Symfony\Component\Yaml\Yaml; @@ -576,6 +577,13 @@ class YamlDriver extends FileDriver // Evaluate entityListeners if (isset($element['entityListeners'])) { foreach ($element['entityListeners'] as $className => $entityListener) { + // Evaluate the listener using naming convention. + if (empty($entityListener)) { + EntityListenerBuilder::bindEntityListener($metadata, $className); + + continue; + } + foreach ($entityListener as $eventName => $callbackElement){ foreach ($callbackElement as $methodName){ $metadata->addEntityListener($eventName, $className, $methodName); diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php index 7d22275b2..aaf4956d3 100644 --- a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php +++ b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php @@ -59,6 +59,7 @@ namespace Doctrine\Tests\Models\CMS; * ) * }) * + * @EntityListeners({"CmsAddressListener"}) */ class CmsAddress { @@ -94,11 +95,6 @@ class CmsAddress */ public $user; - /** - * @var array - */ - public $prePersistHandlerCalls = array(); - public function getId() { return $this->id; } @@ -213,5 +209,17 @@ class CmsAddress ), ) )); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CmsAddressListener', 'postPersist'); + $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CmsAddressListener', 'prePersist'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'CmsAddressListener', 'postUpdate'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'CmsAddressListener', 'preUpdate'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'CmsAddressListener', 'postRemove'); + $metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'CmsAddressListener', 'preRemove'); + + $metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'CmsAddressListener', 'preFlush'); + $metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'CmsAddressListener', 'postLoad'); } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddressListener.php b/tests/Doctrine/Tests/Models/CMS/CmsAddressListener.php new file mode 100644 index 000000000..9c9db89eb --- /dev/null +++ b/tests/Doctrine/Tests/Models/CMS/CmsAddressListener.php @@ -0,0 +1,58 @@ +calls[__FUNCTION__][] = func_get_args(); + } + + public function postPersist() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + public function preUpdate() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + public function postUpdate() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + public function preRemove() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + public function postRemove() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + public function postLoad() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + public function preFlush() + { + $this->calls[__FUNCTION__][] = func_get_args(); + } + + protected function postPersistHandler() + { + throw new \BadMethodCallException("This is not a valid callback"); + } + + protected function prePersistHandler() + { + throw new \BadMethodCallException("This is not a valid callback"); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index bfbab9e32..24b72aaa3 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -814,6 +814,63 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']); $this->assertEquals('prePersistHandler2', $prePersist['method']); } + + + /** + * @group DDC-1955 + */ + public function testEntityListenersNamingConvention() + { + $em = $this->_getTestEntityManager(); + $factory = $this->createClassMetadataFactory($em); + $metadata = $factory->getMetadataFor('Doctrine\Tests\Models\CMS\CmsAddress'); + + $this->assertArrayHasKey(Events::postPersist, $metadata->entityListeners); + $this->assertArrayHasKey(Events::prePersist, $metadata->entityListeners); + $this->assertArrayHasKey(Events::postUpdate, $metadata->entityListeners); + $this->assertArrayHasKey(Events::preUpdate, $metadata->entityListeners); + $this->assertArrayHasKey(Events::postRemove, $metadata->entityListeners); + $this->assertArrayHasKey(Events::preRemove, $metadata->entityListeners); + $this->assertArrayHasKey(Events::postLoad, $metadata->entityListeners); + $this->assertArrayHasKey(Events::preFlush, $metadata->entityListeners); + + $this->assertCount(1, $metadata->entityListeners[Events::postPersist]); + $this->assertCount(1, $metadata->entityListeners[Events::prePersist]); + $this->assertCount(1, $metadata->entityListeners[Events::postUpdate]); + $this->assertCount(1, $metadata->entityListeners[Events::preUpdate]); + $this->assertCount(1, $metadata->entityListeners[Events::postRemove]); + $this->assertCount(1, $metadata->entityListeners[Events::preRemove]); + $this->assertCount(1, $metadata->entityListeners[Events::postLoad]); + $this->assertCount(1, $metadata->entityListeners[Events::preFlush]); + + $postPersist = $metadata->entityListeners[Events::postPersist][0]; + $prePersist = $metadata->entityListeners[Events::prePersist][0]; + $postUpdate = $metadata->entityListeners[Events::postUpdate][0]; + $preUpdate = $metadata->entityListeners[Events::preUpdate][0]; + $postRemove = $metadata->entityListeners[Events::postRemove][0]; + $preRemove = $metadata->entityListeners[Events::preRemove][0]; + $postLoad = $metadata->entityListeners[Events::postLoad][0]; + $preFlush = $metadata->entityListeners[Events::preFlush][0]; + + + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postPersist['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $prePersist['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postUpdate['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $preUpdate['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postRemove['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $preRemove['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postLoad['class']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $preFlush['class']); + + $this->assertEquals(Events::postPersist, $postPersist['method']); + $this->assertEquals(Events::prePersist, $prePersist['method']); + $this->assertEquals(Events::postUpdate, $postUpdate['method']); + $this->assertEquals(Events::preUpdate, $preUpdate['method']); + $this->assertEquals(Events::postRemove, $postRemove['method']); + $this->assertEquals(Events::preRemove, $preRemove['method']); + $this->assertEquals(Events::postLoad, $postLoad['method']); + $this->assertEquals(Events::preFlush, $preFlush['method']); + } } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php index fba8c9db8..24739a50c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php @@ -28,8 +28,6 @@ $metadata->mapOneToOne(array( 'joinColumns' => array(array('referencedColumnName' => 'id')) )); -$metadata->addLifecycleCallback('prePersistHandler', 'prePersist'); - $metadata->addNamedNativeQuery(array ( 'name' => 'find-all', 'query' => 'SELECT id, country, city FROM cms_addresses', @@ -89,4 +87,16 @@ $metadata->addSqlResultSetMapping(array ( 'name' => 'count', ), ) -)); \ No newline at end of file +)); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CmsAddressListener', 'postPersist'); +$metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CmsAddressListener', 'prePersist'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postUpdate, 'CmsAddressListener', 'postUpdate'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preUpdate, 'CmsAddressListener', 'preUpdate'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::postRemove, 'CmsAddressListener', 'postRemove'); +$metadata->addEntityListener(\Doctrine\ORM\Events::preRemove, 'CmsAddressListener', 'preRemove'); + +$metadata->addEntityListener(\Doctrine\ORM\Events::preFlush, 'CmsAddressListener', 'preFlush'); +$metadata->addEntityListener(\Doctrine\ORM\Events::postLoad, 'CmsAddressListener', 'postLoad'); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml index 0af5facda..b35569ae4 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml @@ -7,6 +7,10 @@ + + + + SELECT id, country, city FROM cms_addresses diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml index 696627c3c..da2afca75 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml @@ -1,6 +1,8 @@ Doctrine\Tests\Models\CMS\CmsAddress: type: entity table: cms_address + entityListeners: + CmsAddressListener: namedNativeQueries: find-all: resultSetMapping: mapping-find-all From ec2d5af2c7a2451d1e6353fc95ddd131d5b5b2f5 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Wed, 5 Dec 2012 18:57:49 -0200 Subject: [PATCH 37/41] added missing file --- .../Mapping/Builder/EntityListenerBuilder.php | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php b/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php new file mode 100644 index 000000000..09d257db6 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php @@ -0,0 +1,72 @@ +. + */ + +namespace Doctrine\ORM\Mapping\Builder; + +use Doctrine\ORM\Mapping\MappingException; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Events; + +/** + * Builder for entity listeners. + * + * @since 2.4 + * @author Fabio B. Silva + */ +class EntityListenerBuilder +{ + /** + * @var array Hash-map to handle event names. + */ + static private $events = array( + Events::preRemove => true, + Events::postRemove => true, + Events::prePersist => true, + Events::postPersist => true, + Events::preUpdate => true, + Events::postUpdate => true, + Events::postLoad => true, + Events::preFlush => true, + ); + + /** + * Lookup the entity class to find methods that match to event lifecycle names + * + * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata. + * @param string $className The listener class name. + * + * @throws \Doctrine\ORM\Mapping\MappingException When the listener class not found. + */ + static public function bindEntityListener(ClassMetadata $metadata, $className) + { + $class = $metadata->fullyQualifiedClassName($className); + + if ( ! class_exists($class)) { + throw MappingException::entityListenerClassNotFound($class, $className); + } + + foreach (get_class_methods($class) as $method) { + if ( ! isset(self::$events[$method])) { + continue; + } + + $metadata->addEntityListener($method, $class, $method); + } + } +} \ No newline at end of file From 7177306536f90837302cf4594b231e713f7a519f Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 22 Dec 2012 11:00:37 -0200 Subject: [PATCH 38/41] remove extra comma --- lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php b/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php index 09d257db6..d17abeac5 100644 --- a/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php +++ b/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php @@ -42,7 +42,7 @@ class EntityListenerBuilder Events::preUpdate => true, Events::postUpdate => true, Events::postLoad => true, - Events::preFlush => true, + Events::preFlush => true ); /** From 76c4be1b7483dadd98ff5495e5cdf1337378bc65 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Tue, 29 Jan 2013 12:19:47 -0200 Subject: [PATCH 39/41] Update docs/en/reference/events.rst Docs for lifecycle-callback event arg --- docs/en/reference/events.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index a6b75ad12..f2f112f38 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -336,6 +336,30 @@ The ``key`` of the lifecycleCallbacks is the name of the method and the value is the event type. The allowed event types are the ones listed in the previous Lifecycle Events section. +.. versionadded:: 2.4 +Lifecycle Callbacks Event Argument +----------------------------------- + +Since 2.4 the triggered event is given to the lifecycle-callback. + +With the additional argument you have access to the +``EntityManager`` and ``UnitOfWork`` APIs inside these callback methods. + +.. code-block:: php + + hasChangedField('username')) { + // Do something when the username is changed. + } + } + } + Listening to Lifecycle Events ----------------------------- From 7764ed9a8b6df0c52651c398890f13e704f5a354 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 2 Feb 2013 15:48:40 -0200 Subject: [PATCH 40/41] Docs for Entity Listener and Entity Listener Resolver --- docs/en/reference/events.rst | 205 ++++++++++++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 3 deletions(-) diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index f2f112f38..554e4e1db 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -196,9 +196,7 @@ listeners: - Lifecycle Callbacks are methods on the entity classes that are - called when the event is triggered. They receive absolutely no - arguments and are specifically designed to allow changes inside the - entity classes state. + called when the event is triggered. They receives some kind of ``EventArgs``. - Lifecycle Event Listeners are classes with specific callback methods that receives some kind of ``EventArgs`` instance which give access to the entity, EntityManager or other relevant data. @@ -337,6 +335,7 @@ the value is the event type. The allowed event types are the ones listed in the previous Lifecycle Events section. .. versionadded:: 2.4 + Lifecycle Callbacks Event Argument ----------------------------------- @@ -650,6 +649,206 @@ postLoad This event is called after an entity is constructed by the EntityManager. +Entity listeners +---------------- + +An entity listeners is a lifecycle listener classes used for an entity. + +- The entity listeners mapping may be applied to an entity class or mapped superclass. +- An entity listener is defined by mapping the entity class with the corresponding mapping. + +.. configuration-block:: + + .. code-block:: php + + + + + + + + + + .. code-block:: yaml + + MyProject\Entity\User: + type: entity + entityListeners: + UserListener: + # .... + +.. _reference-entity-listeners: + +Entity listeners class +~~~~~~~~~~~~~~~~~~~~~~ + +An ``Entity Listener`` could be any class, by default it should be a class with a no-arg constructor. + +- Different from :ref:`reference-events-implementing-listeners` an ``Entity Listener`` is invoked just to the specified entity +- An entity listener method receives two arguments, the entity instance and the lifecycle event. +- A callback method could be defined by naming convention or specifying a method mapping. +- When the listener mapping is not given the parser will lookup for methods that match with the naming convention. +- When the listener mapping is given the parser won't lookup for any naming convention. + +.. code-block:: php + + + + + + + + + + + + + + + + + + + + + + .. code-block:: yaml + + MyProject\Entity\User: + type: entity + UserListener: + preFlush: [preFlushHandler] + postLoad: [postLoadHandler] + + postPersist: [postPersistHandler] + prePersist: [prePersistHandler] + + postUpdate: [postUpdateHandler] + preUpdate: [preUpdateHandler] + + postRemove: [postRemoveHandler] + preRemove: [preRemoveHandler] + # .... + + + +Entity listeners resolver +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Doctrine invoke the listener resolver to get the listener instance. + +- An resolver allows you register a specific ``Entity Listener`` instance. +- You can also implement your own resolver by extending ``Doctrine\ORM\Mapping\DefaultEntityListenerResolver`` or implementing ``Doctrine\ORM\Mapping\EntityListenerResolver`` + +Specifying an entity listener instance : + +.. code-block:: php + + service = $service; + } + + public function preUpdate(User $user, PreUpdateEventArgs $event) + { + $this->service->doSomething($user); + } + } + + // register a entity listener. + $listener = $container->get('user_listener'); + $em->getConfiguration()->getEntityListenerResolver()->register($listener); + +Implementing your own resolver : + +.. code-block:: php + + container = $container; + } + + public function resolve($className) + { + // resolve the service id by the given class name; + $id = 'user_listener'; + + return $this->container->get($id); + } + } + + // configure the listener resolver. + $em->getConfiguration()->setEntityListenerResolver($container->get('my_resolver')); + Load ClassMetadata Event ------------------------ From c5aecd43c860f6262912824cf8184ebceccb309a Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 2 Feb 2013 16:19:35 -0200 Subject: [PATCH 41/41] Fix yaml example --- docs/en/reference/events.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index 554e4e1db..d921b42a1 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -771,18 +771,19 @@ you should map the listener method using the event type mapping. MyProject\Entity\User: type: entity - UserListener: - preFlush: [preFlushHandler] - postLoad: [postLoadHandler] + entityListeners: + UserListener: + preFlush: [preFlushHandler] + postLoad: [postLoadHandler] - postPersist: [postPersistHandler] - prePersist: [prePersistHandler] + postPersist: [postPersistHandler] + prePersist: [prePersistHandler] - postUpdate: [postUpdateHandler] - preUpdate: [preUpdateHandler] + postUpdate: [postUpdateHandler] + preUpdate: [preUpdateHandler] - postRemove: [postRemoveHandler] - preRemove: [preRemoveHandler] + postRemove: [postRemoveHandler] + preRemove: [preRemoveHandler] # ....