[OptionsResolver] Added method setFilters() for augmenting the final option values

This commit is contained in:
Bernhard Schussek 2012-05-23 15:59:31 +02:00
parent 45849ce306
commit 0af5f06703
2 changed files with 86 additions and 11 deletions

View File

@ -47,6 +47,12 @@ class OptionsResolver
*/
private $allowedValues = array();
/**
* A list of filters transforming each resolved options.
* @var array
*/
private $filters = array();
/**
* Creates a new instance.
*/
@ -58,12 +64,23 @@ class OptionsResolver
/**
* Sets default option values.
*
* @param array $defaultValues A list of option names as keys and default values
* as values. The option values may be closures
* of the following signatures:
* The options can either be values of any types or closures that
* evaluate the option value lazily. These closures must have one
* of the following signatures:
*
* - function (Options $options)
* - function (Options $options, $previousValue)
* <code>
* function (Options $options)
* function (Options $options, $value)
* </code>
*
* The second parameter passed to the closure is the previously
* set default value, in case you are overwriting an existing
* default value.
*
* The closures should return the lazily created option value.
*
* @param array $defaultValues A list of option names as keys and default
* values or closures as values.
*
* @return OptionsResolver The resolver instance.
*/
@ -81,16 +98,13 @@ class OptionsResolver
/**
* Replaces default option values.
*
* Old defaults are erased, which means that closures passed here can't
* Old defaults are erased, which means that closures passed here cannot
* access the previous default value. This may be useful to improve
* performance if the previous default value is calculated by an expensive
* closure.
*
* @param array $defaultValues A list of option names as keys and default values
* as values. The option values may be closures
* of the following signature:
*
* - function (Options $options)
* @param array $defaultValues A list of option names as keys and default
* values or closures as values.
*
* @return OptionsResolver The resolver instance.
*/
@ -208,6 +222,32 @@ class OptionsResolver
return $this;
}
/**
* Sets filters that are applied on resolved options.
*
* The filters should be closures with the following signature:
*
* <code>
* function (Options $options, $value)
* </code>
*
* The second parameter passed to the closure is the value of
* the option.
*
* The closure should return the filtered value.
*
* @param array $filters
* @return OptionsResolver
*/
public function setFilters(array $filters)
{
$this->validateOptionsExistence($filters);
$this->filters = array_replace($this->filters, $filters);
return $this;
}
/**
* Returns whether an option is known.
*
@ -264,6 +304,11 @@ class OptionsResolver
$combinedOptions->set($option, $value);
}
// Apply filters
foreach ($this->filters as $option => $filter) {
$combinedOptions->overload($option, $filter);
}
// Resolve options
$resolvedOptions = $combinedOptions->all();

View File

@ -373,6 +373,36 @@ class OptionsResolverTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($this->resolver->isRequired('foo'));
}
public function testFiltersTransformFinalOptions()
{
$this->resolver->setDefaults(array(
'foo' => 'bar',
'bam' => 'baz',
));
$this->resolver->setFilters(array(
'foo' => function (Options $options, $value) {
return $options['bam'] . '[' . $value . ']';
},
));
$expected = array(
'foo' => 'baz[bar]',
'bam' => 'baz',
);
$this->assertEquals($expected, $this->resolver->resolve(array()));
$expected = array(
'foo' => 'boo[custom]',
'bam' => 'boo',
);
$this->assertEquals($expected, $this->resolver->resolve(array(
'foo' => 'custom',
'bam' => 'boo',
)));
}
public function testResolveWithoutOptionSucceedsIfRequiredAndDefaultValue()
{
$this->resolver->setRequired(array(