From b25d5d277d01027fafbd806ed7fd47ebca341c7b Mon Sep 17 00:00:00 2001 From: beberlei Date: Thu, 18 Mar 2010 22:36:27 +0000 Subject: [PATCH] [2.0] DDC-283 - Add two events in SchemaTool that allow to hook into the generated Schema representation, possibly modifying or reacting to it in userland or extensions code. --- .../Tools/Event/GenerateSchemaEventArgs.php | 65 ++++++++++++++++ .../Event/GenerateSchemaTableEventArgs.php | 75 +++++++++++++++++++ lib/Doctrine/ORM/Tools/SchemaTool.php | 14 +++- lib/Doctrine/ORM/Tools/ToolEvents.php | 44 +++++++++++ .../Tests/ORM/Tools/SchemaToolTest.php | 48 ++++++++++++ 5 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php create mode 100644 lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php create mode 100644 lib/Doctrine/ORM/Tools/ToolEvents.php diff --git a/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php b/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php new file mode 100644 index 000000000..02d04a253 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php @@ -0,0 +1,65 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Event; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\ORM\EntityManager; + +/** + * Event Args used for the Events::postGenerateSchema event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class GenerateSchemaEventArgs extends \Doctrine\Common\EventArgs +{ + private $_em = null; + private $_schema = null; + + /** + * @param ClassMetadata $classMetadata + * @param Schema $schema + * @param Table $classTable + */ + public function __construct(EntityManager $em, Schema $schema) + { + $this->_em = $em; + $this->_schema = $schema; + } + + /** + * @return EntityManager + */ + public function getEntityManager() { + return $this->_em; + } + + /** + * @return Schema + */ + public function getSchema() { + return $this->_schema; + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php b/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php new file mode 100644 index 000000000..54aa6e7de --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php @@ -0,0 +1,75 @@ +. +*/ + +namespace Doctrine\ORM\Tools\Event; + +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Schema\Table; + +/** + * Event Args used for the Events::postGenerateSchemaTable event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 1.0 + * @version $Revision$ + * @author Benjamin Eberlei + */ +class GenerateSchemaTableEventArgs extends \Doctrine\Common\EventArgs +{ + private $_classMetadata = null; + private $_schema = null; + private $_classTable = null; + + /** + * @param ClassMetadata $classMetadata + * @param Schema $schema + * @param Table $classTable + */ + public function __construct(ClassMetadata $classMetadata, Schema $schema, Table $classTable) + { + $this->_classMetadata = $classMetadata; + $this->_schema = $schema; + $this->_classTable = $classTable; + } + + /** + * @return ClassMetadata + */ + public function getClassMetadata() { + return $this->_classMetadata; + } + + /** + * @return Schema + */ + public function getSchema() { + return $this->_schema; + } + + /** + * @return Table + */ + public function getClassTable() { + return $this->_classTable; + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index 7a45ab427..e0382955a 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -24,7 +24,9 @@ namespace Doctrine\ORM\Tools; use Doctrine\ORM\ORMException, Doctrine\DBAL\Types\Type, Doctrine\ORM\EntityManager, - Doctrine\ORM\Internal\CommitOrderCalculator; + Doctrine\ORM\Internal\CommitOrderCalculator, + Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs, + Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; /** * The SchemaTool is a tool to create/drop/update database schemas based on @@ -117,6 +119,8 @@ class SchemaTool $sm = $this->_em->getConnection()->getSchemaManager(); $schema = new \Doctrine\DBAL\Schema\Schema(array(), array(), $metadataSchemaConfig); + $evm = $this->_em->getEventManager(); + foreach ($classes as $class) { if (isset($processedClasses[$class->name]) || $class->isMappedSuperclass) { continue; @@ -223,6 +227,14 @@ class SchemaTool ); } } + + if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) { + $evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table)); + } + } + + if ($evm->hasListeners(ToolEvents::postGenerateSchema)) { + $evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema)); } return $schema; diff --git a/lib/Doctrine/ORM/Tools/ToolEvents.php b/lib/Doctrine/ORM/Tools/ToolEvents.php new file mode 100644 index 000000000..7ea1f570a --- /dev/null +++ b/lib/Doctrine/ORM/Tools/ToolEvents.php @@ -0,0 +1,44 @@ +. +*/ + +namespace Doctrine\ORM\Tools; + +class ToolEvents +{ + /** + * The postGenerateSchemaTable event occurs in SchemaTool#getSchemaFromMetadata() + * whenever an entity class is transformed into its table representation. It recieves + * the current non-complete Schema instance, the Entity Metadata Class instance and + * the Schema Table instance of this entity. + * + * @var string + */ + const postGenerateSchemaTable = 'postGenerateSchemaTable'; + + /** + * The postGenerateSchema event is triggered in SchemaTool#getSchemaFromMetadata() + * after all entity classes have been transformed into the related Schema structure. + * The EventArgs contain the EntityManager and the created Schema instance. + * + * @var string + */ + const postGenerateSchema = 'postGenerateSchema'; +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php index cfc52203a..ad4551515 100644 --- a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php @@ -3,6 +3,9 @@ namespace Doctrine\Tests\ORM\Tools; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\ORM\Tools\ToolEvents; +use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs; +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; require_once __DIR__ . '/../../TestInit.php'; @@ -56,4 +59,49 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue($table->hasColumn('avatar_id')); $this->assertEquals($customColumnDef, $table->getColumn('avatar_id')->getColumnDefinition()); } + + /** + * @group DDC-283 + */ + public function testPostGenerateEvents() + { + $listener = new GenerateSchemaEventListener(); + + $em = $this->_getTestEntityManager(); + $em->getEventManager()->addEventListener( + array(ToolEvents::postGenerateSchemaTable, ToolEvents::postGenerateSchema), $listener + ); + $schemaTool = new SchemaTool($em); + + $classes = array( + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'), + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsArticle'), + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsComment'), + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsEmployee'), + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup'), + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'), + $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'), + ); + + $schema = $schemaTool->getSchemaFromMetadata($classes); + + $this->assertEquals(count($classes), $listener->tableCalls); + $this->assertTrue($listener->schemaCalled); + } +} + +class GenerateSchemaEventListener +{ + public $tableCalls = 0; + public $schemaCalled = false; + + public function postGenerateSchemaTable(GenerateSchemaTableEventArgs $eventArgs) + { + $this->tableCalls++; + } + + public function postGenerateSchema(GenerateSchemaEventArgs $eventArgs) + { + $this->schemaCalled = true; + } } \ No newline at end of file