diff --git a/UPGRADE-7.2.md b/UPGRADE-7.2.md
index 4ef726b8d8338..791711baf274c 100644
--- a/UPGRADE-7.2.md
+++ b/UPGRADE-7.2.md
@@ -13,6 +13,11 @@ Cache
* `igbinary_serialize()` is not used by default when the igbinary extension is installed
+DependencyInjection
+-------------------
+
+ * Deprecate `!tagged` tag, use `!tagged_iterator` instead
+
Form
----
diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
index 54095a8d37ae5..f7038a59b5653 100644
--- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md
+++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+7.2
+---
+
+ * Deprecate `!tagged` tag, use `!tagged_iterator` instead
+
7.1
---
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 9283598a571f4..661f57d21ee3f 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -586,6 +586,8 @@ private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file
$arguments[$key] = new ServiceLocatorArgument($arg);
break;
case 'tagged':
+ trigger_deprecation('symfony/dependency-injection', '7.2', 'Type "tagged" is deprecated for tag <%s>, use "tagged_iterator" instead in "%s".', $name, $file);
+ // no break
case 'tagged_iterator':
case 'tagged_locator':
$forLocator = 'tagged_locator' === $type;
diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
index afb0b162666ac..8a5d4135e3571 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -852,6 +852,10 @@ private function resolveServices(mixed $value, string $file, bool $isParameter =
return new ServiceLocatorArgument($argument);
}
if (\in_array($value->getTag(), ['tagged', 'tagged_iterator', 'tagged_locator'], true)) {
+ if ('tagged' === $value->getTag()) {
+ trigger_deprecation('symfony/dependency-injection', '7.2', 'Using "!tagged" is deprecated, use "!tagged_iterator" instead in "%s".', $file);
+ }
+
$forLocator = 'tagged_locator' === $value->getTag();
if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) {
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_deprecated_tagged.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_deprecated_tagged.xml
new file mode 100644
index 0000000000000..976450e18f46f
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_deprecated_tagged.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/tagged_deprecated.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/tagged_deprecated.yml
new file mode 100644
index 0000000000000..6c6b65226dd24
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/tagged_deprecated.yml
@@ -0,0 +1,4 @@
+services:
+ iterator_service:
+ class: FooClass
+ arguments: [!tagged {tag: test.tag}]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index 64df6cc7f79b5..0768f5528410e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Tests\Loader;
use PHPUnit\Framework\TestCase;
+use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Config\Exception\LoaderLoadException;
use Symfony\Component\Config\FileLocator;
@@ -48,6 +49,8 @@
class XmlFileLoaderTest extends TestCase
{
+ use ExpectDeprecationTrait;
+
protected static string $fixturesPath;
public static function setUpBeforeClass(): void
@@ -1276,4 +1279,17 @@ public function testStaticConstructorWithFactoryThrows()
$this->expectExceptionMessage('The "static_constructor" service cannot declare a factory as well as a constructor.');
$loader->load('static_constructor_and_factory.xml');
}
+
+ /**
+ * @group legacy
+ */
+ public function testDeprecatedTagged()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+
+ $this->expectDeprecation(sprintf('Since symfony/dependency-injection 7.2: Type "tagged" is deprecated for tag , use "tagged_iterator" instead in "%s".', self::$fixturesPath.'/xml/services_with_deprecated_tagged.xml'));
+
+ $loader->load('services_with_deprecated_tagged.xml');
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
index 6aa4376525893..d7f440f9305fd 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Tests\Loader;
use PHPUnit\Framework\TestCase;
+use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Config\Exception\LoaderLoadException;
use Symfony\Component\Config\FileLocator;
@@ -47,6 +48,8 @@
class YamlFileLoaderTest extends TestCase
{
+ use ExpectDeprecationTrait;
+
protected static string $fixturesPath;
public static function setUpBeforeClass(): void
@@ -1199,4 +1202,17 @@ public function testStaticConstructor()
$definition = $container->getDefinition('static_constructor');
$this->assertEquals((new Definition('stdClass'))->setFactory([null, 'create']), $definition);
}
+
+ /**
+ * @group legacy
+ */
+ public function testDeprecatedTagged()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+
+ $this->expectDeprecation(sprintf('Since symfony/dependency-injection 7.2: Using "!tagged" is deprecated, use "!tagged_iterator" instead in "%s".', self::$fixturesPath.'/yaml/tagged_deprecated.yml'));
+
+ $loader->load('tagged_deprecated.yml');
+ }
}