Skip to content

Commit

Permalink
feature #8375 [OptionsResolver] Allow giving a callback as an allowed…
Browse files Browse the repository at this point in the history
…Value to OptionsResolver (marekkalnik)

This PR was merged into the 2.5-dev branch.

Discussion
----------

[OptionsResolver] Allow giving a callback as an allowedValue to OptionsResolver

I recently had to use an option which was an array and could contain some one or multiple values from a list. As it could contain all possible combinations, it was not possible to validate it with a list of allowed values.

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | --
| License       | MIT
| Doc PR        | symfony/symfony-docs#3437

Commits
-------

07d1d30 Allow giving a callback as an allowedValue to OptionsResolver
  • Loading branch information
fabpot committed Jan 7, 2014
2 parents 6f6554d + 2c08f1b commit 005edcf
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
10 changes: 8 additions & 2 deletions OptionsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,14 @@ private function validateOptionsCompleteness(array $options)
private function validateOptionValues(array $options)
{
foreach ($this->allowedValues as $option => $allowedValues) {
if (isset($options[$option]) && !in_array($options[$option], $allowedValues, true)) {
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", but is expected to be one of "%s"', $option, $options[$option], implode('", "', $allowedValues)));
if (isset($options[$option])) {
if (is_array($allowedValues) && !in_array($options[$option], $allowedValues, true)) {
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", but is expected to be one of "%s"', $option, $options[$option], implode('", "', $allowedValues)));
}

if (is_callable($allowedValues) && !call_user_func($allowedValues, $options[$option])) {
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", which it is not valid', $option, $options[$option]));
}
}
}
}
Expand Down
39 changes: 39 additions & 0 deletions Tests/OptionsResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,45 @@ public function testResolveSucceedsIfOptionRequiredAndValueAllowed()
$this->assertEquals($options, $this->resolver->resolve($options));
}

public function testResolveSucceedsIfValueAllowedCallbackReturnsTrue()
{
$this->resolver->setRequired(array(
'test',
));
$this->resolver->setAllowedValues(array(
'test' => function ($value) {
return true;
},
));

$options = array(
'test' => true,
);

$this->assertEquals($options, $this->resolver->resolve($options));
}

/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
*/
public function testResolveFailsIfValueAllowedCallbackReturnsFalse()
{
$this->resolver->setRequired(array(
'test',
));
$this->resolver->setAllowedValues(array(
'test' => function ($value) {
return false;
},
));

$options = array(
'test' => true,
);

$this->assertEquals($options, $this->resolver->resolve($options));
}

public function testClone()
{
$this->resolver->setDefaults(array('one' => '1'));
Expand Down

0 comments on commit 005edcf

Please sign in to comment.