Explorar o código

added the concept of a main DIC extension for bundles

This allows for better conventions and better error messages if you
use the wrong configuration alias in a config file.

This is also the first step for a bigger refactoring of how the configuration
works (see next commits).

 * Bundle::registerExtensions() method has been renamed to Bundle::build()

 * The "main" DIC extension must be renamed to the new convention to be
   automatically registered:

      SensioBlogBundle -> DependencyInjection\SensioBlogExtension

 * The main DIC extension alias must follow the convention:

      sensio_blog for SensioBlogBundle

 * If you have more than one extension for a bundle (which should really
   never be the case), they must be registered manually by overriding the
   build() method

 * If you use YAML or PHP for your configuration, renamed the following
   configuration entry points in your configs:

      app -> framework
      webprofiler -> web_profiler
      doctrine_odm -> doctrine_mongo_db
Fabien Potencier %!s(int64=14) %!d(string=hai) anos
pai
achega
14aa95ba21

+ 2 - 2
src/Symfony/Bundle/AsseticBundle/AsseticBundle.php

@@ -24,9 +24,9 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
  */
 class AsseticBundle extends Bundle
 {
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addCompilerPass(new AssetManagerPass());
         $container->addCompilerPass(new FilterManagerPass());

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

@@ -25,9 +25,9 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
  */
 class DoctrineBundle extends Bundle
 {
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
     }

+ 1 - 1
src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/DoctrineMongoDBExtension.php

@@ -402,6 +402,6 @@ class DoctrineMongoDBExtension extends AbstractDoctrineExtension
      */
     public function getAlias()
     {
-        return 'doctrine_odm';
+        return 'doctrine_mongo_db';
     }
 }

+ 2 - 2
src/Symfony/Bundle/DoctrineMongoDBBundle/DoctrineMongoDBBundle.php

@@ -27,9 +27,9 @@ use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\RegisterEv
  */
 class DoctrineMongoDBBundle extends Bundle
 {
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
         $container->addCompilerPass(new CreateProxyDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING);

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

@@ -506,6 +506,6 @@ class FrameworkExtension extends Extension
 
     public function getAlias()
     {
-        return 'app';
+        return 'framework';
     }
 }

+ 2 - 2
src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

@@ -64,9 +64,9 @@ class FrameworkBundle extends Bundle
         }
     }
 
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addScope(new Scope('request'));
 

+ 2 - 2
src/Symfony/Bundle/SecurityBundle/SecurityBundle.php

@@ -22,9 +22,9 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVoters
  */
 class SecurityBundle extends Bundle
 {
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addCompilerPass(new AddSecurityVotersPass());
     }

+ 2 - 2
src/Symfony/Bundle/TwigBundle/TwigBundle.php

@@ -22,9 +22,9 @@ use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass;
  */
 class TwigBundle extends Bundle
 {
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addCompilerPass(new TwigEnvironmentPass());
     }

+ 1 - 1
src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php

@@ -85,6 +85,6 @@ class WebProfilerExtension extends Extension
 
     public function getAlias()
     {
-        return 'webprofiler';
+        return 'web_profiler';
     }
 }

+ 2 - 2
src/Symfony/Bundle/ZendBundle/ZendBundle.php

@@ -22,9 +22,9 @@ use Symfony\Bundle\ZendBundle\DependencyInjection\Compiler\ZendLoggerWriterPass;
  */
 class ZendBundle extends Bundle
 {
-    public function registerExtensions(ContainerBuilder $container)
+    public function build(ContainerBuilder $container)
     {
-        parent::registerExtensions($container);
+        parent::build($container);
 
         $container->addCompilerPass(new ZendLoggerWriterPass());
     }

+ 32 - 27
src/Symfony/Component/HttpKernel/Bundle/Bundle.php

@@ -13,6 +13,7 @@ namespace Symfony\Component\HttpKernel\Bundle;
 
 use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\Console\Application;
 use Symfony\Component\Finder\Finder;
 
@@ -41,6 +42,37 @@ abstract class Bundle extends ContainerAware implements BundleInterface
     {
     }
 
+    /**
+     * Builds the bundle.
+     *
+     * It is only ever called once when the cache is empty.
+     *
+     * The default implementation automatically registers a DIC extension
+     * if its name is the same as the bundle name after replacing the
+     * Bundle suffix by Extension (DependencyInjection\SensioBlogExtension
+     * for a SensioBlogBundle for instance). In such a case, the alias
+     * is forced to be the underscore version of the bundle name
+     * (sensio_blog for a SensioBlogBundle for instance).
+     *
+     * This method can be overriden to register compilation passes,
+     * other extensions, ...
+     *
+     * @param ContainerBuilder $container A ContainerBuilder instance
+     */
+    public function build(ContainerBuilder $container)
+    {
+        $class = $this->getNamespace().'\\DependencyInjection\\'.str_replace('Bundle', 'Extension', $this->getName());
+        if (class_exists($class)) {
+            $extension = new $class();
+            $alias = Container::underscore(str_replace('Bundle', '', $this->getName()));
+            if ($alias !== $extension->getAlias()) {
+                throw new \LogicException(sprintf('The extension alias for the default extension of a bundle must be the underscored version of the bundle name ("%s" vs "%s")', $alias, $extension->getAlias()));
+            }
+
+            $container->registerExtension($extension);
+        }
+    }
+
     /**
      * Gets the Bundle namespace.
      *
@@ -96,33 +128,6 @@ abstract class Bundle extends ContainerAware implements BundleInterface
         return $this->name = false === $pos ? $name :  substr($name, $pos + 1);
     }
 
-    /**
-     * Finds and registers Dependency Injection Container extensions.
-     *
-     * Override this method if your DIC extensions do not follow the conventions:
-     *
-     * * Extensions are in the 'DependencyInjection/' sub-directory
-     * * Extension class names ends with 'Extension'
-     *
-     * @param ContainerBuilder $container A ContainerBuilder instance
-     */
-    public function registerExtensions(ContainerBuilder $container)
-    {
-        if (!$dir = realpath($this->getPath().'/DependencyInjection')) {
-            return;
-        }
-
-        $finder = new Finder();
-        $finder->files()->name('*Extension.php')->in($dir);
-
-        $prefix = $this->getNamespace().'\\DependencyInjection';
-        foreach ($finder as $file) {
-            $class = $prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php');
-
-            $container->registerExtension(new $class());
-        }
-    }
-
     /**
      * Finds and registers Commands.
      *

+ 11 - 0
src/Symfony/Component/HttpKernel/Bundle/BundleInterface.php

@@ -11,6 +11,8 @@
 
 namespace Symfony\Component\HttpKernel\Bundle;
 
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
 /**
  * BundleInterface.
  *
@@ -28,6 +30,15 @@ interface BundleInterface
      */
     function shutdown();
 
+    /**
+     * Builds the bundle.
+     *
+     * It is only ever called once when the cache is empty.
+     *
+     * @param ContainerBuilder $container A ContainerBuilder instance
+     */
+    public function build(ContainerBuilder $container);
+
     /**
      * Returns the bundle parent name.
      *

+ 1 - 1
src/Symfony/Component/HttpKernel/Kernel.php

@@ -458,7 +458,7 @@ abstract class Kernel implements KernelInterface
 
         $container = new ContainerBuilder($parameterBag);
         foreach ($this->bundles as $bundle) {
-            $bundle->registerExtensions($container);
+            $bundle->build($container);
 
             if ($this->debug) {
                 $container->addObjectResource($bundle);

+ 16 - 14
src/Symfony/Component/HttpKernel/bootstrap.php

@@ -223,10 +223,12 @@ class ContainerAware implements ContainerAwareInterface
 }
 namespace Symfony\Component\HttpKernel\Bundle
 {
+use Symfony\Component\DependencyInjection\ContainerBuilder;
 interface BundleInterface
 {
     function boot();
     function shutdown();
+    public function build(ContainerBuilder $container);
     function getParent();
     function getName();
     function getNamespace();
@@ -237,6 +239,7 @@ namespace Symfony\Component\HttpKernel\Bundle
 {
 use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\Console\Application;
 use Symfony\Component\Finder\Finder;
 abstract class Bundle extends ContainerAware implements BundleInterface
@@ -249,6 +252,18 @@ abstract class Bundle extends ContainerAware implements BundleInterface
     public function shutdown()
     {
     }
+    public function build(ContainerBuilder $container)
+    {
+        $class = $this->getNamespace().'\\DependencyInjection\\'.str_replace('Bundle', 'Extension', $this->getName());
+        if (class_exists($class)) {
+            $extension = new $class();
+            $alias = Container::underscore(str_replace('Bundle', '', $this->getName()));
+            if ($alias !== $extension->getAlias()) {
+                throw new \LogicException(sprintf('The extension alias for the default extension of a bundle must be the underscored version of the bundle name ("%s" vs "%s")', $alias, $extension->getAlias()));
+            }
+            $container->registerExtension($extension);
+        }
+    }
     public function getNamespace()
     {
         if (null === $this->reflected) {
@@ -276,19 +291,6 @@ abstract class Bundle extends ContainerAware implements BundleInterface
         $pos = strrpos($name, '\\');
         return $this->name = false === $pos ? $name :  substr($name, $pos + 1);
     }
-    public function registerExtensions(ContainerBuilder $container)
-    {
-        if (!$dir = realpath($this->getPath().'/DependencyInjection')) {
-            return;
-        }
-        $finder = new Finder();
-        $finder->files()->name('*Extension.php')->in($dir);
-        $prefix = $this->getNamespace().'\\DependencyInjection';
-        foreach ($finder as $file) {
-            $class = $prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php');
-            $container->registerExtension(new $class());
-        }
-    }
     public function registerCommands(Application $application)
     {
         if (!$dir = realpath($this->getPath().'/Command')) {
@@ -727,7 +729,7 @@ abstract class Kernel implements KernelInterface
         $parameterBag = new ParameterBag($this->getKernelParameters());
         $container = new ContainerBuilder($parameterBag);
         foreach ($this->bundles as $bundle) {
-            $bundle->registerExtensions($container);
+            $bundle->build($container);
             if ($this->debug) {
                 $container->addObjectResource($bundle);
             }

+ 1 - 1
src/Symfony/Component/HttpKernel/bootstrap_cache.php

@@ -289,7 +289,7 @@ abstract class Kernel implements KernelInterface
         $parameterBag = new ParameterBag($this->getKernelParameters());
         $container = new ContainerBuilder($parameterBag);
         foreach ($this->bundles as $bundle) {
-            $bundle->registerExtensions($container);
+            $bundle->build($container);
             if ($this->debug) {
                 $container->addObjectResource($bundle);
             }