Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[HttpKernel] added BundleInterface::getContainerExtension() which is …
…implicitly loaded
  • Loading branch information
kriswallsmith committed Apr 26, 2011
1 parent 3ab5a51 commit 7a7b448
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 54 deletions.
29 changes: 14 additions & 15 deletions src/Symfony/Component/HttpKernel/Bundle/Bundle.php
Expand Up @@ -27,6 +27,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
{
protected $name;
protected $reflected;
protected $extension;

/**
* Boots the Bundle.
Expand All @@ -47,30 +48,28 @@ public function shutdown()
*
* 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, ...
*
* @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);
/**
* 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;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/Symfony/Component/HttpKernel/Bundle/BundleInterface.php
Expand Up @@ -39,6 +39,13 @@ function shutdown();
*/
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.
*
Expand Down
Expand Up @@ -15,26 +15,24 @@
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
{
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';
private $extensions;

if (class_exists($extClass)) {
$ext = new $extClass();
$alias = $ext->getAlias();
public function __construct(array $extensions)
{
$this->extensions = $extensions;
}

// ensure all "main" extensions are loaded
if (!count($container->getExtensionConfig($alias))) {
$container->loadFromExtension($alias, array());
}
public function process(ContainerBuilder $container)
{
foreach ($this->extensions as $extension) {
if (!count($container->getExtensionConfig($extension))) {
$container->loadFromExtension($extension, array());
}
}

Expand Down
14 changes: 10 additions & 4 deletions src/Symfony/Component/HttpKernel/Kernel.php
Expand Up @@ -529,19 +529,25 @@ protected function getEnvParameters()
*/
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);
}
Expand Down
Expand Up @@ -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')
Expand All @@ -60,7 +48,7 @@ public function testAutoloadMainExtension()
->method('getExtensions')
->will($this->returnValue(array()));

$configPass = new MergeExtensionConfigurationPass();
$configPass = new MergeExtensionConfigurationPass(array('loaded', 'notloaded'));
$configPass->process($container);
}
}

0 comments on commit 7a7b448

Please sign in to comment.