From a6be7e2dd00ac752611d99ab74b48d1c1cc24058 Mon Sep 17 00:00:00 2001 From: Matteo Kloiber Date: Sun, 6 Nov 2016 01:40:05 +0100 Subject: [PATCH] Validator::rule now accepts any kind of callback This has been achieved by making sure that the rule is neither a "native" Validator rule (e.g. there is a validate{$CamleCaseName} method) nor it has been registered. If both conditions are met, the rule (even if it is a string) will be accepted and used. Tests for this case have also been added. --- src/Valitron/Validator.php | 22 ++++++++++++++----- .../Valitron/ValidateAddInstanceRuleTest.php | 19 ++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index 20dc88e..4a1a49a 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -1066,6 +1066,20 @@ class Validator return $name; } + /** + * Returns true if either a valdiator with the given name has been + * registered or there is a default validator by that name. + * + * @param string $name + * @return bool + */ + public function hasValidator($name) + { + $rules = $this->getRules(); + return method_exists($this, "validate" . ucfirst($name)) + || isset($rules[$name]); + } + /** * Convenience method to add a single validation rule * @@ -1079,12 +1093,8 @@ class Validator // Get any other arguments passed to function $params = array_slice(func_get_args(), 2); - // Note: we cannot use is_callable here since max, int, and many - // other string can also be callables but aren't really rule callbacks. - // - // If a closure is used, we can be sure that the user actually - // wants $rule to be a custom rule check. - if (is_object($rule) && ($rule instanceof \Closure)) + if (is_callable($rule) + && !(is_string($rule) && $this->hasValidator($rule))) { $name = $this->getUniqueRuleName($fields); $msg = isset($params[0]) ? $params[0] : null; diff --git a/tests/Valitron/ValidateAddInstanceRuleTest.php b/tests/Valitron/ValidateAddInstanceRuleTest.php index cc10d0b..ddefac3 100644 --- a/tests/Valitron/ValidateAddInstanceRuleTest.php +++ b/tests/Valitron/ValidateAddInstanceRuleTest.php @@ -1,6 +1,11 @@ assertEquals("Foo test error message", $errors["foo"][0]); } + public function testAddRuleWithNamedCallbackOk() + { + $v = new Validator(array("bar" => "foo")); + $v->rule("callbackTestFunction", "bar"); + $this->assertFalse($v->validate()); + } + + public function testAddRuleWithNamedCallbackErr() + { + $v = new Validator(array("foo" => "bar")); + $v->rule("callbackTestFunction", "foo"); + $this->assertTrue($v->validate()); + } + public function testUniqueRuleName() { $v = new Validator(array());