8000 Documenting nested options feature for OptionsResolver component · symfony/symfony-docs@f05980b · GitHub
[go: up one dir, main page]

Skip to content

Commit f05980b

Browse files
committed
Documenting nested options feature for OptionsResolver component
1 parent 4ea4efe commit f05980b

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

components/options_resolver.rst

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,105 @@ let you find out which options are defined::
634634
}
635635
}
636636

637+
Nested option
638+
~~~~~~~~~~~~~
639+
640+
.. versionadded:: 4.2
641+
This feature was introduced in Symfony 4.2.
642+
643+
Suppose you want an option named ``spool`` which has two sub-options ``type``
644+
and ``path``. Instead of define it as a simple array of values, you can pass
645+
a closure as the default value of the ``spool`` option with an :class:`Symfony\\Component\\OptionsResolver\\OptionsResolver`
646+
argument. Based on this instance, you can define the options under ``spool`` and its desired default
647+
value::
648+
649+
// ...
650+
class Mailer
651+
{
652+
// ...
653+
public function configureOptions(OptionsResolver $resolver)
654+
{
655+
// ...
656+
$resolver->setDefault('spool', function (OptionsResolver $spoolResolver) {
657+
$spoolResolver->setDefaults(array(
658+
'type' => 'file',
659+
'path' => '/path/to/spool',
660+
));
661+
$spoolResolver->setAllowedValues('type', array('file', 'memory'));
662+
$spoolResolver->setAllowedTypes('path', 'string');
663+
});
664+
}
665+
666+
public function sendMail($from, $to)
667+
{
668+
if ('memory' === $this->options['spool']['type']) {
669+
// ...
670+
}
671+
}
672+
}
673+
674+
$mailer = new Mailer(array(
675+
'spool' => array(
676+
'type' => 'memory',
677+
),
678+
));
679+
680+
It allows you to create a nested options system with required options, validation (type, value),
681+
normalization and more.
682+
683+
If the default value of a child option depend on another option defined in parent level,
684+
adds a second ``Options`` argument to the closure::
685+
686+
// ...
687+
class Mailer
688+
{
689+
// ...
690+
public function configureOptions(OptionsResolver $resolver)
691+
{
692+
// ...
693+
$resolver->setDefault('sandbox', false);
694+
$resolver->setDefault('spool', function (OptionsResolver $spoolResolver, Options $parent) {
695+
$spoolResolver->setDefaults(array(
696+
'type' => $parent['sandbox'] ? 'memory' : 'file',
697+
// ...
698+
));
699+
// ...
700+
});
701+
}
702+
}
703+
704+
.. caution::
705+
706+
The arguments of the closure must be type hinted as ``OptionsResolver`` and ``Options`` respectively.
707+
Otherwise, the closure itself is considered as the default value of the option.
708+
709+
In same way, parent options can access to the child option as follows::
710+
711+
// ...
712+
class Mailer
713+
{
714+
// ...
715+
public function configureOptions(OptionsResolver $resolver)
716+
{
717+
// ...
718+
$resolver->setDefault('spool', function (OptionsResolver $spoolResolver) {
719+
$spoolResolver->setDefaults(array(
720+
'type' => 'file',
721+
// ...
722+
));
723+
// ...
724+
});
725+
$resolver->setDefault('profiling', function (Options $options) {
726+
return 'file' === $options['spool']['type'];
727+
});
728+
}
729+
}
730+
731+
.. note::
732+
733+
The fact that an option is defined as nested, means that you must to pass
734+
an array of values to resolve it on runtime.
735+
637736
Deprecating the Option
638737
~~~~~~~~~~~~~~~~~~~~~~
639738

0 commit comments

Comments
 (0)
0