summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Scheller <igor.scheller@igorshp.de>2019-07-16 01:39:54 +0200
committerIgor Scheller <igor.scheller@igorshp.de>2019-07-16 01:39:54 +0200
commitb25924e868cdf80944e56a76fa6eed4509d9af7b (patch)
tree598dbd84af3610aaf02cab44994eaa9a0c9b7c10
parent6743106d9a8c760580690aab704f908766731801 (diff)
Allow nested rules (not and optional)
-rw-r--r--src/Http/Validation/Validator.php27
-rw-r--r--tests/Unit/Http/Validation/ValidatorTest.php64
2 files changed, 88 insertions, 3 deletions
diff --git a/src/Http/Validation/Validator.php b/src/Http/Validation/Validator.php
index 0bd846bd..976f5682 100644
--- a/src/Http/Validation/Validator.php
+++ b/src/Http/Validation/Validator.php
@@ -22,6 +22,9 @@ class Validator
'required' => 'NotEmpty',
];
+ /** @var array */
+ protected $nestedRules = ['optional', 'not'];
+
/**
* @param array $data
* @param array $rules
@@ -37,20 +40,38 @@ class Validator
$v->with('\\Engelsystem\\Http\\Validation\\Rules', true);
$value = isset($data[$key]) ? $data[$key] : null;
+ $values = explode('|', $values);
+
+ $packing = [];
+ foreach ($this->nestedRules as $rule) {
+ if (in_array($rule, $values)) {
+ $packing[] = $rule;
+ }
+ }
- foreach (explode('|', $values) as $parameters) {
+ $values = array_diff($values, $this->nestedRules);
+ foreach ($values as $parameters) {
$parameters = explode(':', $parameters);
$rule = array_shift($parameters);
$rule = Str::camel($rule);
$rule = $this->map($rule);
+ // To allow rules nesting
+ $w = $v;
try {
- call_user_func_array([$v, $rule], $parameters);
+ foreach (array_reverse(array_merge($packing, [$rule])) as $rule) {
+ if (!in_array($rule, $this->nestedRules)) {
+ call_user_func_array([$w, $rule], $parameters);
+ continue;
+ }
+
+ $w = call_user_func_array([new RespectValidator(), $rule], [$w]);
+ }
} catch (ComponentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
- if ($v->validate($value)) {
+ if ($w->validate($value)) {
$this->data[$key] = $value;
} else {
$this->errors[$key][] = implode('.', ['validation', $key, $this->mapBack($rule)]);
diff --git a/tests/Unit/Http/Validation/ValidatorTest.php b/tests/Unit/Http/Validation/ValidatorTest.php
index 0790b7a8..450e5d4e 100644
--- a/tests/Unit/Http/Validation/ValidatorTest.php
+++ b/tests/Unit/Http/Validation/ValidatorTest.php
@@ -16,6 +16,7 @@ class ValidatorTest extends TestCase
public function testValidate()
{
$val = new Validator();
+
$this->assertTrue($val->validate(
['foo' => 'bar', 'lorem' => 'on', 'dolor' => 'bla'],
['lorem' => 'accepted']
@@ -35,9 +36,36 @@ class ValidatorTest extends TestCase
/**
* @covers \Engelsystem\Http\Validation\Validator::validate
*/
+ public function testValidateChaining()
+ {
+ $val = new Validator();
+
+ $this->assertTrue($val->validate(
+ ['lorem' => 10],
+ ['lorem' => 'required|min:3|max:10']
+ ));
+ $this->assertTrue($val->validate(
+ ['lorem' => 3],
+ ['lorem' => 'required|min:3|max:10']
+ ));
+
+ $this->assertFalse($val->validate(
+ ['lorem' => 2],
+ ['lorem' => 'required|min:3|max:10']
+ ));
+ $this->assertFalse($val->validate(
+ ['lorem' => 42],
+ ['lorem' => 'required|min:3|max:10']
+ ));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Validation\Validator::validate
+ */
public function testValidateNotImplemented()
{
$val = new Validator();
+
$this->expectException(InvalidArgumentException::class);
$val->validate(
@@ -53,6 +81,7 @@ class ValidatorTest extends TestCase
public function testValidateMapping()
{
$val = new Validator();
+
$this->assertTrue($val->validate(
['foo' => 'bar'],
['foo' => 'required']
@@ -75,4 +104,39 @@ class ValidatorTest extends TestCase
$val->getErrors()
);
}
+
+ /**
+ * @covers \Engelsystem\Http\Validation\Validator::validate
+ */
+ public function testValidateNesting()
+ {
+ $val = new Validator();
+
+ $this->assertTrue($val->validate(
+ [],
+ ['foo' => 'not|required']
+ ));
+
+ $this->assertTrue($val->validate(
+ ['foo' => 'foo'],
+ ['foo' => 'not|int']
+ ));
+ $this->assertFalse($val->validate(
+ ['foo' => 1],
+ ['foo' => 'not|int']
+ ));
+
+ $this->assertTrue($val->validate(
+ [],
+ ['foo' => 'optional|int']
+ ));
+ $this->assertTrue($val->validate(
+ ['foo' => '33'],
+ ['foo' => 'optional|int']
+ ));
+ $this->assertFalse($val->validate(
+ ['foo' => 'T'],
+ ['foo' => 'optional|int']
+ ));
+ }
}