Преглед изворни кода

[DoctrineBundle] Implement Proxy CacheWarmer

Benjamin Eberlei пре 14 година
родитељ
комит
4d4eec618c

+ 60 - 0
src/Symfony/Bundle/DoctrineBundle/CacheWarmer/ProxyCacheWarmer.php

@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle\CacheWarmer;
+
+use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
+
+/**
+ * The proxy generator cache warmer generates all entity proxies.
+ *
+ * In the process of generating proxies the cache for all the metadata is primed also,
+ * since this information is necessary to build the proxies in the first place.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ProxyCacheWarmer implements CacheWarmerInterface
+{
+    /**
+     * @var Container
+     */
+    private $container;
+
+    /**
+     * @param Container $container
+     */
+    public function __construct(Container $container)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * This cache warmer is not optional, without proxies fatal error occour!
+     *
+     * @return false
+     */
+    public function isOptional()
+    {
+        return false;
+    }
+
+    public function warmUp($cacheDir)
+    {
+        $entityManagers = $this->container->getParameter('doctrine.orm.entity_managers');
+        foreach ($entityManagers AS $entityManagerName) {
+            $em = $this->container->get(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName));
+            /* @var $em Doctrine\ORM\EntityManager */
+            $classes = $em->getMetadataFactory()->getAllMetadata();
+            $em->getProxyFactory()->generateProxyClasses($classes);
+        }
+    }
+}

+ 2 - 0
src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php

@@ -234,6 +234,8 @@ class DoctrineExtension extends AbstractDoctrineExtension
                 );
             }
         }
+
+        $container->setParameter('doctrine.orm.entity_managers', array_keys($config['entity_managers']));
     }
 
     protected function mergeOrmConfig(array $configs, $container)

+ 9 - 0
src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml

@@ -12,6 +12,7 @@
         <parameter key="doctrine.orm.configuration_class">Doctrine\ORM\Configuration</parameter>
         <parameter key="doctrine.orm.entity_manager_class">Doctrine\ORM\EntityManager</parameter>
         <parameter key="doctrine.orm.auto_generate_proxy_classes">false</parameter>
+        <parameter key="doctrine.orm.entity_managers" type="collection"></parameter>
 
         <!-- proxies -->
         <parameter key="doctrine.orm.proxy_namespace">Proxies</parameter>
@@ -41,6 +42,9 @@
         
         <!--  security/acl -->
         <parameter key="security.acl.collection_cache.class">Symfony\Bundle\DoctrineBundle\Security\AclCollectionCache</parameter>
+
+        <!-- cache warmer -->
+        <parameter key="doctrine.orm.proxy_cache_warmer.class">Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer</parameter>
     </parameters>
 
     <services>
@@ -58,5 +62,10 @@
             <tag name="request.param_converter" />
             <argument type="service" id="doctrine.orm.default_entity_manager" />
         </service>
+
+        <service id="doctrine.orm.proxy_cache_warmer" class="%doctrine.orm.proxy_cache_warmer.class%" public="false">
+            <tag name="kernel.cache_warmer" />
+            <argument type="service" id="service_container" />
+        </service>
     </services>
 </container>

+ 54 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/CacheWarmer/ProxyCacheWarmerTest.php

@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle\Tests\CacheWarmer;
+
+use Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer;
+
+class ProxyCacheWarmerTest extends \Symfony\Bundle\DoctrineBundle\Tests\TestCase
+{
+    /**
+     * This is not necessarily a good test, it doesnt generate any proxies
+     * because there are none in the AnnotationsBundle. However that is
+     * rather a task of doctrine to test. We touch the lines here and
+     * verify that the container is called correctly for the relevant information.
+     */
+    public function testWarmCache()
+    {
+        $testManager = $this->createTestEntityManager(array(
+            __DIR__ . "/../DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Entity")
+        );
+        $container = $this->getMock('Symfony\Component\DependencyInjection\Container');
+        $container->expects($this->at(0))
+                  ->method('getParameter')
+                  ->with($this->equalTo('doctrine.orm.entity_managers'))
+                  ->will($this->returnValue(array('default', 'foo')));
+        $container->expects($this->at(1))
+                  ->method('get')
+                  ->with($this->equalTo('doctrine.orm.default_entity_manager'))
+                  ->will($this->returnValue($testManager));
+        $container->expects($this->at(2))
+                  ->method('get')
+                  ->with($this->equalTo('doctrine.orm.foo_entity_manager'))
+                  ->will($this->returnValue($testManager));
+
+        $cacheWarmer = new ProxyCacheWarmer($container);
+        $cacheWarmer->warmUp(sys_get_temp_dir());
+    }
+
+    public function testProxyCacheWarmingIsNotOptional()
+    {
+        $container = $this->getMock('Symfony\Component\DependencyInjection\Container');
+        $cacheWarmer = new ProxyCacheWarmer($container);
+
+        $this->assertFalse($cacheWarmer->isOptional());
+    }
+}

+ 1 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php

@@ -34,6 +34,7 @@ class ContainerTest extends TestCase
         $this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.orm.default_entity_manager.event_manager'));
         $this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.dbal.event_manager'));
         $this->assertInstanceOf('Doctrine\DBAL\Event\Listeners\MysqlSessionInit', $container->get('doctrine.dbal.default_connection.events.mysqlsessioninit'));
+        $this->assertInstanceOf('Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer', $container->get('doctrine.orm.proxy_cache_warmer'));
 
         $this->assertSame($container->get('my.platform'), $container->get('doctrine.dbal.default_connection')->getDatabasePlatform());
     }

+ 4 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php

@@ -160,6 +160,8 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $this->assertEquals('create', $definition->getFactoryMethod());
         $this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
 
+        $this->assertEquals(array("default"), $container->getParameter('doctrine.orm.entity_managers'), "Set of the existing EntityManagers names is incorrect.");
+
         $arguments = $definition->getArguments();
         $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
         $this->assertEquals('doctrine.dbal.default_connection', (string) $arguments[0]);
@@ -574,6 +576,8 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $container->getCompilerPassConfig()->setRemovingPasses(array());
         $container->compile();
 
+        $this->assertEquals(array("em1", "em2"), $container->getParameter('doctrine.orm.entity_managers'), "Set of the existing EntityManagers names is incorrect.");
+
         $def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
         $def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');
 

+ 2 - 2
src/Symfony/Bundle/DoctrineBundle/Tests/TestCase.php

@@ -29,13 +29,13 @@ class TestCase extends \PHPUnit_Framework_TestCase
     /**
      * @return EntityManager
      */
-    protected function createTestEntityManager()
+    protected function createTestEntityManager($paths = array())
     {
         $config = new \Doctrine\ORM\Configuration();
         $config->setAutoGenerateProxyClasses(true);
         $config->setProxyDir(\sys_get_temp_dir());
         $config->setProxyNamespace('SymfonyTests\Doctrine');
-        $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
+        $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths));
         $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache());
         $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache());