Explorar el Código

[HttpKernel] added an subclass merge extension configuration compiler pass to ensure each bundle's "main" extension is loaded

Kris Wallsmith hace 14 años
padre
commit
33d47be32e

+ 1 - 0
autoload.php.dist

@@ -6,6 +6,7 @@ use Symfony\Component\ClassLoader\UniversalClassLoader;
 
 $loader = new UniversalClassLoader();
 $loader->registerNamespaces(array(
+    'Symfony\\Tests'                 => __DIR__.'/tests',
     'Symfony'                        => __DIR__.'/src',
     'Doctrine\\MongoDB'              => __DIR__.'/vendor/doctrine-mongodb/lib',
     'Doctrine\\ODM\\MongoDB'         => __DIR__.'/vendor/doctrine-mongodb-odm/lib',

+ 43 - 0
src/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php

@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Component\HttpKernel\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass as BaseMergeExtensionConfigurationPass;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Handles automatically loading each bundle's default extension.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
+ */
+class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass
+{
+    public function process(ContainerBuilder $container)
+    {
+        foreach ($container->getParameter('kernel.bundles') as $bundleName => $bundleClass) {
+            $bundleRefl = new \ReflectionClass($bundleClass);
+            $extClass = $bundleRefl->getNamespaceName().'\\DependencyInjection\\'.substr($bundleName, 0, -6).'Extension';
+
+            if (class_exists($extClass)) {
+                $ext = new $extClass();
+                $alias = $ext->getAlias();
+
+                // ensure all "main" extensions are loaded
+                if (!count($container->getExtensionConfig($alias))) {
+                    $container->loadFromExtension($alias, array());
+                }
+            }
+        }
+
+        parent::process($container);
+    }
+}

+ 2 - 0
src/Symfony/Component/HttpKernel/Kernel.php

@@ -24,6 +24,7 @@ use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpKernel\Bundle\BundleInterface;
 use Symfony\Component\HttpKernel\Config\FileLocator;
+use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
 use Symfony\Component\Config\Loader\LoaderResolver;
 use Symfony\Component\Config\Loader\DelegatingLoader;
 use Symfony\Component\Config\ConfigCache;
@@ -457,6 +458,7 @@ abstract class Kernel implements KernelInterface
         $parameterBag = new ParameterBag($this->getKernelParameters());
 
         $container = new ContainerBuilder($parameterBag);
+        $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass());
         foreach ($this->bundles as $bundle) {
             $bundle->build($container);
 

+ 66 - 0
tests/Symfony/Tests/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPassTest.php

@@ -0,0 +1,66 @@
+<?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\Tests\Component\HttpKernel;
+
+use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
+
+class MergeExtensionConfigurationPassTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAutoloadMainExtension()
+    {
+        $bundles = array(
+            'ExtensionAbsentBundle'  => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionAbsentBundle\\ExtensionAbsentBundle',
+            'ExtensionLoadedBundle'  => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionLoadedBundle\\ExtensionLoadedBundle',
+            'ExtensionPresentBundle' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionPresentBundle\\ExtensionPresentBundle',
+        );
+
+        $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerBuilder');
+        $params = $this->getMock('Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag');
+
+        $container->expects($this->once())
+            ->method('getParameter')
+            ->with('kernel.bundles')
+            ->will($this->returnValue($bundles));
+        $container->expects($this->exactly(2))
+            ->method('getExtensionConfig')
+            ->will($this->returnCallback(function($name) {
+                switch ($name) {
+                    case 'extension_present':
+                    return array();
+                    case 'extension_loaded':
+                    return array(array());
+                }
+            }));
+        $container->expects($this->once())
+            ->method('loadFromExtension')
+            ->with('extension_present', array());
+
+        $container->expects($this->any())
+            ->method('getParameterBag')
+            ->will($this->returnValue($params));
+        $params->expects($this->any())
+            ->method('all')
+            ->will($this->returnValue(array()));
+        $container->expects($this->any())
+            ->method('getDefinitions')
+            ->will($this->returnValue(array()));
+        $container->expects($this->any())
+            ->method('getAliases')
+            ->will($this->returnValue(array()));
+        $container->expects($this->any())
+            ->method('getExtensions')
+            ->will($this->returnValue(array()));
+
+        $configPass = new MergeExtensionConfigurationPass();
+        $configPass->process($container);
+    }
+}

+ 18 - 0
tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionAbsentBundle/ExtensionAbsentBundle.php

@@ -0,0 +1,18 @@
+<?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\Tests\Component\HttpKernel\Fixtures\ExtensionAbsentBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+class ExtensionAbsentBundle extends Bundle
+{
+}

+ 22 - 0
tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionLoadedBundle/DependencyInjection/ExtensionLoadedExtension.php

@@ -0,0 +1,22 @@
+<?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\Tests\Component\HttpKernel\Fixtures\ExtensionLoadedBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+class ExtensionLoadedExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+    }
+}

+ 18 - 0
tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionLoadedBundle/ExtensionLoadedBundle.php

@@ -0,0 +1,18 @@
+<?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\Tests\Component\HttpKernel\Fixtures\ExtensionLoadedBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+class ExtensionLoadedBundle extends Bundle
+{
+}

+ 22 - 0
tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionPresentBundle/DependencyInjection/ExtensionPresentExtension.php

@@ -0,0 +1,22 @@
+<?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\Tests\Component\HttpKernel\Fixtures\ExtensionPresentBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+class ExtensionPresentExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+    }
+}

+ 18 - 0
tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionPresentBundle/ExtensionPresentBundle.php

@@ -0,0 +1,18 @@
+<?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\Tests\Component\HttpKernel\Fixtures\ExtensionPresentBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+class ExtensionPresentBundle extends Bundle
+{
+}