Skip to content

Commit 07d1d30

Browse files
committed
Allow giving a callback as an allowedValue to OptionsResolver
1 parent fae3e35 commit 07d1d30

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/Symfony/Component/OptionsResolver/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
}

src/Symfony/Component/OptionsResolver/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)