Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitd04e40b

Browse files
committed
Added support for nested options definition
1 parent8ab7077 commitd04e40b

File tree

3 files changed

+480
-4
lines changed

3 files changed

+480
-4
lines changed

‎src/Symfony/Component/OptionsResolver/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.2.0
55
-----
66

7+
* added support for nested options definition
78
* added`setDeprecated` and`isDeprecated` methods
89

910
3.4.0

‎src/Symfony/Component/OptionsResolver/OptionsResolver.php‎

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ class OptionsResolver implements Options
3737
*/
3838
private$defaults =array();
3939

40+
/**
41+
* A list of closure for nested options.
42+
*
43+
* @var \Closure[][]
44+
*/
45+
private$nested =array();
46+
4047
/**
4148
* The names of required options.
4249
*/
@@ -130,6 +137,20 @@ class OptionsResolver implements Options
130137
* is spread across different locations of your code, such as base and
131138
* sub-classes.
132139
*
140+
* If you want to define nested options, you can pass a closure with the
141+
* following signature:
142+
*
143+
* $options->setDefault('database', function (OptionsResolver $resolver) {
144+
* $resolver->setDefined(array('dbname', 'host', 'port', 'user', 'pass'));
145+
* }
146+
*
147+
* To get access to the parent options, add a second argument to the closure's
148+
* signature:
149+
*
150+
* function (OptionsResolver $resolver, Options $parent) {
151+
* // 'default' === $parent['connection']
152+
* }
153+
*
133154
* @param string $option The name of the option
134155
* @param mixed $value The default value of the option
135156
*
@@ -167,15 +188,27 @@ public function setDefault($option, $value)
167188
$this->lazy[$option][] =$value;
168189
$this->defined[$option] =true;
169190

170-
// Make sure the option is processed
171-
unset($this->resolved[$option]);
191+
// Make sure the option is processed and is not nested anymore
192+
unset($this->resolved[$option],$this->nested[$option]);
193+
194+
return$this;
195+
}
196+
197+
if (isset($params[0]) &&null !== ($class =$params[0]->getClass()) &&self::class ===$class->name && (!isset($params[1]) || (null !== ($class =$params[1]->getClass()) && Options::class ===$class->name))) {
198+
// Store closure for later evaluation
199+
$this->nested[$option][] =$value;
200+
$this->defaults[$option] =array();
201+
$this->defined[$option] =true;
202+
203+
// Make sure the option is processed and is not lazy anymore
204+
unset($this->resolved[$option],$this->lazy[$option]);
172205

173206
return$this;
174207
}
175208
}
176209

177-
// This option is not lazy anymore
178-
unset($this->lazy[$option]);
210+
// This option is not lazynor nestedanymore
211+
unset($this->lazy[$option],$this->nested[$option]);
179212

180213
// Yet undefined options can be marked as resolved, because we only need
181214
// to resolve options with lazy closures, normalizers or validation
@@ -354,6 +387,11 @@ public function getDefinedOptions()
354387
returnarray_keys($this->defined);
355388
}
356389

390+
publicfunctionisNested(string$option):bool
391+
{
392+
returnisset($this->nested[$option]);
393+
}
394+
357395
/**
358396
* Deprecates an option, allowed types or values.
359397
*
@@ -649,6 +687,7 @@ public function clear()
649687

650688
$this->defined =array();
651689
$this->defaults =array();
690+
$this->nested =array();
652691
$this->required =array();
653692
$this->resolved =array();
654693
$this->lazy =array();
@@ -767,6 +806,32 @@ public function offsetGet($option)
767806

768807
$value =$this->defaults[$option];
769808

809+
// Resolve the option if it is a nested definition
810+
if (isset($this->nested[$option])) {
811+
// If the closure is already being called, we have a cyclic dependency
812+
if (isset($this->calling[$option])) {
813+
thrownewOptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.',implode('", "',array_keys($this->calling))));
814+
}
815+
816+
if (!\is_array($value)) {
817+
thrownewInvalidOptionsException(sprintf('The nested option "%s" with value %s is expected to be of type array, but is of type "%s".',$option,$this->formatValue($value),$this->formatTypeOf($value,'array')));
818+
}
819+
820+
// The following section must be protected from cyclic calls.
821+
// BEGIN
822+
$this->calling[$option] =true;
823+
try {
824+
$resolver =newself();
825+
foreach ($this->nested[$option]as$closure) {
826+
$closure($resolver,$this);
827+
}
828+
$value =$resolver->resolve($value);
829+
}finally {
830+
unset($this->calling[$option]);
831+
}
832+
// END
833+
}
834+
770835
// Resolve the option if the default value is lazily evaluated
771836
if (isset($this->lazy[$option])) {
772837
// If the closure is already being called, we have a cyclic

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp