Ver Fonte

[DoctrineMongoDBBundle] switched to compiler passes for proxy/hydrator directory creation and event listeners

Bulat Shakirzyanov há 14 anos atrás
pai
commit
8235f71f57

+ 0 - 58
src/Symfony/Bundle/DoctrineAbstractBundle/Event/EventManager.php

@@ -1,58 +0,0 @@
-<?php
-
-namespace Symfony\Bundle\DoctrineAbstractBundle\Event;
-
-use Doctrine\Common\EventManager as BaseEventManager;
-use Symfony\Component\DependencyInjection\TaggedContainerInterface;
-
-/**
- * An event manager that can pull listeners and subscribers from the service container.
- *
- * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
- */
-class EventManager extends BaseEventManager
-{
-    /**
-     * Loads event listeners from the service container.
-     *
-     *     <service class="MyListener">
-     *         <tag name="doctrine.odm.mongodb.event_listener" event="prePersist" />
-     *         <tag name="doctrine.odm.mongodb.event_listener" event="preUpdate" />
-     *     </service>
-     *
-     * @param TaggedContainerInterface $container The service container
-     * @param string $tagName The name of the tag to load
-     */
-    public function loadTaggedEventListeners(TaggedContainerInterface $container, $tagName = 'doctrine.common.event_listener')
-    {
-        foreach ($container->findTaggedServiceIds($tagName) as $id => $instances) {
-            $events = array();
-            foreach ($instances as $attributes) {
-                if (isset($attributes['event'])) {
-                    $events[] = $attributes['event'];
-                }
-            }
-
-            if (0 < count($events)) {
-                $this->addEventListener($events, $container->get($id));
-            }
-        }
-    }
-
-    /**
-     * Loads event subscribers from the service container.
-     *
-     *     <service class="MySubscriber">
-     *         <tag name="doctrine.odm.mongodb.event_subscriber" />
-     *     </service>
-     *
-     * @param TaggedContainerInterface $container The service container
-     * @param string $tagName The name of the tag to load
-     */
-    public function loadTaggedEventSubscribers(TaggedContainerInterface $container, $tagName = 'doctrine.common.event_listener')
-    {
-        foreach ($container->findTaggedServiceIds($tagName) as $id => $instances) {
-            $this->addEventSubscriber($container->get($id));
-        }
-    }
-}

+ 4 - 0
src/Symfony/Bundle/DoctrineBundle/DependencyInjection/Compiler/CreateProxyDirectoryPass.php

@@ -12,6 +12,10 @@ class CreateProxyDirectoryPass implements CompilerPassInterface
         if (!$container->hasParameter('doctrine.orm.proxy_dir')) {
             return;
         }
+        // Don't do anything if auto_generate_proxy_classes is false
+        if (!$container->getParameter('doctrine.orm.auto_generate_proxy_classes')) {
+            return;
+        }
         $proxyCacheDir = $container->getParameter('doctrine.orm.proxy_dir');
         // Create entity proxy directory
         if (!is_dir($proxyCacheDir)) {

+ 30 - 0
src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateHydratorDirectoryPass.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+class CreateHydratorDirectoryPass implements CompilerPassInterface
+{
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasParameter('doctrine.odm.mongodb.hydrator_dir')) {
+            return;
+        }
+        // Don't do anything if auto_generate_hydrator_classes is false
+        if (!$container->getParameter('doctrine.odm.mongodb.auto_generate_hydrator_classes')) {
+            return;
+        }
+        // Create document proxy directory
+        $hydratorCacheDir = $container->getParameter('doctrine.odm.mongodb.hydrator_dir');
+        if (!is_dir($hydratorCacheDir)) {
+            if (false === @mkdir($hydratorCacheDir, 0777, true)) {
+                die(sprintf('Unable to create the Doctrine Hydrator directory (%s)', dirname($hydratorCacheDir)));
+            }
+        } elseif (!is_writable($hydratorCacheDir)) {
+            die(sprintf('Unable to write in the Doctrine Hydrator directory (%s)', $hydratorCacheDir));
+        }
+    }
+
+}

+ 30 - 0
src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateProxyDirectoryPass.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+class CreateProxyDirectoryPass implements CompilerPassInterface
+{
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasParameter('doctrine.odm.mongodb.proxy_dir')) {
+            return;
+        }
+        // Don't do anything if auto_generate_proxy_classes is false
+        if (!$container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes')) {
+            return;
+        }
+        // Create document proxy directory
+        $proxyCacheDir = $container->getParameter('doctrine.odm.mongodb.proxy_dir');
+        if (!is_dir($proxyCacheDir)) {
+            if (false === @mkdir($proxyCacheDir, 0777, true)) {
+                die(sprintf('Unable to create the Doctrine Proxy directory (%s)', dirname($proxyCacheDir)));
+            }
+        } elseif (!is_writable($proxyCacheDir)) {
+            die(sprintf('Unable to write in the Doctrine Proxy directory (%s)', $proxyCacheDir));
+        }
+    }
+
+}

+ 59 - 0
src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
+{
+    protected $container;
+
+    public function process(ContainerBuilder $container)
+    {
+        $this->container = $container;
+        foreach ($container->findTaggedServiceIds('doctrine.odm.mongodb.event_manager') as $id => $tag) {
+            $definition = $container->getDefinition($id);
+            $prefix = substr($id, 0, -1 * strlen('_event_manager'));
+            $this->registerListeners($prefix, $definition);
+            $this->registerSubscribers($prefix, $definition);
+        }
+    }
+
+    protected function registerSubscribers($prefix, $definition)
+    {
+        $subscribers = array_merge(
+            $this->container->findTaggedServiceIds('doctrine.common.event_subscriber'),
+            $this->container->findTaggedServiceIds($prefix.'_event_subscriber')
+        );
+
+        foreach ($subscribers as $id => $instances) {
+            $definition->addMethodCall('addEventSubscriber', array(new Reference($id)));
+        }
+    }
+
+    protected function registerListeners($prefix, $definition)
+    {
+        $listeners = array_merge(
+            $this->container->findTaggedServiceIds('doctrine.common.event_listener'),
+            $this->container->findTaggedServiceIds($prefix.'_event_listener')
+        );
+
+        foreach ($listeners as $listenerId => $instances) {
+            $events = array();
+            foreach ($instances as $attributes) {
+                if (isset($attributes['event'])) {
+                    $events[] = $attributes['event'];
+                }
+            }
+
+            if (0 < count($events)) {
+                $definition->addMethodCall('addEventListener', array(
+                    $events,
+                    new Reference($listenerId),
+                ));
+            }
+        }
+    }
+}

+ 8 - 49
src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/DoctrineMongoDBExtension.php

@@ -5,6 +5,7 @@ namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection;
 use Symfony\Component\DependencyInjection\Extension\Extension;
 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Alias;
 use Symfony\Component\DependencyInjection\Reference;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\DependencyInjection\Resource\FileResource;
@@ -31,45 +32,11 @@ class DoctrineMongoDBExtension extends AbstractDoctrineExtension
      */
     public function mongodbLoad($config, ContainerBuilder $container)
     {
-        $this->createProxyDirectory($container->getParameter('kernel.cache_dir'));
-        $this->createHydratorDirectory($container->getParameter('kernel.cache_dir'));
         $this->loadDefaults($config, $container);
         $this->loadConnections($config, $container);
         $this->loadDocumentManagers($config, $container);
     }
 
-    /**
-     * Create the Doctrine MongoDB ODM Document proxy directory
-     */
-    protected function createProxyDirectory($tmpDir)
-    {
-        // Create document proxy directory
-        $proxyCacheDir = $tmpDir.'/doctrine/odm/mongodb/Proxies';
-        if (!is_dir($proxyCacheDir)) {
-            if (false === @mkdir($proxyCacheDir, 0777, true)) {
-                die(sprintf('Unable to create the Doctrine Proxy directory (%s)', dirname($proxyCacheDir)));
-            }
-        } elseif (!is_writable($proxyCacheDir)) {
-            die(sprintf('Unable to write in the Doctrine Proxy directory (%s)', $proxyCacheDir));
-        }
-    }
-
-    /**
-     * Create the Doctrine MongoDB ODM Document hydrator directory
-     */
-    protected function createHydratorDirectory($tmpDir)
-    {
-        // Create document hydrator directory
-        $hydratorCacheDir = $tmpDir.'/doctrine/odm/mongodb/Hydrators';
-        if (!is_dir($hydratorCacheDir)) {
-            if (false === @mkdir($hydratorCacheDir, 0777, true)) {
-                die(sprintf('Unable to create the Doctrine Hydrator directory (%s)', dirname($hydratorCacheDir)));
-            }
-        } elseif (!is_writable($hydratorCacheDir)) {
-            die(sprintf('Unable to write in the Doctrine Hydrator directory (%s)', $hydratorCacheDir));
-        }
-    }
-
     /**
      * Loads the default configuration.
      *
@@ -171,20 +138,8 @@ class DoctrineMongoDBExtension extends AbstractDoctrineExtension
         $eventManagerId = sprintf('doctrine.odm.mongodb.%s_event_manager', $eventManagerName);
         if (!$container->hasDefinition($eventManagerId)) {
             $eventManagerDef = new Definition('%doctrine.odm.mongodb.event_manager_class%');
-            $eventManagerDef->addMethodCall('loadTaggedEventListeners', array(
-                new Reference('service_container'),
-            ));
-            $eventManagerDef->addMethodCall('loadTaggedEventListeners', array(
-                new Reference('service_container'),
-                sprintf('doctrine.odm.mongodb.%s_event_listener', $eventManagerName),
-            ));
-            $eventManagerDef->addMethodCall('loadTaggedEventSubscribers', array(
-                new Reference('service_container'),
-            ));
-            $eventManagerDef->addMethodCall('loadTaggedEventSubscribers', array(
-                new Reference('service_container'),
-                sprintf('doctrine.odm.mongodb.%s_event_subscriber', $eventManagerName),
-            ));
+            $eventManagerDef->addTag('doctrine.odm.mongodb.event_manager');
+            $eventManagerDef->setPublic(false);
             $container->setDefinition($eventManagerId, $eventManagerDef);
         }
 
@@ -201,7 +156,11 @@ class DoctrineMongoDBExtension extends AbstractDoctrineExtension
         if ($documentManager['name'] == $defaultDocumentManager) {
             $container->setAlias(
                 'doctrine.odm.mongodb.document_manager',
-                sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name'])
+                new Alias(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name']))
+            );
+            $container->setAlias(
+                'doctrine.odm.mongodb.event_manager',
+                new Alias(sprintf('doctrine.odm.mongodb.%s_event_manager', $documentManager['name']))
             );
         }
     }

+ 13 - 0
src/Symfony/Bundle/DoctrineMongoDBBundle/DoctrineMongoDBBundle.php

@@ -2,7 +2,12 @@
 
 namespace Symfony\Bundle\DoctrineMongoDBBundle;
 
+use Symfony\Component\DependencyInjection\Compiler\PassConfig;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\CreateHydratorDirectoryPass;
+use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\CreateProxyDirectoryPass;
+use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\RegisterEventListenersAndSubscribersPass;
 
 /**
  * Doctrine MongoDB ODM bundle.
@@ -13,4 +18,12 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
  */
 class DoctrineMongoDBBundle extends Bundle
 {
+    public function registerExtensions(ContainerBuilder $container)
+    {
+        parent::registerExtensions($container);
+
+        $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
+        $container->addCompilerPass(new CreateProxyDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING);
+        $container->addCompilerPass(new CreateHydratorDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING);
+    }
 }

+ 3 - 12
src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml

@@ -14,14 +14,16 @@
     <parameter key="doctrine.odm.mongodb.document_manager_class">Doctrine\ODM\MongoDB\DocumentManager</parameter>
     <parameter key="doctrine.odm.mongodb.logger_class">Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger</parameter>
     <parameter key="doctrine.odm.mongodb.data_collector_class">Symfony\Bundle\DoctrineMongoDBBundle\DataCollector\DoctrineMongoDBDataCollector</parameter>
-    <parameter key="doctrine.odm.mongodb.event_manager_class">Symfony\Bundle\DoctrineAbstractBundle\Event\EventManager</parameter>
+    <parameter key="doctrine.odm.mongodb.event_manager_class">Doctrine\Common\EventManager</parameter>
 
     <!-- proxies -->
     <parameter key="doctrine.odm.mongodb.proxy_namespace">Proxies</parameter>
+    <parameter key="doctrine.odm.mongodb.proxy_dir">%kernel.cache_dir%/doctrine/odm/mongodb/Proxies</parameter>
     <parameter key="doctrine.odm.mongodb.auto_generate_proxy_classes">false</parameter>
 
     <!-- hydrators -->
     <parameter key="doctrine.odm.mongodb.hydrator_namespace">Proxies</parameter>
+    <parameter key="doctrine.odm.mongodb.hydrator_dir">%kernel.cache_dir%/doctrine/odm/mongodb/Hydrators</parameter>
     <parameter key="doctrine.odm.mongodb.auto_generate_hydrator_classes">false</parameter>
 
     <!-- cache -->
@@ -85,16 +87,5 @@
 
     <service id="security.user.document_manager" alias="doctrine.odm.mongodb.default_document_manager" />
 
-    <!-- events -->
-    <service id="doctrine.odm.mongodb.event_manager" class="%doctrine.odm.mongodb.event_manager_class%">
-      <call method="loadTaggedEventListeners">
-        <argument type="service" id="service_container" />
-        <argument>doctrine.odm.mongodb.event_listener</argument>
-      </call>
-      <call method="loadTaggedEventSubscribers">
-        <argument type="service" id="service_container" />
-        <argument>doctrine.odm.mongodb.event_listener</argument>
-      </call>
-    </service>
   </services>
 </container>

+ 1 - 1
src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php

@@ -55,6 +55,6 @@ class ContainerTest extends TestCase
         $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.cache'));
         $this->assertInstanceOf('Doctrine\ODM\MongoDB\DocumentManager', $container->get('doctrine.odm.mongodb.document_manager'));
         $this->assertInstanceof('Doctrine\Common\Annotations\AnnotationReader', $container->get('doctrine.odm.mongodb.metadata.annotation_reader'));
-        $this->assertInstanceof('Symfony\Bundle\DoctrineAbstractBundle\Event\EventManager', $container->get('doctrine.odm.mongodb.event_manager'));
+        $this->assertInstanceof('Doctrine\Common\EventManager', $container->get('doctrine.odm.mongodb.event_manager'));
     }
 }