diff --git a/JBBCode/CodeDefinitionBuilder.php b/JBBCode/CodeDefinitionBuilder.php index cf5c1bb..bec8983 100644 --- a/JBBCode/CodeDefinitionBuilder.php +++ b/JBBCode/CodeDefinitionBuilder.php @@ -3,12 +3,14 @@ namespace JBBCode; require_once "CodeDefinition.php"; +require_once "validators/CallableValidatorAdapter.php"; /** * Implements the builder pattern for the CodeDefinition class. A builder * is the recommended way of constructing CodeDefinition objects. * * @author jbowens + * @author Kubo2 */ class CodeDefinitionBuilder { @@ -111,14 +113,15 @@ public function setNestLimit($limit) /** * Sets the InputValidator that option arguments should be validated with. * - * @param InputValidator $validator the InputValidator instance to use + * @param InputValidator|callable $validator the validator to use when validating input * @return self */ - public function setOptionValidator(InputValidator $validator, $option=null) + public function setOptionValidator($validator, $option=null) { if(empty($option)){ $option = $this->tagName; } + $validator = $this->checkInputValidator($validator); $this->optionValidator[$option] = $validator; return $this; } @@ -126,11 +129,12 @@ public function setOptionValidator(InputValidator $validator, $option=null) /** * Sets the InputValidator that body ({param}) text should be validated with. * - * @param InputValidator $validator the InputValidator instance to use + * @param InputValidator|callable $validator the validator to use when validating input * @return self */ - public function setBodyValidator(InputValidator $validator) + public function setBodyValidator($validator) { + $validator = $this->checkInputValidator($validator); $this->bodyValidator = $validator; return $this; } @@ -158,6 +162,26 @@ public function removeBodyValidator() return $this; } + /** + * Checks if `$validator` is a valid input validator, otherwise throws an exception + * + * @internal + * @return InputValidator + * @throws \InvalidArgumentException + */ + private function checkInputValidator($validator) { + if($validator instanceof InputValidator) { + return $validator; + } elseif(is_callable($validator)) { + return new validators\CallableValidatorAdapter($validator); + } else { + throw new \InvalidArgumentException( + '$validator must be either of type callable, or an instance of JBBCode\InputValidator, ' . + (is_object($validator) ? get_class($validator) : gettype($validator)) . ' given' + ); + } + } + /** * Builds a CodeDefinition with the current state of the builder. * diff --git a/JBBCode/InputValidator.php b/JBBCode/InputValidator.php index 6320b87..196d4bb 100644 --- a/JBBCode/InputValidator.php +++ b/JBBCode/InputValidator.php @@ -13,7 +13,7 @@ interface InputValidator { /** - * Returns true iff the given input is valid, false otherwise. + * Returns true if the given input is valid, false otherwise. * @param string $input * @return boolean */ diff --git a/JBBCode/tests/ValidatorTest.php b/JBBCode/tests/ValidatorTest.php index e7dacb0..52b9cbd 100644 --- a/JBBCode/tests/ValidatorTest.php +++ b/JBBCode/tests/ValidatorTest.php @@ -1,13 +1,15 @@ getAsHtml()); } + /** + * Test functionality of {@link JBBCode\CallableValidatorAdapter} + */ + public function testCallableValidatorAdapter() { + $emptyValidator = new \JBBCode\validators\CallableValidatorAdapter(function($input) { + return empty($input); + }); + $this->assertTrue($emptyValidator->validate('')); + $this->assertFalse($emptyValidator->validate('Hey! I am here')); + } + } diff --git a/JBBCode/validators/CallableValidatorAdapter.php b/JBBCode/validators/CallableValidatorAdapter.php new file mode 100644 index 0000000..bff5fcd --- /dev/null +++ b/JBBCode/validators/CallableValidatorAdapter.php @@ -0,0 +1,40 @@ +validator = $validator; + } + + /** + * {@inheritdoc} + * @return boolean Anything returned by the callable validator, coerced to boolean + */ + public function validate($input) { + return (boolean) call_user_func($this->validator, $input); + } +}