More accurate message on invalid config builder

Throw exception when try to autowire nested bundle config instead of ConfigBuilder.
Also renamed test class AcmeConfigBuilder to AcmeConfig according config builders auto naming.
This commit is contained in:
Alexander Menshchikov 2021-04-29 23:06:38 +03:00
parent 694c052e3c
commit 0501ecc2d8
No known key found for this signature in database
GPG Key ID: 09E9B66531C5035A
7 changed files with 78 additions and 30 deletions

View File

@ -159,12 +159,16 @@ class PhpFileLoader extends FileLoader
// If it does not start with Symfony\Config\ we dont know how to handle this
if ('Symfony\\Config\\' !== substr($namespace, 0, 15)) {
throw new InvalidargumentException(sprintf('Could not find or generate class "%s".', $namespace));
throw new InvalidArgumentException(sprintf('Could not find or generate class "%s".', $namespace));
}
// Try to get the extension alias
$alias = Container::underscore(substr($namespace, 15, -6));
if (false !== strpos($alias, '\\')) {
throw new InvalidArgumentException('You can only use "root" ConfigBuilders from "Symfony\\Config\\" namespace. Nested classes like "Symfony\\Config\\Framework\\CacheConfig" cannot be used.');
}
if (!$this->container->hasExtension($alias)) {
$extensions = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s". Looked for namespace "%s", found "%s".', $namespace, $alias, $extensions ? implode('", "', $extensions) : 'none'));

View File

@ -0,0 +1,42 @@
<?php
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
use Symfony\Component\Config\Builder\ConfigBuilderInterface;
class AcmeConfig implements ConfigBuilderInterface
{
private $color;
private $nested;
public function color($value)
{
$this->color = $value;
}
public function nested(array $value)
{
if (null === $this->nested) {
$this->nested = new \Symfony\Config\AcmeConfig\NestedConfig();
} elseif ([] !== $value) {
throw new \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException(sprintf('The node created by "nested()" has already been initialized. You cannot pass values the second time you call nested().'));
}
return $this->nested;
}
public function toArray(): array
{
return [
'color' => $this->color
];
}
public function getExtensionAlias(): string
{
return 'acme';
}
}
class_alias(AcmeConfig::class, '\\Symfony\\Config\\AcmeConfig');

View File

@ -0,0 +1,10 @@
<?php
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig;
class NestedConfig
{
}
class_alias(NestedConfig::class, '\\Symfony\\Config\\AcmeConfig\\NestedConfig');

View File

@ -1,27 +0,0 @@
<?php
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
use Symfony\Component\Config\Builder\ConfigBuilderInterface;
class AcmeConfigBuilder implements ConfigBuilderInterface
{
private $color;
public function color($value)
{
$this->color = $value;
}
public function toArray(): array
{
return [
'color' => $this->color
];
}
public function getExtensionAlias(): string
{
return 'acme';
}
}

View File

@ -1,7 +1,7 @@
<?php
use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfigBuilder;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig;
return static function (AcmeConfigBuilder $config) {
return static function (AcmeConfig $config) {
$config->color('blue');
};

View File

@ -0,0 +1,7 @@
<?php
use Symfony\Config\AcmeConfig\NestedConfig;
return static function (NestedConfig $config) {
throw new RuntimeException('This code should not be run.');
};

View File

@ -164,4 +164,16 @@ class PhpFileLoaderTest extends TestCase
$loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator());
$loader->load($fixtures.'/config/deprecated_without_package_version.php');
}
public function testNestedBundleConfigNotAllowed()
{
$fixtures = realpath(__DIR__.'/../Fixtures');
$container = new ContainerBuilder();
$loader = new PhpFileLoader($container, new FileLocator(), 'prod', new ConfigBuilderGenerator(sys_get_temp_dir()));
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches('/^'.preg_quote('Could not resolve argument "Symfony\\Config\\AcmeConfig\\NestedConfig $config"', '/').'/');
$loader->load($fixtures.'/config/nested_bundle_config.php');
}
}