From 29d40a770adade71bd6208e4a1d3bf7649154089 Mon Sep 17 00:00:00 2001 From: Philipp Rieber Date: Mon, 2 Dec 2013 07:12:29 +0100 Subject: [PATCH 1/2] [Components][OptionsResolver] Fix&improve replaceDefaults() description --- components/options_resolver.rst | 89 ++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/components/options_resolver.rst b/components/options_resolver.rst index a05351b109e..e6f9d64bac6 100644 --- a/components/options_resolver.rst +++ b/components/options_resolver.rst @@ -177,21 +177,12 @@ override this default. You don't need to configure ``username`` as an optional option. The ``OptionsResolver`` already knows that options with a default value are optional. -The OptionsResolver component also has an -:method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::replaceDefaults` -method. This can be used to override the previous default value. The closure -that is passed has 2 parameters: - -* ``$options`` (an :class:`Symfony\\Component\\OptionsResolver\\Options` - instance), with all the default options -* ``$value``, the previous set default value - Default Values that depend on another Option ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose you add a ``port`` option to the ``Mailer`` class, whose default value you guess based on the host. You can do that easily by using a -Closure as the default value:: +closure as the default value:: use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolverInterface; @@ -214,9 +205,83 @@ Closure as the default value:: .. caution:: - The first argument of the Closure must be typehinted as ``Options``, + The first argument of the closure must be typehinted as ``Options``, otherwise it is considered as the value. +Overwriting Default Values +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A previously set default value can be overwritten by invoking +:method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setDefaults` +again. When using a closure as the new value it is passed 2 arguments: + + * ``$options``: an :class:`Symfony\\Component\\OptionsResolver\\Options` + instance with all the other default options + * ``$previousValue``: the previous set default value + +.. code-block:: php + + use Symfony\Component\OptionsResolver\Options; + use Symfony\Component\OptionsResolver\OptionsResolverInterface; + + // ... + protected function setDefaultOptions(OptionsResolverInterface $resolver) + { + // ... + $resolver->setDefaults(array( + 'encryption' => 'ssl', + 'host' => 'localhost', + )); + + // ... + $resolver->setDefaults(array( + 'encryption' => 'tls', // simple overwrite + 'host' => function (Options $options, $previousValue) { + return 'localhost' == $previousValue ? '127.0.0.1' : $previousValue; + }, + )); + } + +.. tip:: + + If the previous default value is calculated by an expensive closure and + you don't need access to it, you can use the + :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::replaceDefaults` + method instead. It acts like ``setDefaults`` but simply erases the + previous value to improve performance. This means that the previous + default value is not available when overwriting with another closure:: + + use Symfony\Component\OptionsResolver\Options; + use Symfony\Component\OptionsResolver\OptionsResolverInterface; + + // ... + protected function setDefaultOptions(OptionsResolverInterface $resolver) + { + // ... + $resolver->setDefaults(array( + 'encryption' => 'ssl', + 'heavy' => function (Options $options) { + // Some heavy calculations to create the $result + + return $result; + }, + )); + + $resolver->replaceDefaults(array( + 'encryption' => 'tls', // simple overwrite + 'heavy' => function (Options $options) { + // $previousValue not available + // ... + + return $someOtherResult; + }, + )); + } + +.. note:: + + Existing option keys that you do not mention when overwriting are preserved. + Configure allowed Values ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -270,7 +335,7 @@ Normalize the Options Some values need to be normalized before you can use them. For instance, pretend that the ``host`` should always start with ``http://``. To do that, -you can write normalizers. These Closures will be executed after all options +you can write normalizers. These closures will be executed after all options are passed and should return the normalized value. You can configure these normalizers by calling :method:`Symfony\\Components\\OptionsResolver\\OptionsResolver::setNormalizers`:: From e91802f626c33cdbfbda262f7782de5f8e710e98 Mon Sep 17 00:00:00 2001 From: Philipp Rieber Date: Tue, 3 Dec 2013 10:36:23 +0100 Subject: [PATCH 2/2] Fix wrong list indentation --- components/options_resolver.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/options_resolver.rst b/components/options_resolver.rst index e6f9d64bac6..9a62f8581fa 100644 --- a/components/options_resolver.rst +++ b/components/options_resolver.rst @@ -215,9 +215,9 @@ A previously set default value can be overwritten by invoking :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setDefaults` again. When using a closure as the new value it is passed 2 arguments: - * ``$options``: an :class:`Symfony\\Component\\OptionsResolver\\Options` - instance with all the other default options - * ``$previousValue``: the previous set default value +* ``$options``: an :class:`Symfony\\Component\\OptionsResolver\\Options` + instance with all the other default options +* ``$previousValue``: the previous set default value .. code-block:: php