8000 bug #40994 [Config] More accurate message on invalid config builder (… · symfony/symfony@9857fae · GitHub
[go: up one dir, main page]

Skip to content

Commit 9857fae

Browse files
committed
bug #40994 [Config] More accurate message on invalid config builder (a-menshchikov)
This PR was merged into the 5.3-dev branch. Discussion ---------- [Config] More accurate message on invalid config builder | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | | License | MIT | Doc PR | Throw exception when trying to autowire nested bundle config instead of ConfigBuilder (related Doc PR symfony/symfony-docs#15300). Also renamed test class AcmeConfigBuilder to AcmeConfig according config builders auto naming. Inspired by a chat with `@Nyholm` Commits ------- 0501ecc More accurate message on invalid config builder
2 parents 21e3738 + 0501ecc commit 9857fae

File tree

7 files changed

+78
-30
lines changed

7 files changed

+78
-30
lines changed

src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,16 @@ private function configBuilder(string $namespace): ConfigBuilderInterface
159159

160160
// If it does not start with Symfony\Config\ we dont know how to handle this
161161
if ('Symfony\\Config\\' !== substr($namespace, 0, 15)) {
162-
throw new InvalidargumentException(sprintf('Could not find or generate class "%s".', $namespace));
162+
throw new InvalidArgumentException(sprintf('Could not find or generate class "%s".', $namespace));
163163
}
164164

165165
// Try to get the extension alias
166166
$alias = Container::underscore(substr($namespace, 15, -6));
167167

168+
if (false !== strpos($alias, '\\')) {
169+
throw new InvalidArgumentException('You can only use "root" ConfigBuilders from "Symfony\\Config\\" namespace. Nested classes like "Symfony\\Config\\Framework\\CacheConfig" cannot be used.');
170+
}
171+
168172
if (!$this->container->hasExtension($alias)) {
169173
$extensions = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
170174
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'));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\Config\Builder\ConfigBuilderInterface;
6+
7+
class AcmeConfig implements ConfigBuilderInterface
8+
{
9+
private $color;
10+
11+
private $nested;
12+
13+
public function color($value)
14+
{
15+
$this->color = $value;
16+
}
17+
18+
public function nested(array $value)
19+
{
20+
if (null === $this->nested) {
21+
$this->nested = new \Symfony\Config\AcmeConfig\NestedConfig();
22+
} elseif ([] !== $value) {
23+
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().'));
24+
}
25+
26+
return $this->nested;
27+
}
28+
29+
public function toArray(): array
30+
{
31+
return [
32+
'color' => $this->color
33+
];
34+
}
35+
36+
public function getExtensionAlias(): string
37+
{
38+
return 'acme';
39+
}
40+
}
41+
42+
class_alias(AcmeConfig::class, '\\Symfony\\Config\\AcmeConfig');
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig;
4+
5+
class NestedConfig
6+
{
7+
}
8+
9+
class_alias(NestedConfig::class, '\\Symfony\\Config\\AcmeConfig\\NestedConfig');
10+

src/Symfony/Component/DependencyInjection/Tests/Fixtures/AcmeConfigBuilder.php

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

3-
use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfigBuilder;
3+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig;
44

5-
return static function (AcmeConfigBuilder $config) {
5+
return static function (AcmeConfig $config) {
66
$config->color('blue');
77
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
use Symfony\Config\AcmeConfig\NestedConfig;
4+
5+
return static function (NestedConfig $config) {
6+
throw new RuntimeException('This code should not be run.');
7+
};

src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,16 @@ public function testDeprecatedWithoutPackageAndVersion()
164164
$loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator());
165165
$loader->load($fixtures.'/config/deprecated_without_package_version.php');
166166
}
167+
168+
public function testNestedBundleConfigNotAllowed()
169+
{
170+
$fixtures = realpath(__DIR__.'/../Fixtures');
171+
$container = new ContainerBuilder();
172+
$loader = new PhpFileLoader($container, new FileLocator(), 'prod', new ConfigBuilderGenerator(sys_get_temp_dir()));
173+
174+
$this->expectException(\InvalidArgumentException::class);
175+
$this->expectExceptionMessageMatches('/^'.preg_quote('Could not resolve argument "Symfony\\Config\\AcmeConfig\\NestedConfig $config"', '/').'/');
176+
177+
$loader->load($fixtures.'/config/nested_bundle_config.php');
178+
}
167179
}

0 commit comments

Comments
 (0)
0