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

[OptionsResolver] Documenting nested options feature #9995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions 94 components/options_resolver.rst
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,100 @@ let you find out which options are defined::
}
}

Nested Option
~~~~~~~~~~~~~

.. versionadded:: 4.2
This feature was introduced in Symfony 4.2.

Suppose you have an option named ``spool`` which has two sub-options ``type``
and ``path``. Instead of defining it as a simple array of values, you can pass
a closure as the default value of the ``spool`` option with a :class:`Symfony\\Component\\OptionsResolver\\OptionsResolver`
argument. Based on this instance, you can define the options under ``spool`` and its desired default
value::

class Mailer
{
// ...

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('spool', function (OptionsResolver $spoolResolver) {
$spoolResolver->setDefaults(array(
'type' => 'file',
'path' => '/path/to/spool',
));
$spoolResolver->setAllowedValues('type', array('file', 'memory'));
$spoolResolver->setAllowedTypes('path', 'string');
});
}

public function sendMail($from, $to)
{
if ('memory' === $this->options['spool']['type']) {
// ...
}
}
}

$mailer = new Mailer(array(
'spool' => array(
'type' => 'memory',
),
));

Also you can define required options, validation (type, value) and normalization of these
nested options.

If the default value of a child option depend on another option defined in parent level,
adds a second ``Options`` argument to the closure for access to them::

class Mailer
{
// ...

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('sandbox', false);
$resolver->setDefault('spool', function (OptionsResolver $spoolResolver, Options $parent) {
$spoolResolver->setDefaults(array(
'type' => $parent['sandbox'] ? 'memory' : 'file',
// ...
));
});
}
}

.. caution::

The arguments of the closure must be type hinted as ``OptionsResolver`` and ``Options`` respectively.
Otherwise, the closure itself is considered as the default value of the option.

In same way, parent options can access to the child option as normal array::

class Mailer
{
// ...

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('spool', function (OptionsResolver $spoolResolver) {
$spoolResolver->setDefaults(array(
'type' => 'file',
// ...
));
});
$resolver->setDefault('profiling', function (Options $options) {
return 'file' === $options['spool']['type'];
});
}
}

.. note::

The fact that an option is defined as nested means that you must pass
an array of values to resolve it at runtime.

Deprecating the Option
~~~~~~~~~~~~~~~~~~~~~~

Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.