Skip to content

Commit be65ed4

Browse files
committed
Merge branch '5.4' into 6.4
* 5.4: [DependencyInjection] Add tests for repeating `#[Autoconfigure]` attributes [DependencyInjection] Fix handling of repeated `#[Autoconfigure]` attributes [SecurityBundle] Make security schema deterministic [Translations][Core] Fix security Italian translation.
2 parents 6cf0115 + 1539a0a commit be65ed4

9 files changed

+203
-4
lines changed

Loader/XmlFileLoader.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,33 @@ private function parseFileToDOM(string $file): \DOMDocument
458458
try {
459459
$dom = XmlUtils::loadFile($file, $this->validateSchema(...));
460460
} catch (\InvalidArgumentException $e) {
461-
throw new InvalidArgumentException(sprintf('Unable to parse file "%s": ', $file).$e->getMessage(), $e->getCode(), $e);
461+
$invalidSecurityElements = [];
462+
$errors = explode("\n", $e->getMessage());
463+
foreach ($errors as $i => $error) {
464+
if (preg_match("#^\[ERROR 1871] Element '\{http://symfony\.com/schema/dic/security}([^']+)'#", $error, $matches)) {
465+
$invalidSecurityElements[$i] = $matches[1];
466+
}
467+
}
468+
if ($invalidSecurityElements) {
469+
$dom = XmlUtils::loadFile($file);
470+
471+
foreach ($invalidSecurityElements as $errorIndex => $tagName) {
472+
foreach ($dom->getElementsByTagNameNS('http://symfony.com/schema/dic/security', $tagName) as $element) {
473+
if (!$parent = $element->parentNode) {
474+
continue;
475+
}
476+
if ('http://symfony.com/schema/dic/security' !== $parent->namespaceURI) {
477+
continue;
478+
}
479+
if ('provider' === $parent->localName || 'firewall' === $parent->localName) {
480+
unset($errors[$errorIndex]);
481+
}
482+
}
483+
}
484+
}
485+
if ($errors) {
486+
throw new InvalidArgumentException(sprintf('Unable to parse file "%s": ', $file).implode("/n", $errors), $e->getCode(), $e);
487+
}
462488
}
463489

464490
$this->validateExtensions($dom, $file);
@@ -858,6 +884,6 @@ private function loadFromExtensions(\DOMDocument $xml): void
858884
*/
859885
public static function convertDomElementToArray(\DOMElement $element): mixed
860886
{
861-
return XmlUtils::convertDomElementToArray($element);
887+
return XmlUtils::convertDomElementToArray($element, false);
862888
}
863889
}

Loader/YamlFileLoader.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,9 @@ private function parseDefinition(string $id, array|string|null $service, string
450450
return $return ? $alias : $this->container->setAlias($id, $alias);
451451
}
452452

453+
$changes = [];
453454
if (null !== $definition) {
454-
// no-op
455+
$changes = $definition->getChanges();
455456
} elseif ($this->isLoadingInstanceof) {
456457
$definition = new ChildDefinition('');
457458
} elseif (isset($service['parent'])) {
@@ -474,7 +475,7 @@ private function parseDefinition(string $id, array|string|null $service, string
474475
$definition->setAutoconfigured($defaults['autoconfigure']);
475476
}
476477

477-
$definition->setChanges([]);
478+
$definition->setChanges($changes);
478479

479480
if (isset($service['class'])) {
480481
$definition->setClass($service['class']);

Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
use Symfony\Component\DependencyInjection\Reference;
2020
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureAttributed;
2121
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredInterface;
22+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeated;
23+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedBindings;
24+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedCalls;
25+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedOverwrite;
26+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedProperties;
27+
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedTag;
2228
use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists;
2329
use Symfony\Component\DependencyInjection\Tests\Fixtures\StaticConstructorAutoconfigure;
2430

@@ -76,6 +82,99 @@ public function testAutoconfiguredTag()
7682
$this->assertEquals([AutoconfiguredInterface::class => $expected], $container->getAutoconfiguredInstanceof());
7783
}
7884

85+
public function testAutoconfiguredRepeated()
86+
{
87+
$container = new ContainerBuilder();
88+
$container->register('foo', AutoconfigureRepeated::class)
89+
->setAutoconfigured(true);
90+
91+
(new RegisterAutoconfigureAttributesPass())->process($container);
92+
93+
$expected = (new ChildDefinition(''))
94+
->setLazy(true)
95+
->setPublic(true)
96+
->setShared(false);
97+
98+
$this->assertEquals([AutoconfigureRepeated::class => $expected], $container->getAutoconfiguredInstanceof());
99+
}
100+
101+
public function testAutoconfiguredRepeatedOverwrite()
102+
{
103+
$container = new ContainerBuilder();
104+
$container->register('foo', AutoconfigureRepeatedOverwrite::class)
105+
->setAutoconfigured(true);
106+
107+
(new RegisterAutoconfigureAttributesPass())->process($container);
108+
109+
$expected = (new ChildDefinition(''))
110+
->setLazy(true)
111+
->setPublic(false)
112+
->setShared(true);
113+
114+
$this->assertEquals([AutoconfigureRepeatedOverwrite::class => $expected], $container->getAutoconfiguredInstanceof());
115+
}
116+
117+
public function testAutoconfiguredRepeatedTag()
118+
{
119+
$container = new ContainerBuilder();
120+
$container->register('foo', AutoconfigureRepeatedTag::class)
121+
->setAutoconfigured(true);
122+
123+
(new RegisterAutoconfigureAttributesPass())->process($container);
124+
125+
$expected = (new ChildDefinition(''))
126+
->addTag('foo', ['priority' => 2])
127+
->addTag('bar');
128+
129+
$this->assertEquals([AutoconfigureRepeatedTag::class => $expected], $container->getAutoconfiguredInstanceof());
130+
}
131+
132+
public function testAutoconfiguredRepeatedCalls()
133+
{
134+
$container = new ContainerBuilder();
135+
$container->register('foo', AutoconfigureRepeatedCalls::class)
136+
->setAutoconfigured(true);
137+
138+
(new RegisterAutoconfigureAttributesPass())->process($container);
139+
140+
$expected = (new ChildDefinition(''))
141+
->addMethodCall('setBar', ['arg2'])
142+
->addMethodCall('setFoo', ['arg1']);
143+
144+
$this->assertEquals([AutoconfigureRepeatedCalls::class => $expected], $container->getAutoconfiguredInstanceof());
145+
}
146+
147+
public function testAutoconfiguredRepeatedBindingsOverwrite()
148+
{
149+
$container = new ContainerBuilder();
150+
$container->register('foo', AutoconfigureRepeatedBindings::class)
151+
->setAutoconfigured(true);
152+
153+
(new RegisterAutoconfigureAttributesPass())->process($container);
154+
155+
$expected = (new ChildDefinition(''))
156+
->setBindings(['$arg' => new BoundArgument('bar', false, BoundArgument::INSTANCEOF_BINDING, realpath(__DIR__.'/../Fixtures/AutoconfigureRepeatedBindings.php'))]);
157+
158+
$this->assertEquals([AutoconfigureRepeatedBindings::class => $expected], $container->getAutoconfiguredInstanceof());
159+
}
160+
161+
public function testAutoconfiguredRepeatedPropertiesOverwrite()
162+
{
163+
$container = new ContainerBuilder();
164+
$container->register('foo', AutoconfigureRepeatedProperties::class)
165+
->setAutoconfigured(true);
166+
167+
(new RegisterAutoconfigureAttributesPass())->process($container);
168+
169+
$expected = (new ChildDefinition(''))
170+
->setProperties([
171+
'$foo' => 'bar',
172+
'$bar' => 'baz',
173+
]);
174+
175+
$this->assertEquals([AutoconfigureRepeatedProperties::class => $expected], $container->getAutoconfiguredInstanceof());
176+
}
177+
79178
public function testMissingParent()
80179
{
81180
$container = new ContainerBuilder();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
6+
7+
#[Autoconfigure(public: true, shared: false)]
8+
#[Autoconfigure(lazy: true)]
9+
class AutoconfigureRepeated
10+
{
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
6+
7+
#[Autoconfigure(bind: ['$arg' => 'foo'])]
8+
#[Autoconfigure(bind: ['$arg' => 'bar'])]
9+
class AutoconfigureRepeatedBindings
10+
{
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
6+
7+
#[Autoconfigure(calls: [['setBar', ['arg2']]])]
8+
#[Autoconfigure(calls: [['setFoo', ['arg1']]])]
9+
class AutoconfigureRepeatedCalls
10+
{
11+
public function setFoo(string $arg)
12+
{
13+
}
14+
15+
public function setBar(string $arg)
16+
{
17+
}
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
6+
7+
#[Autoconfigure(public: true, shared: false)]
8+
#[Autoconfigure(lazy: true, shared: true, public: false)]
9+
class AutoconfigureRepeatedOverwrite
10+
{
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
6+
7+
#[Autoconfigure(properties: ['$replaced' => 'to be replaced', '$bar' => 'existing to be replaced'])]
8+
#[Autoconfigure(properties: ['$foo' => 'bar', '$bar' => 'baz'])]
9+
class AutoconfigureRepeatedProperties
10+
{
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
6+
7+
#[AutoconfigureTag('foo', ['priority' => 2])]
8+
#[AutoconfigureTag('bar')]
9+
class AutoconfigureRepeatedTag
10+
{
11+
}

0 commit comments

Comments
 (0)