[HttpKernel] added BundleInterface::getContainerExtension() which is implicitly loaded

This commit is contained in:
Kris Wallsmith 2011-04-25 21:12:35 -07:00
parent 3ab5a51e17
commit 7a7b448680
5 changed files with 52 additions and 54 deletions

View File

@ -27,6 +27,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
{
protected $name;
protected $reflected;
protected $extension;
/**
* Boots the Bundle.
@ -47,13 +48,6 @@ abstract class Bundle extends ContainerAware implements BundleInterface
*
* 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 overridden to register compilation passes,
* other extensions, ...
*
@ -61,16 +55,21 @@ abstract class Bundle extends ContainerAware implements BundleInterface
*/
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);
/**
* Returns the bundle's container extension.
*
* @return ExtensionInterface|null The container extension
*/
public function getContainerExtension()
{
if (null === $this->extension) {
$class = $this->getNamespace().'\\DependencyInjection\\'.str_replace('Bundle', 'Extension', $this->getName());
$this->extension = class_exists($class) ? new $class() : false;
}
return $this->extension ?: null;
}
/**

View File

@ -39,6 +39,13 @@ interface BundleInterface
*/
function build(ContainerBuilder $container);
/**
* Returns the container extension that should be implicitly loaded.
*
* @return ExtensionInterface|null The default extension
*/
function getContainerExtension();
/**
* Returns the bundle parent name.
*

View File

@ -15,26 +15,24 @@ use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPa
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Handles automatically loading each bundle's default extension.
* Ensures certain extensions are always loaded.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass
{
private $extensions;
public function __construct(array $extensions)
{
$this->extensions = $extensions;
}
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());
}
foreach ($this->extensions as $extension) {
if (!count($container->getExtensionConfig($extension))) {
$container->loadFromExtension($extension, array());
}
}

View File

@ -529,19 +529,25 @@ abstract class Kernel implements KernelInterface
*/
protected function buildContainer()
{
$parameterBag = new ParameterBag($this->getKernelParameters());
$container = new ContainerBuilder($parameterBag);
$container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass());
$container = new ContainerBuilder(new ParameterBag($this->getKernelParameters()));
$extensions = array();
foreach ($this->bundles as $bundle) {
$bundle->build($container);
if ($extension = $bundle->getContainerExtension()) {
$container->registerExtension($extension);
$extensions[] = $extension->getAlias();
}
if ($this->debug) {
$container->addObjectResource($bundle);
}
}
$container->addObjectResource($this);
// ensure these extensions are implicitly loaded
$container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions));
if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) {
$container->merge($cont);
}

View File

@ -17,32 +17,20 @@ 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))
$container->expects($this->at(0))
->method('getExtensionConfig')
->will($this->returnCallback(function($name) {
switch ($name) {
case 'extension_present':
return array();
case 'extension_loaded':
return array(array());
}
}));
->with('loaded')
->will($this->returnValue(array(array())));
$container->expects($this->at(1))
->method('getExtensionConfig')
->with('notloaded')
->will($this->returnValue(array()));
$container->expects($this->once())
->method('loadFromExtension')
->with('extension_present', array());
->with('notloaded', array());
$container->expects($this->any())
->method('getParameterBag')
@ -60,7 +48,7 @@ class MergeExtensionConfigurationPassTest extends \PHPUnit_Framework_TestCase
->method('getExtensions')
->will($this->returnValue(array()));
$configPass = new MergeExtensionConfigurationPass();
$configPass = new MergeExtensionConfigurationPass(array('loaded', 'notloaded'));
$configPass->process($container);
}
}