1
0
mirror of synced 2025-01-18 06:21:40 +03:00

support naming convention for listeners without mapping.

This commit is contained in:
Fabio B. Silva 2012-12-05 18:47:48 -02:00 committed by fabio.silva
parent 46fea51622
commit e6d9d1de47
9 changed files with 175 additions and 11 deletions

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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');
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace Doctrine\Tests\Models\CMS;
class CmsAddressListener
{
public $calls;
public function prePersist()
{
$this->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");
}
}

View File

@ -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']);
}
}
/**

View File

@ -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',
),
)
));
));
$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');

View File

@ -7,6 +7,10 @@
<entity name="Doctrine\Tests\Models\CMS\CmsAddress" table="cms_users">
<entity-listeners>
<entity-listener class="CmsAddressListener"/>
</entity-listeners>
<named-native-queries>
<named-native-query name="find-all" result-set-mapping="mapping-find-all">
<query>SELECT id, country, city FROM cms_addresses</query>

View File

@ -1,6 +1,8 @@
Doctrine\Tests\Models\CMS\CmsAddress:
type: entity
table: cms_address
entityListeners:
CmsAddressListener:
namedNativeQueries:
find-all:
resultSetMapping: mapping-find-all