Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ac36617

Browse files
ogizanaginicolas-grekas
authored andcommitted
[DependencyInjection][FrameworkBundle] Fix using PHP 8.1 enum as parameters
1 parent 582f572 commit ac36617

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+265
-52
lines changed

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,20 @@ protected function formatValue($value): string
168168
*/
169169
protected function formatParameter($value): string
170170
{
171+
if ($value instanceof \UnitEnum) {
172+
return var_export($value, true);
173+
}
174+
175+
// Recursively search for enum values, so we can replace it
176+
// before json_encode (which will not display anything for \UnitEnum otherwise)
177+
if (\is_array($value)) {
178+
array_walk_recursive($value, static function (&$value) {
179+
if ($value instanceof \UnitEnum) {
180+
$value = var_export($value, true);
181+
}
182+
});
183+
}
184+
171185
if (\is_bool($value) || \is_array($value) || (null === $value)) {
172186
$jsonString = json_encode($value);
173187

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ private function writeData(array $data, array $options)
158158
{
159159
$flags = $options['json_encoding'] ?? 0;
160160

161+
// Recursively search for enum values, so we can replace it
162+
// before json_encode (which will not display anything for \UnitEnum otherwise)
163+
array_walk_recursive($data, static function (&$value) {
164+
if ($value instanceof \UnitEnum) {
165+
$value = var_export($value, true);
166+
}
167+
});
168+
161169
$this->write(json_encode($data, $flags | \JSON_PRETTY_PRINT)."\n");
162170
}
163171

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ protected function describeContainerDefinition(Definition $definition, array $op
342342
$argumentsInformation[] = sprintf('Service locator (%d element(s))', \count($argument->getValues()));
343343
} elseif ($argument instanceof Definition) {
344344
$argumentsInformation[] = 'Inlined Service';
345+
} elseif ($argument instanceof \UnitEnum) {
346+
$argumentsInformation[] = var_export($argument, true);
345347
} else {
346348
$argumentsInformation[] = \is_array($argument) ? sprintf('Array (%d element(s))', \count($argument)) : $argument;
347349
}

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,9 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom): array
386386
foreach ($this->getArgumentNodes($argument, $dom) as $childArgumentXML) {
387387
$argumentXML->appendChild($childArgumentXML);
388388
}
389+
} elseif ($argument instanceof \UnitEnum) {
390+
$argumentXML->setAttribute('type', 'constant');
391+
$argumentXML->appendChild(new \DOMText(var_export($argument, true)));
389392
} else {
390393
$argumentXML->appendChild(new \DOMText($argument));
391394
}

src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function setContainer(ContainerInterface $container): ?ContainerInterface
5858
/**
5959
* Gets a container parameter by its name.
6060
*
61-
* @return array|bool|float|int|string|null
61+
* @return array|bool|float|int|string|\UnitEnum|null
6262
*
6363
* @final
6464
*/

src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ abstract class Controller implements ContainerAwareInterface
3131
/**
3232
* Gets a container configuration parameter by its name.
3333
*
34-
* @return array|bool|float|int|string|null
34+
* @return array|bool|float|int|string|\UnitEnum|null
3535
*
3636
* @final
3737
*/

src/Symfony/Bundle/FrameworkBundle/Test/TestContainer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function getParameterBag(): ParameterBagInterface
5959
/**
6060
* {@inheritdoc}
6161
*
62-
* @return array|bool|float|int|string|null
62+
* @return array|bool|float|int|string|\UnitEnum|null
6363
*/
6464
public function getParameter($name)
6565
{

src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum;
1516
use Symfony\Component\Console\Input\ArrayInput;
1617
use Symfony\Component\Console\Output\BufferedOutput;
1718
use Symfony\Component\Console\Style\SymfonyStyle;
@@ -121,6 +122,10 @@ public function getDescribeContainerDefinitionWithArgumentsShownTestData()
121122
$definitionsWithArgs[str_replace('definition_', 'definition_arguments_', $key)] = $definition;
122123
}
123124

125+
if (\PHP_VERSION_ID >= 80100) {
126+
$definitionsWithArgs['definition_arguments_with_enum'] = (new Definition('definition_with_enum'))->setArgument(0, FooUnitEnum::FOO);
127+
}
128+
124129
return $this->getDescriptionTestData($definitionsWithArgs);
125130
}
126131

@@ -248,7 +253,7 @@ private function assertDescription($expectedDescription, $describedObject, array
248253
}
249254
}
250255

251-
private function getDescriptionTestData(array $objects)
256+
private function getDescriptionTestData(iterable $objects)
252257
{
253258
$data = [];
254259
foreach ($objects as $name => $object) {

src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor;
1313

14+
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum;
15+
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Suit;
1416
use Symfony\Component\DependencyInjection\Alias;
1517
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1618
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -61,14 +63,26 @@ public static function getRoutes()
6163

6264
public static function getContainerParameters()
6365
{
64-
return [
65-
'parameters_1' => new ParameterBag([
66-
'integer' => 12,
67-
'string' => 'Hello world!',
68-
'boolean' => true,
69-
'array' => [12, 'Hello world!', true],
70-
]),
71-
];
66+
yield 'parameters_1' => new ParameterBag([
67+
'integer' => 12,
68+
'string' => 'Hello world!',
69+
'boolean' => true,
70+
'array' => [12, 'Hello world!', true],
71+
]);
72+
73+
if (\PHP_VERSION_ID < 80100) {
74+
return;
75+
}
76+
77+
yield 'parameters_enums' => new ParameterBag([
78+
'unit_enum' => FooUnitEnum::BAR,
79+
'backed_enum' => Suit::Hearts,
80+
'array_of_enums' => Suit::cases(),
81+
'map' => [
82+
'mixed' => [Suit::Hearts, FooUnitEnum::BAR],
83+
'single' => FooUnitEnum::BAR,
84+
],
85+
]);
7286
}
7387

7488
public static function getContainerParameter()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"class": "definition_with_enum",
3+
"public": false,
4+
"synthetic": false,
5+
"lazy": false,
6+
"shared": true,
7+
"abstract": false,
8+
"autowire": false,
9+
"autoconfigure": false,
10+
"arguments": [
11+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\FooUnitEnum::FOO"
12+
],
13+
"file": null,
14+
"tags": []
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
- Class: `definition_with_enum`
2+
- Public: no
3+
- Synthetic: no
4+
- Lazy: no
5+
- Shared: yes
6+
- Abstract: no
7+
- Autowired: no
8+
- Autoconfigured: no
9+
- Arguments: yes
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---------------- ----------------------------------------------------------------
2+
 Option   Value 
3+
---------------- ----------------------------------------------------------------
4+
Service ID -
5+
Class definition_with_enum
6+
Tags -
7+
Public no
8+
Synthetic no
9+
Lazy no
10+
Shared yes
11+
Abstract no
12+
Autowired no
13+
Autoconfigured no
14+
Arguments Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum::FOO
15+
---------------- ----------------------------------------------------------------
16+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<definition class="definition_with_enum" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file="">
3+
<argument type="constant">Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum::FOO</argument>
4+
</definition>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"array_of_enums": [
3+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::Hearts",
4+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::Diamonds",
5+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::Clubs",
6+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::Spades"
7+
],
8+
"backed_enum": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::Hearts",
9+
"map": {
10+
"mixed": [
11+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::Hearts",
12+
"Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\FooUnitEnum::BAR"
13+
],
14+
"single": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\FooUnitEnum::BAR"
15+
},
16+
"unit_enum": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\FooUnitEnum::BAR"
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Container parameters
2+
====================
3+
4+
- `array_of_enums`: `["Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::H...`
5+
- `backed_enum`: `Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Suit::Hearts`
6+
- `map`: `{"mixed":["Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures...`
7+
- `unit_enum`: `Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum::BAR`
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Symfony Container Parameters
2+
============================
3+
4+
---------------- -----------------------------------------------------------------
5+
 Parameter   Value 
6+
---------------- -----------------------------------------------------------------
7+
array_of_enums ["Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::H...
8+
backed_enum Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Suit::Hearts
9+
map {"mixed":["Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures...
10+
unit_enum Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum::BAR
11+
---------------- -----------------------------------------------------------------
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<parameters>
3+
<parameter key="array_of_enums">["Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures\\Suit::H...</parameter>
4+
<parameter key="backed_enum">Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Suit::Hearts</parameter>
5+
<parameter key="map">{"mixed":["Symfony\\Bundle\\FrameworkBundle\\Tests\\Fixtures...</parameter>
6+
<parameter key="unit_enum">Symfony\Bundle\FrameworkBundle\Tests\Fixtures\FooUnitEnum::BAR</parameter>
7+
</parameters>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures;
13+
14+
enum FooUnitEnum
15+
{
16+
case BAR;
17+
case FOO;
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures;
13+
14+
enum Suit: string
15+
{
16+
case Hearts = 'H';
17+
case Diamonds = 'D';
18+
case Clubs = 'C';
19+
case Spades = 'S';
20+
}

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"ext-xml": "*",
2121
"symfony/cache": "^4.4|^5.0",
2222
"symfony/config": "^4.4.11|~5.0.11|^5.1.3",
23-
"symfony/dependency-injection": "^4.4.1|^5.0.1",
23+
"symfony/dependency-injection": "^4.4.38|^5.0.1",
2424
"symfony/error-handler": "^4.4.1|^5.0.1",
2525
"symfony/http-foundation": "^4.4|^5.0",
2626
"symfony/http-kernel": "^4.4",

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function getParameterBag()
109109
*
110110
* @param string $name The parameter name
111111
*
112-
* @return array|bool|string|int|float|null
112+
* @return array|bool|string|int|float|\UnitEnum|null
113113
*
114114
* @throws InvalidArgumentException if the parameter is not defined
115115
*/
@@ -133,8 +133,8 @@ public function hasParameter($name)
133133
/**
134134
* Sets a parameter.
135135
*
136-
* @param string $name The parameter name
137-
* @param array|bool|string|int|float|null $value The parameter value
136+
* @param string $name The parameter name
137+
* @param array|bool|string|int|float|\UnitEnum|null $value The parameter value
138138
*/
139139
public function setParameter($name, $value)
140140
{

src/Symfony/Component/DependencyInjection/ContainerInterface.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public function initialized($id);
7474
*
7575
* @param string $name The parameter name
7676
*
77-
* @return array|bool|string|int|float|null
77+
* @return array|bool|string|int|float|\UnitEnum|null
7878
*
7979
* @throws InvalidArgumentException if the parameter is not defined
8080
*/
@@ -92,8 +92,8 @@ public function hasParameter($name);
9292
/**
9393
* Sets a parameter.
9494
*
95-
* @param string $name The parameter name
96-
* @param array|bool|string|int|float|null $value The parameter value
95+
* @param string $name The parameter name
96+
* @param array|bool|string|int|float|\UnitEnum|null $value The parameter value
9797
*/
9898
public function setParameter($name, $value);
9999
}

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,10 +1436,11 @@ private function addDefaultParametersMethod(): string
14361436
if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) {
14371437
throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: "%s".', $resolvedKey));
14381438
}
1439-
$export = $this->exportParameters([$value]);
1439+
$hasEnum = false;
1440+
$export = $this->exportParameters([$value], '', 12, $hasEnum);
14401441
$export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2);
14411442

1442-
if (preg_match("/\\\$this->(?:getEnv\('(?:[-.\w]*+:)*+\w++'\)|targetDir\.'')/", $export[1])) {
1443+
if ($hasEnum || preg_match("/\\\$this->(?:getEnv\('(?:[-.\w]*+:)*+\w++'\)|targetDir\.'')/", $export[1])) {
14431444
$dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]);
14441445
} else {
14451446
$php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]);
@@ -1450,7 +1451,7 @@ private function addDefaultParametersMethod(): string
14501451
$code = <<<'EOF'
14511452
14521453
/**
1453-
* @return array|bool|float|int|string|null
1454+
* @return array|bool|float|int|string|\UnitEnum|null
14541455
*/
14551456
public function getParameter($name)
14561457
{
@@ -1545,12 +1546,12 @@ protected function getDefaultParameters(): array
15451546
/**
15461547
* @throws InvalidArgumentException
15471548
*/
1548-
private function exportParameters(array $parameters, string $path = '', int $indent = 12): string
1549+
private function exportParameters(array $parameters, string $path = '', int $indent = 12, bool &$hasEnum = false): string
15491550
{
15501551
$php = [];
15511552
foreach ($parameters as $key => $value) {
15521553
if (\is_array($value)) {
1553-
$value = $this->exportParameters($value, $path.'/'.$key, $indent + 4);
1554+
$value = $this->exportParameters($value, $path.'/'.$key, $indent + 4, $hasEnum);
15541555
} elseif ($value instanceof ArgumentInterface) {
15551556
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', \get_class($value), $path.'/'.$key));
15561557
} elseif ($value instanceof Variable) {
@@ -1561,6 +1562,9 @@ private function exportParameters(array $parameters, string $path = '', int $ind
15611562
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key));
15621563
} elseif ($value instanceof Expression) {
15631564
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path.'/'.$key));
1565+
} elseif ($value instanceof \UnitEnum) {
1566+
$hasEnum = true;
1567+
$value = sprintf('\%s::%s', \get_class($value), $value->name);
15641568
} else {
15651569
$value = $this->export($value);
15661570
}

src/Symfony/Component/DependencyInjection/ParameterBag/ContainerBag.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function all()
3636
/**
3737
* {@inheritdoc}
3838
*
39-
* @return array|bool|string|int|float|null
39+
* @return array|bool|string|int|float|\UnitEnum|null
4040
*/
4141
public function get($name)
4242
{

0 commit comments

Comments
 (0)