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 bef49ae

Browse filesBrowse files
committed
Added support for nesting options as default value
1 parent 2ae7ad9 commit bef49ae
Copy full SHA for bef49ae

File tree

3 files changed

+500
-4
lines changed
Filter options

3 files changed

+500
-4
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/OptionsResolver/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
4.2.0
5+
-----
6+
7+
* added support for nesting options as default value
8+
49
3.4.0
510
-----
611

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/OptionsResolver/OptionsResolver.php
+54-4Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class OptionsResolver implements Options
3636
*/
3737
private $defaults = array();
3838

39+
/**
40+
* A list of closures for nested options.
41+
*
42+
* @var \Closure[][]
43+
*/
44+
private $nested = array();
45+
3946
/**
4047
* The names of required options.
4148
*/
@@ -161,15 +168,27 @@ public function setDefault($option, $value)
161168
$this->lazy[$option][] = $value;
162169
$this->defined[$option] = true;
163170

164-
// Make sure the option is processed
165-
unset($this->resolved[$option]);
171+
// Make sure the option is processed and is not nested anymore
172+
unset($this->resolved[$option], $this->nested[$option]);
173+
174+
return $this;
175+
}
176+
177+
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))) {
178+
$this->nested[$option][] = $value;
179+
180+
$this->defaults[$option] = array();
181+
$this->defined[$option] = true;
182+
183+
// Make sure the option is processed and this option is not lazy anymore
184+
unset($this->resolved[$option], $this->lazy[$option]);
166185

167186
return $this;
168187
}
169188
}
170189

171-
// This option is not lazy anymore
172-
unset($this->lazy[$option]);
190+
// This option is not lazy nor nested anymore
191+
unset($this->lazy[$option], $this->nested[$option]);
173192

174193
// Yet undefined options can be marked as resolved, because we only need
175194
// to resolve options with lazy closures, normalizers or validation
@@ -614,6 +633,7 @@ public function clear()
614633

615634
$this->defined = array();
616635
$this->defaults = array();
636+
$this->nested = array();
617637
$this->required = array();
618638
$this->resolved = array();
619639
$this->lazy = array();
@@ -745,6 +765,36 @@ public function offsetGet($option)
745765

746766
$value = $this->defaults[$option];
747767

768+
// Resolve the option if the default value is nested
769+
if (isset($this->nested[$option])) {
770+
// If the closure is already being called, we have a cyclic
771+
// dependency
772+
if (isset($this->calling[$option])) {
773+
throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', implode('", "', array_keys($this->calling))));
774+
}
775+
776+
// Nested values must be an array
777+
if (!\is_array($value)) {
778+
throw new InvalidOptionsException(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')));
779+
}
780+
781+
// The following section must be protected from cyclic
782+
// calls. Set $calling for the current $option to detect a cyclic
783+
// dependency
784+
// BEGIN
785+
$this->calling[$option] = true;
786+
try {
787+
$resolver = new self();
788+
foreach ($this->nested[$option] as $closure) {
789+
$closure($resolver, $this);
790+
}
791+
$value = $resolver->resolve($value);
792+
} finally {
793+
unset($this->calling[$option]);
794+
}
795+
// END
796+
}
797+
748798
// Resolve the option if the default value is lazily evaluated
749799
if (isset($this->lazy[$option])) {
750800
// If the closure is already being called, we have a cyclic

0 commit comments

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