From c4e330e5ca205c1759720a3ba5523e152a124ddf Mon Sep 17 00:00:00 2001 From: jwage Date: Wed, 15 Jul 2009 20:18:40 +0000 Subject: [PATCH] [2.0] Placing loadClassMetadata() event so users can manipulate class meta data through events --- lib/Doctrine/ORM/EntityManager.php | 4 +- .../ORM/Event/LoadClassMetadataEventArgs.php | 27 ++++++++++ lib/Doctrine/ORM/Events.php | 1 + .../ORM/Mapping/ClassMetadataFactory.php | 17 +++++-- .../Tests/Mocks/MetadataDriverMock.php | 5 ++ tests/Doctrine/Tests/ORM/Mapping/AllTests.php | 1 + .../ORM/Mapping/ClassMetadataFactoryTest.php | 16 +++++- .../Mapping/ClassMetadataLoadEventTest.php | 51 +++++++++++++++++++ .../Tests/ORM/Mapping/ClassMetadataTest.php | 1 + 9 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index e29b651eb..c5474674e 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -141,9 +141,7 @@ class EntityManager $this->_conn = $conn; $this->_config = $config; $this->_eventManager = $eventManager; - $this->_metadataFactory = new ClassMetadataFactory( - $this->_config->getMetadataDriverImpl(), - $this->_conn->getDatabasePlatform()); + $this->_metadataFactory = new ClassMetadataFactory($this); $this->_metadataFactory->setCacheDriver($this->_config->getMetadataCacheImpl()); $this->_unitOfWork = new UnitOfWork($this); $this->_proxyGenerator = new DynamicProxyGenerator($this, $this->_config->getCacheDir()); diff --git a/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php b/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php new file mode 100644 index 000000000..862152a99 --- /dev/null +++ b/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php @@ -0,0 +1,27 @@ + + * @since 2.0 + */ +class LoadClassMetadataEventArgs extends EventArgs +{ + private $_classMetadata; + + public function __construct(\Doctrine\ORM\Mapping\ClassMetadata $classMetadata) + { + $this->_classMetadata = $classMetadata; + } + + public function getClassMetadata() + { + return $this->_classMetadata; + } +} + diff --git a/lib/Doctrine/ORM/Events.php b/lib/Doctrine/ORM/Events.php index aa6e84e41..2668671fc 100644 --- a/lib/Doctrine/ORM/Events.php +++ b/lib/Doctrine/ORM/Events.php @@ -40,4 +40,5 @@ final class Events const preUpdate = 'preUpdate'; const postUpdate = 'postUpdate'; const load = 'load'; + const loadClassMetadata = 'loadClassMetadata'; } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index f382f7933..4290fdddc 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -23,6 +23,7 @@ namespace Doctrine\ORM\Mapping; use Doctrine\Common\DoctrineException; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\ORM\Events; /** * The metadata factory is used to create ClassMetadata objects that contain all the @@ -38,10 +39,13 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; */ class ClassMetadataFactory { + private $_em; /** The targeted database platform. */ private $_targetPlatform; /** The used metadata driver. */ private $_driver; + /** The event manager instance */ + private $_evm; /** The used cache driver. */ private $_cacheDriver; private $_loadedMetadata = array(); @@ -51,10 +55,12 @@ class ClassMetadataFactory * * @param $driver The metadata driver to use. */ - public function __construct($driver, AbstractPlatform $targetPlatform) + public function __construct(\Doctrine\ORM\EntityManager $em) { - $this->_driver = $driver; - $this->_targetPlatform = $targetPlatform; + $this->_em = $em; + $this->_driver = $em->getConfiguration()->getMetadataDriverImpl(); + $this->_targetPlatform = $em->getConnection()->getDatabasePlatform(); + $this->_evm = $em->getEventManager(); } /** @@ -183,6 +189,11 @@ class ClassMetadataFactory $class->setParentClasses($visited); + if ($this->_evm->hasListeners(Events::loadClassMetadata)) { + $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class); + $this->_evm->dispatchEvent(Events::loadClassMetadata, $eventArgs); + } + $this->_generateStaticSql($class); $this->_loadedMetadata[$className] = $class; diff --git a/tests/Doctrine/Tests/Mocks/MetadataDriverMock.php b/tests/Doctrine/Tests/Mocks/MetadataDriverMock.php index bedda6d40..045720e90 100644 --- a/tests/Doctrine/Tests/Mocks/MetadataDriverMock.php +++ b/tests/Doctrine/Tests/Mocks/MetadataDriverMock.php @@ -13,4 +13,9 @@ class MetadataDriverMock { return false; } + + public function preload() + { + return array(); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AllTests.php b/tests/Doctrine/Tests/ORM/Mapping/AllTests.php index 29e94c011..64df08927 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AllTests.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AllTests.php @@ -23,6 +23,7 @@ class AllTests $suite->addTestSuite('Doctrine\Tests\ORM\Mapping\XmlDriverTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Mapping\YamlDriverTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Mapping\ClassMetadataFactoryTest'); + $suite->addTestSuite('Doctrine\Tests\ORM\Mapping\ClassMetadataLoadEventTest'); return $suite; } diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php index 5f50d80fc..bc1219202 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php @@ -4,7 +4,11 @@ namespace Doctrine\Tests\ORM\Mapping; use Doctrine\Tests\Mocks\MetadataDriverMock; use Doctrine\Tests\Mocks\DatabasePlatformMock; +use Doctrine\Tests\Mocks\EntityManagerMock; +use Doctrine\Tests\Mocks\ConnectionMock; +use Doctrine\Tests\Mocks\DriverMock; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\Common\EventManager; require_once __DIR__ . '/../../TestInit.php'; @@ -13,8 +17,16 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase public function testGetMetadataForSingleClass() { - $mockPlatform = new DatabasePlatformMock(); + $driverMock = new DriverMock(); + $config = new \Doctrine\ORM\Configuration(); + $eventManager = new EventManager(); + $conn = new ConnectionMock(array(), $driverMock, $config, $eventManager); $mockDriver = new MetadataDriverMock(); + $config->setMetadataDriverImpl($mockDriver); + + $entityManager = EntityManagerMock::create($conn, $config, $eventManager); + + $mockPlatform = $conn->getDatabasePlatform(); $mockPlatform->setPrefersSequences(true); $mockPlatform->setPrefersIdentityColumns(false); @@ -30,7 +42,7 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase $cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); // SUT - $cmf = new ClassMetadataFactoryTestSubject($mockDriver, $mockPlatform); + $cmf = new ClassMetadataFactoryTestSubject($entityManager); $cmf->setMetadataForClass('Doctrine\Tests\ORM\Mapping\TestEntity1', $cm1); // Prechecks diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php new file mode 100644 index 000000000..64357cf99 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php @@ -0,0 +1,51 @@ +_getTestEntityManager(); + $metadataFactory = $em->getMetadataFactory(); + $evm = $em->getEventManager(); + $evm->addEventListener(Events::loadClassMetadata, $this); + $classMetadata = $metadataFactory->getMetadataFor('Doctrine\Tests\ORM\Mapping\LoadEventTestEntity'); + $this->assertTrue($classMetadata->hasField('about')); + } + + public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs) + { + $classMetadata = $eventArgs->getClassMetadata(); + $field = array( + 'fieldName' => 'about', + 'type' => 'string', + 'length' => 255 + ); + $classMetadata->mapField($field); + } +} + +/** + * @Entity + * @Table(name="load_event_test_entity") + */ +class LoadEventTestEntity +{ + /** + * @Id @Column(type="integer") + * @GeneratedValue(strategy="AUTO") + */ + private $id; + /** + * @Column(type="string", length=255) + */ + private $name; + + private $about; +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index 386302dab..32c02f59a 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -3,6 +3,7 @@ namespace Doctrine\Tests\ORM\Mapping; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Events; require_once __DIR__ . '/../../TestInit.php';