Skip to content

Commit 005edcf

Browse files
committed
feature #8375 [OptionsResolver] Allow giving a callback as an allowedValue 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
2 parents 6f6554d + 2c08f1b commit 005edcf

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

OptionsResolver.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,14 @@ private function validateOptionsCompleteness(array $options)
294294
private function validateOptionValues(array $options)
295295
{
296296
foreach ($this->allowedValues as $option => $allowedValues) {
297-
if (isset($options[$option]) && !in_array($options[$option], $allowedValues, true)) {
298-
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", but is expected to be one of "%s"', $option, $options[$option], implode('", "', $allowedValues)));
297+
if (isset($options[$option])) {
298+
if (is_array($allowedValues) && !in_array($options[$option], $allowedValues, true)) {
299+
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", but is expected to be one of "%s"', $option, $options[$option], implode('", "', $allowedValues)));
300+
}
301+
302+
if (is_callable($allowedValues) && !call_user_func($allowedValues, $options[$option])) {
303+
throw new InvalidOptionsException(sprintf('The option "%s" has the value "%s", which it is not valid', $option, $options[$option]));
304+
}
299305
}
300306
}
301307
}

Tests/OptionsResolverTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,45 @@ public function testResolveSucceedsIfOptionRequiredAndValueAllowed()
658658
$this->assertEquals($options, $this->resolver->resolve($options));
659659
}
660660

661+
public function testResolveSucceedsIfValueAllowedCallbackReturnsTrue()
662+
{
663+
$this->resolver->setRequired(array(
664+
'test',
665+
));
666+
$this->resolver->setAllowedValues(array(
667+
'test' => function ($value) {
668+
return true;
669+
},
670+
));
671+
672+
$options = array(
673+
'test' => true,
674+
);
675+
676+
$this->assertEquals($options, $this->resolver->resolve($options));
677+
}
678+
679+
/**
680+
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
681+
*/
682+
public function testResolveFailsIfValueAllowedCallbackReturnsFalse()
683+
{
684+
$this->resolver->setRequired(array(
685+
'test',
686+
));
687+
$this->resolver->setAllowedValues(array(
688+
'test' => function ($value) {
689+
return false;
690+
},
691+
));
692+
693+
$options = array(
694+
'test' => true,
695+
);
696+
697+
$this->assertEquals($options, $this->resolver->resolve($options));
698+
}
699+
661700
public function testClone()
662701
{
663702
$this->resolver->setDefaults(array('one' => '1'));

0 commit comments

Comments
 (0)