diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index 711b631d54590..3ea0b1b93f731 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -1812,6 +1812,8 @@ private function dumpValue($value, bool $interpolate = true): string
return $code;
}
+ } elseif ($value instanceof \UnitEnum) {
+ return sprintf('\%s::%s', \get_class($value), $value->name);
} elseif (\is_object($value) || \is_resource($value)) {
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
}
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
index 02a501bd2c34c..8017fc579aaa2 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
@@ -313,6 +313,9 @@ private function convertParameters(array $parameters, string $type, \DOMElement
$element->setAttribute('type', 'binary');
$text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
$element->appendChild($text);
+ } elseif ($value instanceof \UnitEnum) {
+ $element->setAttribute('type', 'constant');
+ $element->appendChild($this->document->createTextNode(self::phpToXml($value)));
} else {
if (\in_array($value, ['null', 'true', 'false'], true)) {
$element->setAttribute('type', 'string');
@@ -366,6 +369,8 @@ public static function phpToXml($value): string
return 'false';
case $value instanceof Parameter:
return '%'.$value.'%';
+ case $value instanceof \UnitEnum:
+ return sprintf('%s::%s', \get_class($value), $value->name);
case \is_object($value) || \is_resource($value):
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
default:
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
index c055a686128c2..5dce997d9df9d 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
@@ -286,6 +286,8 @@ private function dumpValue($value)
return $this->getExpressionCall((string) $value);
} elseif ($value instanceof Definition) {
return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
+ } elseif ($value instanceof \UnitEnum) {
+ return new TaggedValue('php/const', sprintf('%s::%s', \get_class($value), $value->name));
} elseif (\is_object($value) || \is_resource($value)) {
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
index b46fbf937b910..3468e35a944c1 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
@@ -40,6 +40,8 @@
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
@@ -1208,6 +1210,29 @@ public function testDumpHandlesObjectClassNames()
$this->assertInstanceOf(\stdClass::class, $container->get('bar'));
}
+ /**
+ * @requires PHP 8.1
+ */
+ public function testDumpHandlesEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $container
+ ->register('foo', FooClassWithEnumAttribute::class)
+ ->setPublic(true)
+ ->addArgument(FooUnitEnum::BAR);
+
+ $container->compile();
+
+ $dumper = new PhpDumper($container);
+ eval('?>'.$dumper->dump([
+ 'class' => 'Symfony_DI_PhpDumper_Test_Enumeration',
+ ]));
+
+ $container = new \Symfony_DI_PhpDumper_Test_Enumeration();
+
+ $this->assertSame(FooUnitEnum::BAR, $container->get('foo')->getBar());
+ }
+
public function testUninitializedSyntheticReference()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php
index dda18a306207e..18caa150f278e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php
@@ -21,6 +21,8 @@
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
class XmlDumperTest extends TestCase
{
@@ -249,4 +251,21 @@ public function testDumpAbstractServices()
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump());
}
+
+ /**
+ * @requires PHP 8.1
+ */
+ public function testDumpHandlesEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $container
+ ->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class)
+ ->setPublic(true)
+ ->addArgument(FooUnitEnum::BAR);
+
+ $container->compile();
+ $dumper = new XmlDumper($container);
+
+ $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_with_enumeration.xml'), $dumper->dump());
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php
index b359f668d7758..9a973afe69df7 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php
@@ -22,6 +22,8 @@
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Yaml;
@@ -129,6 +131,23 @@ public function testServiceClosure()
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_service_closure.yml', $dumper->dump());
}
+ /**
+ * @requires PHP 8.1
+ */
+ public function testDumpHandlesEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $container
+ ->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class)
+ ->setPublic(true)
+ ->addArgument(FooUnitEnum::BAR);
+
+ $container->compile();
+ $dumper = new YamlDumper($container);
+
+ $this->assertEquals(file_get_contents(self::$fixturesPath.'/yaml/services_with_enumeration.yml'), $dumper->dump());
+ }
+
private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '')
{
$parser = new Parser();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php
new file mode 100644
index 0000000000000..3b2235efdd76b
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php
@@ -0,0 +1,18 @@
+bar = $bar;
+ }
+
+ public function getBar(): FooUnitEnum
+ {
+ return $this->bar;
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php
new file mode 100644
index 0000000000000..d51cf9c995e26
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php
@@ -0,0 +1,8 @@
+
+
+
+
+
+ Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml
new file mode 100644
index 0000000000000..8864e6d892857
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml
new file mode 100644
index 0000000000000..46bf505d44b80
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml
@@ -0,0 +1,10 @@
+
+services:
+ service_container:
+ class: Symfony\Component\DependencyInjection\ContainerInterface
+ public: true
+ synthetic: true
+ Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute:
+ class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute
+ public: true
+ arguments: [!php/const 'Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR']
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml
new file mode 100644
index 0000000000000..b9f74e0f468ab
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml
@@ -0,0 +1,10 @@
+
+services:
+ service_container:
+ class: Symfony\Component\DependencyInjection\ContainerInterface
+ public: true
+ synthetic: true
+ Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute:
+ class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute
+ public: true
+ arguments: [!php/const 'Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ']
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index 80d3393010602..ef00b2f721608 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -37,6 +37,8 @@
use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar;
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
use Symfony\Component\ExpressionLanguage\Expression;
@@ -827,6 +829,32 @@ public function testInstanceof()
$this->assertSame(['foo' => [[]], 'bar' => [[]]], $definition->getTags());
}
+ /**
+ * @requires PHP 8.1
+ */
+ public function testEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('services_with_enumeration.xml');
+ $container->compile();
+
+ $definition = $container->getDefinition(FooClassWithEnumAttribute::class);
+ $this->assertSame([FooUnitEnum::BAR], $definition->getArguments());
+ }
+
+ /**
+ * @requires PHP 8.1
+ */
+ public function testInvalidEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+
+ $this->expectException(\Error::class);
+ $loader->load('services_with_invalid_enumeration.xml');
+ }
+
public function testInstanceOfAndChildDefinitionNotAllowed()
{
$this->expectException(InvalidArgumentException::class);
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
index f367bf3452384..910e7b2a243e5 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
@@ -37,6 +37,8 @@
use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar;
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
use Symfony\Component\ExpressionLanguage\Expression;
@@ -909,6 +911,33 @@ public function testDefaultValueOfTagged()
$this->assertNull($iteratorArgument->getIndexAttribute());
}
+ /**
+ * @requires PHP 8.1
+ */
+ public function testEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+ $loader->load('services_with_enumeration.yml');
+ $container->compile();
+
+ $definition = $container->getDefinition(FooClassWithEnumAttribute::class);
+ $this->assertSame([FooUnitEnum::BAR], $definition->getArguments());
+ }
+
+ /**
+ * @requires PHP 8.1
+ */
+ public function testInvalidEnumeration()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('The constant "Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ" is not defined');
+ $loader->load('services_with_invalid_enumeration.yml');
+ }
+
public function testReturnsClone()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php
index a317bb0438e5f..10ed14fe5116b 100644
--- a/src/Symfony/Component/Yaml/Inline.php
+++ b/src/Symfony/Component/Yaml/Inline.php
@@ -127,6 +127,8 @@ public static function dump($value, int $flags = 0): string
return self::dumpNull($flags);
case $value instanceof \DateTimeInterface:
return $value->format('c');
+ case $value instanceof \UnitEnum:
+ return sprintf('!php/const %s::%s', \get_class($value), $value->name);
case \is_object($value):
if ($value instanceof TaggedValue) {
return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags);
diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php b/src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php
new file mode 100644
index 0000000000000..59092e27e8728
--- /dev/null
+++ b/src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php
@@ -0,0 +1,8 @@
+assertSame($expected, Inline::dump($dateTime));
}
+ /**
+ * @requires PHP 8.1
+ */
+ public function testDumpUnitEnum()
+ {
+ $this->assertSame("!php/const Symfony\Component\Yaml\Tests\Fixtures\FooUnitEnum::BAR", Inline::dump(FooUnitEnum::BAR));
+ }
+
public function getDateTimeDumpTests()
{
$tests = [];