From 07d1d3074e9cd971de3cbd2a04c09193e6348d6e Mon Sep 17 00:00:00 2001 From: Marek Kalnik Date: Fri, 28 Jun 2013 01:36:53 +0200 Subject: [PATCH] Allow giving a callback as an allowedValue to OptionsResolver --- .../OptionsResolver/OptionsResolver.php | 10 ++++- .../Tests/OptionsResolverTest.php | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 86a1f7a07092..ec1989dc3062 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -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])); + } } } } diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php index 2fae3575014d..9d6f7c024881 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php @@ -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'));