Skip to content

Commit 219414c

Browse files
committed
feature #36586 [DI] allow loading and dumping tags with an attribute named "name" (nicolas-grekas)
This PR was merged into the 5.1-dev branch. Discussion ---------- [DI] allow loading and dumping tags with an attribute named "name" | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - This is a minor feature added for consistency: using PHP, we can already define tags with an attribute named `"name"`. But then, we cannot dump such definitions in YAML nor XML since we don't have a syntax to declare such tags in these formats. I spotted this while looking at a dumped container: we already use an attribute named `"name"` on two tags: `cache.pool` and `workflow.definition`. Currently, the dumped XML is wrong because of this. This PR enables the following new syntaxes (the current style still works as usual): - in YAML, consistently with the new syntax for method calls: ```yaml tags: - cache.pool: { name: my_cache_pool } ``` - in XML: ```xml <tag name="my_cache_pool">cache.pool</tag> ``` Commits ------- b023e4cac3 [DI] allow loading and dumping tags with an attribute named "name"
2 parents 684c44a + a565ede commit 219414c

18 files changed

+62
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CHANGELOG
1616
configure them explicitly instead
1717
* added class `Symfony\Component\DependencyInjection\Dumper\Preloader` to help with preloading on PHP 7.4+
1818
* added tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload
19+
* allowed loading and dumping tags with an attribute named "name"
1920
* deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead
2021
* deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead
2122
* deprecated PHP-DSL's `inline()` function, use `service()` instead

Dumper/XmlDumper.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ private function addService(Definition $definition, ?string $id, \DOMElement $pa
137137
foreach ($definition->getTags() as $name => $tags) {
138138
foreach ($tags as $attributes) {
139139
$tag = $this->document->createElement('tag');
140-
$tag->setAttribute('name', $name);
140+
if (!\array_key_exists('name', $attributes)) {
141+
$tag->setAttribute('name', $name);
142+
} else {
143+
$tag->appendChild($this->document->createTextNode($name));
144+
}
141145
foreach ($attributes as $key => $value) {
142146
$tag->setAttribute($key, $value);
143147
}

Dumper/YamlDumper.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ private function addService(string $id, Definition $definition): string
7979
foreach ($attributes as $key => $value) {
8080
$att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value));
8181
}
82-
$att = $att ? ', '.implode(', ', $att) : '';
82+
$att = $att ? ': { '.implode(', ', $att).' }' : '';
8383

84-
$tagsCode .= sprintf(" - { name: %s%s }\n", $this->dumper->dump($name), $att);
84+
$tagsCode .= sprintf(" - %s%s\n", $this->dumper->dump($name), $att);
8585
}
8686
}
8787
if ($tagsCode) {

Loader/XmlFileLoader.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,9 @@ private function parseDefinition(\DOMElement $service, string $file, Definition
316316

317317
foreach ($tags as $tag) {
318318
$parameters = [];
319+
$tagName = $tag->nodeValue;
319320
foreach ($tag->attributes as $name => $node) {
320-
if ('name' === $name) {
321+
if ('name' === $name && '' === $tagName) {
321322
continue;
322323
}
323324

@@ -328,11 +329,11 @@ private function parseDefinition(\DOMElement $service, string $file, Definition
328329
$parameters[$name] = XmlUtils::phpize($node->nodeValue);
329330
}
330331

331-
if ('' === $tag->getAttribute('name')) {
332+
if ('' === $tagName && '' === $tagName = $tag->getAttribute('name')) {
332333
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', (string) $service->getAttribute('id'), $file));
333334
}
334335

335-
$definition->addTag($tag->getAttribute('name'), $parameters);
336+
$definition->addTag($tagName, $parameters);
336337
}
337338

338339
$definition->setTags(array_merge_recursive($definition->getTags(), $defaults->getTags()));

Loader/YamlFileLoader.php

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,16 @@ private function parseDefaults(array &$content, string $file): array
266266
$tag = ['name' => $tag];
267267
}
268268

269-
if (!isset($tag['name'])) {
270-
throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in "%s".', $file));
269+
if (1 === \count($tag) && \is_array(current($tag))) {
270+
$name = key($tag);
271+
$tag = current($tag);
272+
} else {
273+
if (!isset($tag['name'])) {
274+
throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in "%s".', $file));
275+
}
276+
$name = $tag['name'];
277+
unset($tag['name']);
271278
}
272-
$name = $tag['name'];
273-
unset($tag['name']);
274279

275280
if (!\is_string($name) || '' === $name) {
276281
throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in "%s".', $file));
@@ -568,11 +573,16 @@ private function parseDefinition(string $id, $service, string $file, array $defa
568573
$tag = ['name' => $tag];
569574
}
570575

571-
if (!isset($tag['name'])) {
572-
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in "%s".', $id, $file));
576+
if (1 === \count($tag) && \is_array(current($tag))) {
577+
$name = key($tag);
578+
$tag = current($tag);
579+
} else {
580+
if (!isset($tag['name'])) {
581+
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in "%s".', $id, $file));
582+
}
583+
$name = $tag['name'];
584+
unset($tag['name']);
573585
}
574-
$name = $tag['name'];
575-
unset($tag['name']);
576586

577587
if (!\is_string($name) || '' === $name) {
578588
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', $id, $file));

Loader/schema/dic/services/services-1.0.xsd

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,11 @@
187187
</xsd:complexType>
188188

189189
<xsd:complexType name="tag">
190-
<xsd:attribute name="name" type="xsd:string" use="required" />
191-
<xsd:anyAttribute namespace="##any" processContents="lax" />
190+
<xsd:simpleContent>
191+
<xsd:extension base="xsd:string">
192+
<xsd:anyAttribute namespace="##any" processContents="lax" />
193+
</xsd:extension>
194+
</xsd:simpleContent>
192195
</xsd:complexType>
193196

194197
<xsd:complexType name="deprecated">

Tests/Fixtures/config/anonymous.expected.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ services:
1212
class: stdClass
1313
public: false
1414
tags:
15-
- { name: listener }
15+
- listener
1616
decorated:
1717
class: Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator
1818
public: true

Tests/Fixtures/config/defaults.expected.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ services:
1212
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
1313
public: true
1414
tags:
15-
- { name: t, a: b }
15+
- t: { a: b }
1616
autowire: true
1717
autoconfigure: true
1818
arguments: ['@bar']
1919
bar:
2020
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
2121
public: true
2222
tags:
23-
- { name: t, a: b }
23+
- t: { a: b }
2424
autowire: true
2525
calls:
2626
- [setFoo, ['@bar']]

Tests/Fixtures/config/instanceof.expected.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ services:
88
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
99
public: true
1010
tags:
11-
- { name: tag, k: v }
11+
- tag: { k: v }
1212
lazy: true
1313
properties: { p: 1 }
1414
calls:

Tests/Fixtures/config/lazy_fqcn.expected.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ services:
88
class: stdClass
99
public: true
1010
tags:
11-
- { name: proxy, interface: SomeInterface }
11+
- proxy: { interface: SomeInterface }
1212
lazy: true

0 commit comments

Comments
 (0)