Skip to content

[DI][DX] Throw exception on some ContainerBuilder methods used from extensions #24295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

/**
* Merges extension configs into the container builder.
Expand Down Expand Up @@ -52,7 +55,7 @@ public function process(ContainerBuilder $container)
}
$config = $resolvingBag->resolveValue($config);

$tmpContainer = new ContainerBuilder($resolvingBag);
$tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
$tmpContainer->setResourceTracking($container->isTrackingResources());
$tmpContainer->addObjectResource($extension);
if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
Expand Down Expand Up @@ -121,3 +124,44 @@ public function getEnvPlaceholders()
return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders();
}
}

/**
* A container builder preventing using methods that wouldn't have any effect from extensions.
*
* @internal
*/
class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder
{
private $extensionClass;

public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null)
{
parent::__construct($parameterBag);

$this->extensionClass = get_class($extension);
}

/**
* {@inheritdoc}
*/
public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
{
throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', get_class($pass), $this->extensionClass));
}

/**
* {@inheritdoc}
*/
public function registerExtension(ExtensionInterface $extension)
{
throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', get_class($extension), $this->extensionClass));
}

/**
* {@inheritdoc}
*/
public function compile($resolveEnvPlaceholders = false)
{
throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
Expand Down Expand Up @@ -54,6 +55,22 @@ public function testExpressionLanguageProviderForwarding()
$this->assertEquals(array($provider), $tmpProviders);
}

public function testExtensionLoadGetAMergeExtensionConfigurationContainerBuilderInstance()
{
$extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('load'))->getMock();
$extension->expects($this->once())
->method('load')
->with($this->isType('array'), $this->isInstanceOf(MergeExtensionConfigurationContainerBuilder::class))
;

$container = new ContainerBuilder(new ParameterBag());
$container->registerExtension($extension);
$container->prependExtensionConfig('foo', array());

$pass = new MergeExtensionConfigurationPass();
$pass->process($container);
}

public function testExtensionConfigurationIsTrackedByDefault()
{
$extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('getConfiguration'))->getMock();
Expand Down