Skip to content

Commit ef06f33

Browse files
bug #40857 [DependencyInjection] Add support of PHP enumerations (alexandre-daubois)
This PR was merged into the 4.4 branch. Discussion ---------- [DependencyInjection] Add support of PHP enumerations | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes (new PHP version compatibility) | New feature? | no | Deprecations? | no | Tickets | Fix #40233 | License | MIT | Doc PR | _(see below)_ Added support of enums using `!php/const` tag, as they work the same way. Commits ------- 88c69c0 [DependencyInjection] Add support of PHP enumerations
2 parents b62881c + 88c69c0 commit ef06f33

17 files changed

+212
-0
lines changed

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,8 @@ private function dumpValue($value, bool $interpolate = true): string
18121812

18131813
return $code;
18141814
}
1815+
} elseif ($value instanceof \UnitEnum) {
1816+
return sprintf('\%s::%s', \get_class($value), $value->name);
18151817
} elseif (\is_object($value) || \is_resource($value)) {
18161818
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
18171819
}

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ private function convertParameters(array $parameters, string $type, \DOMElement
313313
$element->setAttribute('type', 'binary');
314314
$text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
315315
$element->appendChild($text);
316+
} elseif ($value instanceof \UnitEnum) {
317+
$element->setAttribute('type', 'constant');
318+
$element->appendChild($this->document->createTextNode(self::phpToXml($value)));
316319
} else {
317320
if (\in_array($value, ['null', 'true', 'false'], true)) {
318321
$element->setAttribute('type', 'string');
@@ -366,6 +369,8 @@ public static function phpToXml($value): string
366369
return 'false';
367370
case $value instanceof Parameter:
368371
return '%'.$value.'%';
372+
case $value instanceof \UnitEnum:
373+
return sprintf('%s::%s', \get_class($value), $value->name);
369374
case \is_object($value) || \is_resource($value):
370375
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
371376
default:

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ private function dumpValue($value)
286286
return $this->getExpressionCall((string) $value);
287287
} elseif ($value instanceof Definition) {
288288
return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
289+
} elseif ($value instanceof \UnitEnum) {
290+
return new TaggedValue('php/const', sprintf('%s::%s', \get_class($value), $value->name));
289291
} elseif (\is_object($value) || \is_resource($value)) {
290292
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
291293
}

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
4141
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
4242
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
43+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
44+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
4345
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
4446
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
4547
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
@@ -1208,6 +1210,29 @@ public function testDumpHandlesObjectClassNames()
12081210
$this->assertInstanceOf(\stdClass::class, $container->get('bar'));
12091211
}
12101212

1213+
/**
1214+
* @requires PHP 8.1
1215+
*/
1216+
public function testDumpHandlesEnumeration()
1217+
{
1218+
$container = new ContainerBuilder();
1219+
$container
1220+
->register('foo', FooClassWithEnumAttribute::class)
1221+
->setPublic(true)
1222+
->addArgument(FooUnitEnum::BAR);
1223+
1224+
$container->compile();
1225+
1226+
$dumper = new PhpDumper($container);
1227+
eval('?>'.$dumper->dump([
1228+
'class' => 'Symfony_DI_PhpDumper_Test_Enumeration',
1229+
]));
1230+
1231+
$container = new \Symfony_DI_PhpDumper_Test_Enumeration();
1232+
1233+
$this->assertSame(FooUnitEnum::BAR, $container->get('foo')->getBar());
1234+
}
1235+
12111236
public function testUninitializedSyntheticReference()
12121237
{
12131238
$container = new ContainerBuilder();

src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
2222
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
2323
use Symfony\Component\DependencyInjection\Reference;
24+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
25+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
2426

2527
class XmlDumperTest extends TestCase
2628
{
@@ -249,4 +251,21 @@ public function testDumpAbstractServices()
249251

250252
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump());
251253
}
254+
255+
/**
256+
* @requires PHP 8.1
257+
*/
258+
public function testDumpHandlesEnumeration()
259+
{
260+
$container = new ContainerBuilder();
261+
$container
262+
->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class)
263+
->setPublic(true)
264+
->addArgument(FooUnitEnum::BAR);
265+
266+
$container->compile();
267+
$dumper = new XmlDumper($container);
268+
269+
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_with_enumeration.xml'), $dumper->dump());
270+
}
252271
}

src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
2323
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
2424
use Symfony\Component\DependencyInjection\Reference;
25+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
26+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
2527
use Symfony\Component\Yaml\Parser;
2628
use Symfony\Component\Yaml\Yaml;
2729

@@ -129,6 +131,23 @@ public function testServiceClosure()
129131
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_service_closure.yml', $dumper->dump());
130132
}
131133

134+
/**
135+
* @requires PHP 8.1
136+
*/
137+
public function testDumpHandlesEnumeration()
138+
{
139+
$container = new ContainerBuilder();
140+
$container
141+
->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class)
142+
->setPublic(true)
143+
->addArgument(FooUnitEnum::BAR);
144+
145+
$container->compile();
146+
$dumper = new YamlDumper($container);
147+
148+
$this->assertEquals(file_get_contents(self::$fixturesPath.'/yaml/services_with_enumeration.yml'), $dumper->dump());
149+
}
150+
132151
private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '')
133152
{
134153
$parser = new Parser();
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+
class FooClassWithEnumAttribute
6+
{
7+
private FooUnitEnum $bar;
8+
9+
public function __construct(FooUnitEnum $bar)
10+
{
11+
$this->bar = $bar;
12+
}
13+
14+
public function getBar(): FooUnitEnum
15+
{
16+
return $this->bar;
17+
}
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
enum FooUnitEnum
6+
{
7+
case BAR;
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
5+
<service id="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" class="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" public="true">
6+
<argument type="constant">Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR</argument>
7+
</service>
8+
</services>
9+
</container>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
5+
<service id="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" class="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" public="true">
6+
<argument type="constant">Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ</argument>
7+
</service>
8+
</services>
9+
</container>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy