Skip to content

Commit

Permalink
Merge branch '5.4' into 6.4
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
xabbuh committed Aug 20, 2024
2 parents 6cf0115 + 1539a0a commit be65ed4
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 4 deletions.
30 changes: 28 additions & 2 deletions Loader/XmlFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,33 @@ private function parseFileToDOM(string $file): \DOMDocument
try {
$dom = XmlUtils::loadFile($file, $this->validateSchema(...));
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Unable to parse file "%s": ', $file).$e->getMessage(), $e->getCode(), $e);
$invalidSecurityElements = [];
$errors = explode("\n", $e->getMessage());
foreach ($errors as $i => $error) {
if (preg_match("#^\[ERROR 1871] Element '\{http://symfony\.com/schema/dic/security}([^']+)'#", $error, $matches)) {
$invalidSecurityElements[$i] = $matches[1];
}
}
if ($invalidSecurityElements) {
$dom = XmlUtils::loadFile($file);

foreach ($invalidSecurityElements as $errorIndex => $tagName) {
foreach ($dom->getElementsByTagNameNS('http://symfony.com/schema/dic/security', $tagName) as $element) {
if (!$parent = $element->parentNode) {
continue;
}
if ('http://symfony.com/schema/dic/security' !== $parent->namespaceURI) {
continue;
}
if ('provider' === $parent->localName || 'firewall' === $parent->localName) {
unset($errors[$errorIndex]);
}
}
}
}
if ($errors) {
throw new InvalidArgumentException(sprintf('Unable to parse file "%s": ', $file).implode("/n", $errors), $e->getCode(), $e);
}
}

$this->validateExtensions($dom, $file);
Expand Down Expand Up @@ -858,6 +884,6 @@ private function loadFromExtensions(\DOMDocument $xml): void
*/
public static function convertDomElementToArray(\DOMElement $element): mixed
{
return XmlUtils::convertDomElementToArray($element);
return XmlUtils::convertDomElementToArray($element, false);
}
}
5 changes: 3 additions & 2 deletions Loader/YamlFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,9 @@ private function parseDefinition(string $id, array|string|null $service, string
return $return ? $alias : $this->container->setAlias($id, $alias);
}

$changes = [];
if (null !== $definition) {
// no-op
$changes = $definition->getChanges();
} elseif ($this->isLoadingInstanceof) {
$definition = new ChildDefinition('');
} elseif (isset($service['parent'])) {
Expand All @@ -474,7 +475,7 @@ private function parseDefinition(string $id, array|string|null $service, string
$definition->setAutoconfigured($defaults['autoconfigure']);
}

$definition->setChanges([]);
$definition->setChanges($changes);

if (isset($service['class'])) {
$definition->setClass($service['class']);
Expand Down
99 changes: 99 additions & 0 deletions Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureAttributed;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredInterface;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeated;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedBindings;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedCalls;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedOverwrite;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedProperties;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedTag;
use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists;
use Symfony\Component\DependencyInjection\Tests\Fixtures\StaticConstructorAutoconfigure;

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

public function testAutoconfiguredRepeated()
{
$container = new ContainerBuilder();
$container->register('foo', AutoconfigureRepeated::class)
->setAutoconfigured(true);

(new RegisterAutoconfigureAttributesPass())->process($container);

$expected = (new ChildDefinition(''))
->setLazy(true)
->setPublic(true)
->setShared(false);

$this->assertEquals([AutoconfigureRepeated::class => $expected], $container->getAutoconfiguredInstanceof());
}

public function testAutoconfiguredRepeatedOverwrite()
{
$container = new ContainerBuilder();
$container->register('foo', AutoconfigureRepeatedOverwrite::class)
->setAutoconfigured(true);

(new RegisterAutoconfigureAttributesPass())->process($container);

$expected = (new ChildDefinition(''))
->setLazy(true)
->setPublic(false)
->setShared(true);

$this->assertEquals([AutoconfigureRepeatedOverwrite::class => $expected], $container->getAutoconfiguredInstanceof());
}

public function testAutoconfiguredRepeatedTag()
{
$container = new ContainerBuilder();
$container->register('foo', AutoconfigureRepeatedTag::class)
->setAutoconfigured(true);

(new RegisterAutoconfigureAttributesPass())->process($container);

$expected = (new ChildDefinition(''))
->addTag('foo', ['priority' => 2])
->addTag('bar');

$this->assertEquals([AutoconfigureRepeatedTag::class => $expected], $container->getAutoconfiguredInstanceof());
}

public function testAutoconfiguredRepeatedCalls()
{
$container = new ContainerBuilder();
$container->register('foo', AutoconfigureRepeatedCalls::class)
->setAutoconfigured(true);

(new RegisterAutoconfigureAttributesPass())->process($container);

$expected = (new ChildDefinition(''))
->addMethodCall('setBar', ['arg2'])
->addMethodCall('setFoo', ['arg1']);

$this->assertEquals([AutoconfigureRepeatedCalls::class => $expected], $container->getAutoconfiguredInstanceof());
}

public function testAutoconfiguredRepeatedBindingsOverwrite()
{
$container = new ContainerBuilder();
$container->register('foo', AutoconfigureRepeatedBindings::class)
->setAutoconfigured(true);

(new RegisterAutoconfigureAttributesPass())->process($container);

$expected = (new ChildDefinition(''))
->setBindings(['$arg' => new BoundArgument('bar', false, BoundArgument::INSTANCEOF_BINDING, realpath(__DIR__.'/../Fixtures/AutoconfigureRepeatedBindings.php'))]);

$this->assertEquals([AutoconfigureRepeatedBindings::class => $expected], $container->getAutoconfiguredInstanceof());
}

public function testAutoconfiguredRepeatedPropertiesOverwrite()
{
$container = new ContainerBuilder();
$container->register('foo', AutoconfigureRepeatedProperties::class)
->setAutoconfigured(true);

(new RegisterAutoconfigureAttributesPass())->process($container);

$expected = (new ChildDefinition(''))
->setProperties([
'$foo' => 'bar',
'$bar' => 'baz',
]);

$this->assertEquals([AutoconfigureRepeatedProperties::class => $expected], $container->getAutoconfiguredInstanceof());
}

public function testMissingParent()
{
$container = new ContainerBuilder();
Expand Down
11 changes: 11 additions & 0 deletions Tests/Fixtures/AutoconfigureRepeated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(public: true, shared: false)]
#[Autoconfigure(lazy: true)]
class AutoconfigureRepeated
{
}
11 changes: 11 additions & 0 deletions Tests/Fixtures/AutoconfigureRepeatedBindings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(bind: ['$arg' => 'foo'])]
#[Autoconfigure(bind: ['$arg' => 'bar'])]
class AutoconfigureRepeatedBindings
{
}
18 changes: 18 additions & 0 deletions Tests/Fixtures/AutoconfigureRepeatedCalls.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(calls: [['setBar', ['arg2']]])]
#[Autoconfigure(calls: [['setFoo', ['arg1']]])]
class AutoconfigureRepeatedCalls
{
public function setFoo(string $arg)
{
}

public function setBar(string $arg)
{
}
}
11 changes: 11 additions & 0 deletions Tests/Fixtures/AutoconfigureRepeatedOverwrite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(public: true, shared: false)]
#[Autoconfigure(lazy: true, shared: true, public: false)]
class AutoconfigureRepeatedOverwrite
{
}
11 changes: 11 additions & 0 deletions Tests/Fixtures/AutoconfigureRepeatedProperties.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(properties: ['$replaced' => 'to be replaced', '$bar' => 'existing to be replaced'])]
#[Autoconfigure(properties: ['$foo' => 'bar', '$bar' => 'baz'])]
class AutoconfigureRepeatedProperties
{
}
11 changes: 11 additions & 0 deletions Tests/Fixtures/AutoconfigureRepeatedTag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;

#[AutoconfigureTag('foo', ['priority' => 2])]
#[AutoconfigureTag('bar')]
class AutoconfigureRepeatedTag
{
}

0 comments on commit be65ed4

Please sign in to comment.