summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Scheller <igor.scheller@igorshp.de>2019-07-10 13:34:15 +0200
committerIgor Scheller <igor.scheller@igorshp.de>2019-07-10 13:34:15 +0200
commit6743106d9a8c760580690aab704f908766731801 (patch)
tree36dd2333d4148cb593e9f7fb3790740605cd1f12
parent6d5ada252202bfb29eba884cf9567e969d798607 (diff)
Replaced validation with `respect/validation`
-rw-r--r--composer.json1
-rw-r--r--src/Http/Validation/Rules/In.php21
-rw-r--r--src/Http/Validation/Rules/NotIn.php15
-rw-r--r--src/Http/Validation/Validates.php154
-rw-r--r--src/Http/Validation/ValidationServiceProvider.php3
-rw-r--r--src/Http/Validation/Validator.php61
-rw-r--r--tests/Unit/Controllers/AuthControllerTest.php3
-rw-r--r--tests/Unit/Http/Validation/Rules/InTest.php19
-rw-r--r--tests/Unit/Http/Validation/Rules/NotInTest.php20
-rw-r--r--tests/Unit/Http/Validation/ValidatesTest.php308
-rw-r--r--tests/Unit/Http/Validation/ValidatorTest.php42
11 files changed, 155 insertions, 492 deletions
diff --git a/composer.json b/composer.json
index b2b70789..a1f2101b 100644
--- a/composer.json
+++ b/composer.json
@@ -32,6 +32,7 @@
"psr/container": "^1.0",
"psr/http-server-middleware": "^1.0",
"psr/log": "^1.1",
+ "respect/validation": "^1.1",
"swiftmailer/swiftmailer": "^6.2",
"symfony/http-foundation": "^4.3",
"symfony/psr-http-message-bridge": "^1.2",
diff --git a/src/Http/Validation/Rules/In.php b/src/Http/Validation/Rules/In.php
new file mode 100644
index 00000000..d585cc3d
--- /dev/null
+++ b/src/Http/Validation/Rules/In.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Engelsystem\Http\Validation\Rules;
+
+use Respect\Validation\Rules\In as RespectIn;
+
+class In extends RespectIn
+{
+ /**
+ * @param mixed $haystack
+ * @param bool $compareIdentical
+ */
+ public function __construct($haystack, $compareIdentical = false)
+ {
+ if (!is_array($haystack)) {
+ $haystack = explode(',', $haystack);
+ }
+
+ parent::__construct($haystack, $compareIdentical);
+ }
+}
diff --git a/src/Http/Validation/Rules/NotIn.php b/src/Http/Validation/Rules/NotIn.php
new file mode 100644
index 00000000..7f223c42
--- /dev/null
+++ b/src/Http/Validation/Rules/NotIn.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Engelsystem\Http\Validation\Rules;
+
+class NotIn extends In
+{
+ /**
+ * @param mixed $input
+ * @return bool
+ */
+ public function validate($input)
+ {
+ return !parent::validate($input);
+ }
+}
diff --git a/src/Http/Validation/Validates.php b/src/Http/Validation/Validates.php
deleted file mode 100644
index 2e3a1a73..00000000
--- a/src/Http/Validation/Validates.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-
-namespace Engelsystem\Http\Validation;
-
-use InvalidArgumentException;
-
-class Validates
-{
- /**
- * @param mixed $value
- * @return bool
- */
- public function accepted($value): bool
- {
- return in_array($value, ['true', '1', 'y', 'yes', 'on', 1, true], true);
- }
-
- /**
- * @param string $value
- * @param array $parameters ['min', 'max']
- * @return bool
- */
- public function between($value, $parameters): bool
- {
- $this->validateParameterCount(2, $parameters, __FUNCTION__);
- $size = $this->getSize($value);
-
- return $size >= $parameters[0] && $size <= $parameters[1];
- }
-
- /**
- * @param mixed $value
- * @return bool
- */
- public function bool($value): bool
- {
- return in_array($value, ['1', 1, true, '0', 0, false], true);
- }
-
- /**
- * @param mixed $value
- * @param array $parameters ['1,2,3,56,7']
- * @return bool
- */
- public function in($value, $parameters): bool
- {
- $this->validateParameterCount(1, $parameters, __FUNCTION__);
-
- return in_array($value, explode(',', $parameters[0]));
- }
-
- /**
- * @param mixed $value
- * @return bool
- */
- public function int($value): bool
- {
- return filter_var($value, FILTER_VALIDATE_INT) !== false;
- }
-
- /**
- * @param string $value
- * @param array $parameters ['max']
- * @return bool
- */
- public function max($value, $parameters): bool
- {
- $this->validateParameterCount(1, $parameters, __FUNCTION__);
- $size = $this->getSize($value);
-
- return $size <= $parameters[0];
- }
-
- /**
- * @param string $value
- * @param array $parameters ['min']
- * @return bool
- */
- public function min($value, $parameters)
- {
- $this->validateParameterCount(1, $parameters, __FUNCTION__);
- $size = $this->getSize($value);
-
- return $size >= $parameters[0];
- }
-
- /**
- * @param mixed $value
- * @param array $parameters ['1,2,3,56,7']
- * @return bool
- */
- public function notIn($value, $parameters): bool
- {
- $this->validateParameterCount(1, $parameters, __FUNCTION__);
-
- return !$this->in($value, $parameters);
- }
-
- /**
- * @param mixed $value
- * @return bool
- */
- public function numeric($value): bool
- {
- return is_numeric($value);
- }
-
- /**
- * @param mixed $value
- * @return bool
- */
- public function required($value): bool
- {
- if (
- is_null($value)
- || (is_string($value) && trim($value) === '')
- ) {
- return false;
- }
-
- return true;
- }
-
- /**
- * @param mixed $value
- * @return int|float
- */
- protected function getSize($value)
- {
- if (is_numeric($value)) {
- return $value;
- }
-
- return mb_strlen($value);
- }
-
- /**
- * @param int $count
- * @param array $parameters
- * @param string $rule
- *
- * @throws InvalidArgumentException
- */
- protected function validateParameterCount(int $count, array $parameters, string $rule)
- {
- if (count($parameters) < $count) {
- throw new InvalidArgumentException(sprintf(
- 'The rule "%s" requires at least %d parameters',
- $rule,
- $count
- ));
- }
- }
-}
diff --git a/src/Http/Validation/ValidationServiceProvider.php b/src/Http/Validation/ValidationServiceProvider.php
index 2f1c6359..14530ae6 100644
--- a/src/Http/Validation/ValidationServiceProvider.php
+++ b/src/Http/Validation/ValidationServiceProvider.php
@@ -10,9 +10,6 @@ class ValidationServiceProvider extends ServiceProvider
{
public function register()
{
- $validates = $this->app->make(Validates::class);
- $this->app->instance(Validates::class, $validates);
-
$validator = $this->app->make(Validator::class);
$this->app->instance(Validator::class, $validator);
$this->app->instance('validator', $validator);
diff --git a/src/Http/Validation/Validator.php b/src/Http/Validation/Validator.php
index a9235a5f..0bd846bd 100644
--- a/src/Http/Validation/Validator.php
+++ b/src/Http/Validation/Validator.php
@@ -4,25 +4,23 @@ namespace Engelsystem\Http\Validation;
use Illuminate\Support\Str;
use InvalidArgumentException;
+use Respect\Validation\Exceptions\ComponentException;
+use Respect\Validation\Validator as RespectValidator;
class Validator
{
- /** @var Validates */
- protected $validate;
-
/** @var string[] */
protected $errors = [];
/** @var array */
protected $data = [];
- /**
- * @param Validates $validate
- */
- public function __construct(Validates $validate)
- {
- $this->validate = $validate;
- }
+ /** @var array */
+ protected $mapping = [
+ 'accepted' => 'TrueVal',
+ 'int' => 'IntVal',
+ 'required' => 'NotEmpty',
+ ];
/**
* @param array $data
@@ -35,23 +33,30 @@ class Validator
$this->data = [];
foreach ($rules as $key => $values) {
+ $v = new RespectValidator();
+ $v->with('\\Engelsystem\\Http\\Validation\\Rules', true);
+
+ $value = isset($data[$key]) ? $data[$key] : null;
+
foreach (explode('|', $values) as $parameters) {
$parameters = explode(':', $parameters);
$rule = array_shift($parameters);
$rule = Str::camel($rule);
+ $rule = $this->map($rule);
- if (!method_exists($this->validate, $rule)) {
- throw new InvalidArgumentException('Unknown validation rule: ' . $rule);
+ try {
+ call_user_func_array([$v, $rule], $parameters);
+ } catch (ComponentException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
- $value = isset($data[$key]) ? $data[$key] : null;
- if (!$this->validate->{$rule}($value, $parameters, $data)) {
- $this->errors[$key][] = implode('.', ['validation', $key, $rule]);
-
- continue;
+ if ($v->validate($value)) {
+ $this->data[$key] = $value;
+ } else {
+ $this->errors[$key][] = implode('.', ['validation', $key, $this->mapBack($rule)]);
}
- $this->data[$key] = $value;
+ $v->removeRules();
}
}
@@ -59,6 +64,26 @@ class Validator
}
/**
+ * @param string $rule
+ * @return string
+ */
+ protected function map($rule)
+ {
+ return $this->mapping[$rule] ?? $rule;
+ }
+
+ /**
+ * @param string $rule
+ * @return string
+ */
+ protected function mapBack($rule)
+ {
+ $mapping = array_flip($this->mapping);
+
+ return $mapping[$rule] ?? $rule;
+ }
+
+ /**
* @return array
*/
public function getData(): array
diff --git a/tests/Unit/Controllers/AuthControllerTest.php b/tests/Unit/Controllers/AuthControllerTest.php
index d3dbfa4b..c3d9659c 100644
--- a/tests/Unit/Controllers/AuthControllerTest.php
+++ b/tests/Unit/Controllers/AuthControllerTest.php
@@ -8,7 +8,6 @@ use Engelsystem\Http\Exceptions\ValidationException;
use Engelsystem\Http\Request;
use Engelsystem\Http\Response;
use Engelsystem\Http\UrlGeneratorInterface;
-use Engelsystem\Http\Validation\Validates;
use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\User\Settings;
use Engelsystem\Models\User\User;
@@ -66,7 +65,7 @@ class AuthControllerTest extends TestCase
list(, , $url, $auth) = $this->getMocks();
$session = new Session(new MockArraySessionStorage());
/** @var Validator|MockObject $validator */
- $validator = new Validator(new Validates());
+ $validator = new Validator();
$user = new User([
'name' => 'foo',
diff --git a/tests/Unit/Http/Validation/Rules/InTest.php b/tests/Unit/Http/Validation/Rules/InTest.php
new file mode 100644
index 00000000..e5688d90
--- /dev/null
+++ b/tests/Unit/Http/Validation/Rules/InTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http\Validation\Rules;
+
+use Engelsystem\Http\Validation\Rules\In;
+use Engelsystem\Test\Unit\TestCase;
+
+class InTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Http\Validation\Rules\In::__construct
+ */
+ public function testConstruct()
+ {
+ $rule = new In('foo,bar');
+
+ $this->assertEquals(['foo', 'bar'], $rule->haystack);
+ }
+}
diff --git a/tests/Unit/Http/Validation/Rules/NotInTest.php b/tests/Unit/Http/Validation/Rules/NotInTest.php
new file mode 100644
index 00000000..9be12336
--- /dev/null
+++ b/tests/Unit/Http/Validation/Rules/NotInTest.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http\Validation\Rules;
+
+use Engelsystem\Http\Validation\Rules\NotIn;
+use Engelsystem\Test\Unit\TestCase;
+
+class NotInTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Http\Validation\Rules\NotIn::validate
+ */
+ public function testConstruct()
+ {
+ $rule = new NotIn('foo,bar');
+
+ $this->assertTrue($rule->validate('lorem'));
+ $this->assertFalse($rule->validate('foo'));
+ }
+}
diff --git a/tests/Unit/Http/Validation/ValidatesTest.php b/tests/Unit/Http/Validation/ValidatesTest.php
deleted file mode 100644
index 5cf0447a..00000000
--- a/tests/Unit/Http/Validation/ValidatesTest.php
+++ /dev/null
@@ -1,308 +0,0 @@
-<?php
-
-namespace Engelsystem\Test\Unit\Http\Validation;
-
-use Engelsystem\Http\Validation\Validates;
-use InvalidArgumentException;
-use PHPUnit\Framework\TestCase;
-
-class ValidatesTest extends TestCase
-{
- /**
- * @return array
- */
- public function provideAccepted()
- {
- return [
- ['true'],
- ['1'],
- ['y'],
- ['yes'],
- ['on'],
- ['1test', false],
- ['false', false],
- ['no', false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::accepted
- * @param mixed $value
- * @param bool $result
- * @dataProvider provideAccepted
- */
- public function testAccepted($value, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->accepted($value) === $result);
- }
-
- /**
- * @return array
- */
- public function provideBetween()
- {
- return [
- ['42', [10, 100]],
- [42.5, [42, 43]],
- [42, [42, 1000]],
- [1337, [0, 99], false],
- [-17, [32, 45], false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::between
- * @param mixed $value
- * @param array $parameters
- * @param bool $result
- * @dataProvider provideBetween
- */
- public function testBetween($value, array $parameters, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->between($value, $parameters) === $result);
- }
-
- /**
- * @return array
- */
- public function provideBool()
- {
- return [
- ['1'],
- [1],
- [true],
- ['0'],
- [0],
- [false],
- ['true', false],
- ['false', false],
- ['yes', false],
- ['no', false],
- ['bool', false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::bool
- * @param mixed $value
- * @param bool $result
- * @dataProvider provideBool
- */
- public function testBool($value, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->bool($value) === $result);
- }
-
- /**
- * @return array
- */
- public function provideIn()
- {
- return [
- ['lorem', ['lorem,ipsum,dolor']],
- [99, ['66,77,88,99,111']],
- [4, ['1,3,5,7'], false],
- ['toggle', ['on,off'], false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::in
- * @param mixed $value
- * @param array $parameters
- * @param bool $result
- * @dataProvider provideIn
- */
- public function testIn($value, array $parameters, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->in($value, $parameters) === $result);
- }
-
- /**
- * @return array
- */
- public function provideInt()
- {
- return [
- ['1337'],
- [42],
- ['0'],
- [false, false],
- ['12asd1', false],
- ['one', false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::int
- * @param mixed $value
- * @param bool $result
- * @dataProvider provideInt
- */
- public function testInt($value, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->int($value) === $result);
- }
-
- /**
- * @return array
- */
- public function provideMax()
- {
- return [
- ['99', [100]],
- [-42, [1024]],
- [99, [99]],
- [100, [10], false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::max
- * @param mixed $value
- * @param array $parameters
- * @param bool $result
- * @dataProvider provideMax
- */
- public function testMax($value, array $parameters, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->max($value, $parameters) === $result);
- }
-
- /**
- * @return array
- */
- public function provideMin()
- {
- return [
- [32, [0]],
- [7, [7]],
- ['99', [10]],
- [3, [42], false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::min
- * @param mixed $value
- * @param array $parameters
- * @param bool $result
- * @dataProvider provideMin
- */
- public function testMin($value, array $parameters, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->min($value, $parameters) === $result);
- }
-
- /**
- * @return array
- */
- public function provideNotIn()
- {
- return [
- [77, ['50,60,70']],
- ['test', ['coding,deployment']],
- ['PHP', ['Java,PHP,bash'], false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::notIn
- * @param mixed $value
- * @param array $parameters
- * @param bool $result
- * @dataProvider provideNotIn
- */
- public function testNotIn($value, array $parameters, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->notIn($value, $parameters) === $result);
- }
-
- /**
- * @return array
- */
- public function provideNumeric()
- {
- return [
- [77],
- ['42'],
- ['1337e0'],
- ['123f00', false],
- [null, false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::numeric
- * @param mixed $value
- * @param bool $result
- * @dataProvider provideNumeric
- */
- public function testNumeric($value, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->numeric($value) === $result);
- }
-
- /**
- * @return array
- */
- public function provideRequired()
- {
- return [
- ['Lorem ipsum'],
- ['1234'],
- [1234],
- ['0'],
- [0],
- ['', false],
- [' ', false],
- [null, false],
- ];
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::required
- * @param mixed $value
- * @param bool $result
- * @dataProvider provideRequired
- */
- public function testRequired($value, bool $result = true)
- {
- $val = new Validates;
- $this->assertTrue($val->required($value) === $result);
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::getSize
- */
- public function testGetSize()
- {
- $val = new Validates;
- $this->assertTrue($val->max(42, [999]));
- $this->assertTrue($val->max('99', [100]));
- $this->assertFalse($val->max('101', [100]));
- $this->assertTrue($val->max('lorem', [5]));
- $this->assertFalse($val->max('Lorem Ipsum', [5]));
- }
-
- /**
- * @covers \Engelsystem\Http\Validation\Validates::validateParameterCount
- */
- public function testValidateParameterCount()
- {
- $val = new Validates;
- $this->assertTrue($val->between(42, [1, 100]));
-
- $this->expectException(InvalidArgumentException::class);
- $val->between(42, [1]);
- }
-}
diff --git a/tests/Unit/Http/Validation/ValidatorTest.php b/tests/Unit/Http/Validation/ValidatorTest.php
index 799265ec..0790b7a8 100644
--- a/tests/Unit/Http/Validation/ValidatorTest.php
+++ b/tests/Unit/Http/Validation/ValidatorTest.php
@@ -2,7 +2,6 @@
namespace Engelsystem\Test\Unit\Http\Validation;
-use Engelsystem\Http\Validation\Validates;
use Engelsystem\Http\Validation\Validator;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
@@ -10,19 +9,18 @@ use PHPUnit\Framework\TestCase;
class ValidatorTest extends TestCase
{
/**
- * @covers \Engelsystem\Http\Validation\Validator::__construct
* @covers \Engelsystem\Http\Validation\Validator::validate
* @covers \Engelsystem\Http\Validation\Validator::getData
* @covers \Engelsystem\Http\Validation\Validator::getErrors
*/
public function testValidate()
{
- $val = new Validator(new Validates);
+ $val = new Validator();
$this->assertTrue($val->validate(
- ['foo' => 'bar', 'lorem' => 'on'],
- ['foo' => 'required|not_in:lorem,ipsum,dolor', 'lorem' => 'accepted']
+ ['foo' => 'bar', 'lorem' => 'on', 'dolor' => 'bla'],
+ ['lorem' => 'accepted']
));
- $this->assertEquals(['foo' => 'bar', 'lorem' => 'on'], $val->getData());
+ $this->assertEquals(['lorem' => 'on'], $val->getData());
$this->assertFalse($val->validate(
[],
@@ -39,7 +37,7 @@ class ValidatorTest extends TestCase
*/
public function testValidateNotImplemented()
{
- $val = new Validator(new Validates);
+ $val = new Validator();
$this->expectException(InvalidArgumentException::class);
$val->validate(
@@ -47,4 +45,34 @@ class ValidatorTest extends TestCase
['foo' => 'never_implemented']
);
}
+
+ /**
+ * @covers \Engelsystem\Http\Validation\Validator::map
+ * @covers \Engelsystem\Http\Validation\Validator::mapBack
+ */
+ public function testValidateMapping()
+ {
+ $val = new Validator();
+ $this->assertTrue($val->validate(
+ ['foo' => 'bar'],
+ ['foo' => 'required']
+ ));
+ $this->assertTrue($val->validate(
+ ['foo' => '0'],
+ ['foo' => 'int']
+ ));
+ $this->assertTrue($val->validate(
+ ['foo' => 'on'],
+ ['foo' => 'accepted']
+ ));
+
+ $this->assertFalse($val->validate(
+ [],
+ ['lorem' => 'required']
+ ));
+ $this->assertEquals(
+ ['lorem' => ['validation.lorem.required']],
+ $val->getErrors()
+ );
+ }
}