Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2d81a3a

Browse filesBrowse files
HypeMCnicolas-grekas
authored andcommitted
[Config] Allow scalar configuration in PHP Configuration
1 parent 1c176e1 commit 2d81a3a
Copy full SHA for 2d81a3a

Some content is hidden

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

47 files changed

+1218
-264
lines changed

‎src/Symfony/Component/Config/Builder/ClassBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Builder/ClassBuilder.php
+3-5Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function build(): string
6868
}
6969
$require .= sprintf('require_once __DIR__.\DIRECTORY_SEPARATOR.\'%s\';', implode('\'.\DIRECTORY_SEPARATOR.\'', $path))."\n";
7070
}
71-
$use = '';
71+
$use = $require ? "\n" : '';
7272
foreach (array_keys($this->use) as $statement) {
7373
$use .= sprintf('use %s;', $statement)."\n";
7474
}
@@ -81,17 +81,15 @@ public function build(): string
8181
foreach ($this->methods as $method) {
8282
$lines = explode("\n", $method->getContent());
8383
foreach ($lines as $line) {
84-
$body .= ' '.$line."\n";
84+
$body .= ($line ? ' '.$line : '')."\n";
8585
}
8686
}
8787

8888
$content = strtr('<?php
8989
9090
namespace NAMESPACE;
9191
92-
REQUIRE
93-
USE
94-
92+
REQUIREUSE
9593
/**
9694
* This class is automatically generated to help in creating a config.
9795
*/

‎src/Symfony/Component/Config/Builder/ConfigBuilderGenerator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Builder/ConfigBuilderGenerator.php
+109-17Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,39 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
136136
$class->addRequire($childClass);
137137
$this->classes[] = $childClass;
138138

139-
$property = $class->addProperty($node->getName(), $childClass->getFqcn());
140-
$body = '
139+
$hasNormalizationClosures = $this->hasNormalizationClosures($node);
140+
$property = $class->addProperty(
141+
$node->getName(),
142+
$this->getType($childClass->getFqcn(), $hasNormalizationClosures)
143+
);
144+
$body = $hasNormalizationClosures ? '
145+
/**
146+
* @return CLASS|$this
147+
*/
148+
public function NAME($value = [])
149+
{
150+
if (!\is_array($value)) {
151+
$this->_usedProperties[\'PROPERTY\'] = true;
152+
$this->PROPERTY = $value;
153+
154+
return $this;
155+
}
156+
157+
if (!$this->PROPERTY instanceof CLASS) {
158+
$this->_usedProperties[\'PROPERTY\'] = true;
159+
$this->PROPERTY = new CLASS($value);
160+
} elseif (0 < \func_num_args()) {
161+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
162+
}
163+
164+
return $this->PROPERTY;
165+
}' : '
141166
public function NAME(array $value = []): CLASS
142167
{
143168
if (null === $this->PROPERTY) {
144169
$this->_usedProperties[\'PROPERTY\'] = true;
145170
$this->PROPERTY = new CLASS($value);
146-
} elseif ([] !== $value) {
171+
} elseif (0 < \func_num_args()) {
147172
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
148173
}
149174
@@ -227,10 +252,29 @@ public function NAME(string $VAR, $VALUE): self
227252
}
228253
$class->addRequire($childClass);
229254
$this->classes[] = $childClass;
230-
$property = $class->addProperty($node->getName(), $childClass->getFqcn().'[]');
255+
256+
$hasNormalizationClosures = $this->hasNormalizationClosures($node) || $this->hasNormalizationClosures($prototype);
257+
$property = $class->addProperty(
258+
$node->getName(),
259+
$this->getType($childClass->getFqcn().'[]', $hasNormalizationClosures)
260+
);
231261

232262
if (null === $key = $node->getKeyAttribute()) {
233-
$body = '
263+
$body = $hasNormalizationClosures ? '
264+
/**
265+
* @return CLASS|$this
266+
*/
267+
public function NAME($value = [])
268+
{
269+
$this->_usedProperties[\'PROPERTY\'] = true;
270+
if (!\is_array($value)) {
271+
$this->PROPERTY[] = $value;
272+
273+
return $this;
274+
}
275+
276+
return $this->PROPERTY[] = new CLASS($value);
277+
}' : '
234278
public function NAME(array $value = []): CLASS
235279
{
236280
$this->_usedProperties[\'PROPERTY\'] = true;
@@ -239,19 +283,38 @@ public function NAME(array $value = []): CLASS
239283
}';
240284
$class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
241285
} else {
242-
$body = '
243-
public function NAME(string $VAR, array $VALUE = []): CLASS
286+
$body = $hasNormalizationClosures ? '
287+
/**
288+
* @return CLASS|$this
289+
*/
290+
public function NAME(string $VAR, $VALUE = [])
244291
{
245-
if (!isset($this->PROPERTY[$VAR])) {
292+
if (!\is_array($VALUE)) {
246293
$this->_usedProperties[\'PROPERTY\'] = true;
294+
$this->PROPERTY[$VAR] = $VALUE;
247295
248-
return $this->PROPERTY[$VAR] = new CLASS($VALUE);
296+
return $this;
249297
}
250-
if ([] === $VALUE) {
251-
return $this->PROPERTY[$VAR];
298+
299+
if (!isset($this->PROPERTY[$VAR]) || !$this->PROPERTY[$VAR] instanceof CLASS) {
300+
$this->_usedProperties[\'PROPERTY\'] = true;
301+
$this->PROPERTY[$VAR] = new CLASS($VALUE);
302+
} elseif (1 < \func_num_args()) {
303+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
304+
}
305+
306+
return $this->PROPERTY[$VAR];
307+
}' : '
308+
public function NAME(string $VAR, array $VALUE = []): CLASS
309+
{
310+
if (!isset($this->PROPERTY[$VAR])) {
311+
$this->_usedProperties[\'PROPERTY\'] = true;
312+
$this->PROPERTY[$VAR] = new CLASS($VALUE);
313+
} elseif (1 < \func_num_args()) {
314+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
252315
}
253316
254-
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
317+
return $this->PROPERTY[$VAR];
255318
}';
256319
$class->addUse(InvalidConfigurationException::class);
257320
$class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value']);
@@ -375,16 +438,22 @@ private function buildToArray(ClassBuilder $class): void
375438
$code = '$this->PROPERTY';
376439
if (null !== $p->getType()) {
377440
if ($p->isArray()) {
378-
$code = 'array_map(function ($v) { return $v->toArray(); }, $this->PROPERTY)';
441+
$code = $p->areScalarsAllowed()
442+
? 'array_map(function ($v) { return $v instanceof CLASS ? $v->toArray() : $v; }, $this->PROPERTY)'
443+
: 'array_map(function ($v) { return $v->toArray(); }, $this->PROPERTY)'
444+
;
379445
} else {
380-
$code = '$this->PROPERTY->toArray()';
446+
$code = $p->areScalarsAllowed()
447+
? '$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY'
448+
: '$this->PROPERTY->toArray()'
449+
;
381450
}
382451
}
383452

384453
$body .= strtr('
385454
if (isset($this->_usedProperties[\'PROPERTY\'])) {
386455
$output[\'ORG_NAME\'] = '.$code.';
387-
}', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName()]);
456+
}', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName(), 'CLASS' => $p->getType()]);
388457
}
389458

390459
$extraKeys = $class->shouldAllowExtraKeys() ? ' + $this->_extraKeys' : '';
@@ -405,9 +474,15 @@ private function buildConstructor(ClassBuilder $class): void
405474
$code = '$value[\'ORG_NAME\']';
406475
if (null !== $p->getType()) {
407476
if ($p->isArray()) {
408-
$code = 'array_map(function ($v) { return new '.$p->getType().'($v); }, $value[\'ORG_NAME\'])';
477+
$code = $p->areScalarsAllowed()
478+
? 'array_map(function ($v) { return \is_array($v) ? new '.$p->getType().'($v) : $v; }, $value[\'ORG_NAME\'])'
479+
: 'array_map(function ($v) { return new '.$p->getType().'($v); }, $value[\'ORG_NAME\'])'
480+
;
409481
} else {
410-
$code = 'new '.$p->getType().'($value[\'ORG_NAME\'])';
482+
$code = $p->areScalarsAllowed()
483+
? '\is_array($value[\'ORG_NAME\']) ? new '.$p->getType().'($value[\'ORG_NAME\']) : $value[\'ORG_NAME\']'
484+
: 'new '.$p->getType().'($value[\'ORG_NAME\'])'
485+
;
411486
}
412487
}
413488

@@ -466,4 +541,21 @@ private function getSubNamespace(ClassBuilder $rootClass): string
466541
{
467542
return sprintf('%s\\%s', $rootClass->getNamespace(), substr($rootClass->getName(), 0, -6));
468543
}
544+
545+
private function hasNormalizationClosures(NodeInterface $node): bool
546+
{
547+
try {
548+
$r = new \ReflectionProperty($node, 'normalizationClosures');
549+
} catch (\ReflectionException $e) {
550+
return false;
551+
}
552+
$r->setAccessible(true);
553+
554+
return [] !== $r->getValue($node);
555+
}
556+
557+
private function getType(string $classType, bool $hasNormalizationClosures): string
558+
{
559+
return $classType.($hasNormalizationClosures ? '|scalar' : '');
560+
}
469561
}

‎src/Symfony/Component/Config/Builder/Property.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Builder/Property.php
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Property
2323
private $name;
2424
private $originalName;
2525
private $array = false;
26+
private $scalarsAllowed = false;
2627
private $type = null;
2728
private $content;
2829

@@ -47,6 +48,11 @@ public function setType(string $type): void
4748
$this->array = false;
4849
$this->type = $type;
4950

51+
if ('|scalar' === substr($type, -7)) {
52+
$this->scalarsAllowed = true;
53+
$this->type = $type = substr($type, 0, -7);
54+
}
55+
5056
if ('[]' === substr($type, -2)) {
5157
$this->array = true;
5258
$this->type = substr($type, 0, -2);
@@ -72,4 +78,9 @@ public function isArray(): bool
7278
{
7379
return $this->array;
7480
}
81+
82+
public function areScalarsAllowed(): bool
83+
{
84+
return $this->scalarsAllowed;
85+
}
7586
}

‎src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList.config.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList.config.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<?php
22

3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
312
use Symfony\Config\AddToListConfig;
413

514
return static function (AddToListConfig $config) {

‎src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList.output.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList.output.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<?php
22

3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
312
return [
413
'translator' => [
514
'fallbacks' => ['sv', 'fr', 'es'],

‎src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<?php
22

3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
312
namespace Symfony\Component\Config\Tests\Builder\Fixtures;
413

514
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

‎src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList/Symfony/Config/AddToList/Messenger/ReceivingConfig.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList/Symfony/Config/AddToList/Messenger/ReceivingConfig.php
+9-12Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
namespace Symfony\Config\AddToList\Messenger;
44

5-
65
use Symfony\Component\Config\Loader\ParamConfigurator;
76
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
87

9-
108
/**
119
* This class is automatically generated to help in creating a config.
1210
*/
@@ -15,7 +13,7 @@ class ReceivingConfig
1513
private $priority;
1614
private $color;
1715
private $_usedProperties = [];
18-
16+
1917
/**
2018
* @default null
2119
* @param ParamConfigurator|int $value
@@ -25,10 +23,10 @@ public function priority($value): self
2523
{
2624
$this->_usedProperties['priority'] = true;
2725
$this->priority = $value;
28-
26+
2927
return $this;
3028
}
31-
29+
3230
/**
3331
* @default null
3432
* @param ParamConfigurator|mixed $value
@@ -38,30 +36,29 @@ public function color($value): self
3836
{
3937
$this->_usedProperties['color'] = true;
4038
$this->color = $value;
41-
39+
4240
return $this;
4341
}
44-
42+
4543
public function __construct(array $value = [])
4644
{
47-
4845
if (array_key_exists('priority', $value)) {
4946
$this->_usedProperties['priority'] = true;
5047
$this->priority = $value['priority'];
5148
unset($value['priority']);
5249
}
53-
50+
5451
if (array_key_exists('color', $value)) {
5552
$this->_usedProperties['color'] = true;
5653
$this->color = $value['color'];
5754
unset($value['color']);
5855
}
59-
56+
6057
if ([] !== $value) {
6158
throw new InvalidConfigurationException(sprintf('The following keys are not supported by "%s": ', __CLASS__).implode(', ', array_keys($value)));
6259
}
6360
}
64-
61+
6562
public function toArray(): array
6663
{
6764
$output = [];
@@ -71,7 +68,7 @@ public function toArray(): array
7168
if (isset($this->_usedProperties['color'])) {
7269
$output['color'] = $this->color;
7370
}
74-
71+
7572
return $output;
7673
}
7774

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.