diff --git a/docs/index.md b/docs/index.md index cb4cd04..3fcb75c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,12 +5,14 @@ permalink: /index.html --- ## {{ page.title }} -*Verja* is a very simple and stupid library to filter and validate input data. The name *Verja* comes from the Old -Norse language and means defender. The idea behind this name is that the library defends you from invalid input. +**Verja** is a very simple and stupid library to filter and validate input data. The name +[**Verja**](https://en.wiktionary.org/wiki/verja) (pronunciation **/ˈvɛrja/** +[IPA](https://en.wiktionary.org/wiki/Wiktionary:International_Phonetic_Alphabet)) comes from the Old Norse language and +means to defend. The idea behind this name is that the library defends you from invalid, missing and unwanted input. -The interface is very straight forward. `Verja\Gate` is the main object (you should **not reuse** this object). It -holds the data that should be validated, and the `Verja\Field`s. Each field has it's own filters and validators. When -you run `$container->validate()` each field gets filtered and validated. +The interface is very straight forward. `Verja\Gate` is the gate for your input data. It holds the data that should be +validated, and the `Verja\Field`s. Each field has it's own filters and validators. When you run `$container->validate()` +each field gets filtered and validated. Here is a small pseudo code example to explain the simplicity of this library: diff --git a/docs/usage.md b/docs/usage.md index e2881da..40524f4 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -163,16 +163,8 @@ $gate->getData(); // throws "Invalid pw: value should be equal to contexts pw_co ### Show Errors -The `Validator` may contain an error in the following format after validating an invalid value: - -```php?start_inline=true -return [ - 'key' => 'NOT_CONTAINS', // a key that can be used for translation - 'value' => 'any string', // the value that got validated - 'message' => 'value should contain "bar"', // OPTIONAL - a default error message (used for exceptions) - 'parameters' => [ 'subString' => 'bar' ], // OPTIONAL - parameters used for validation -]; -``` +The `Validator` may contain an `Verja\Error` after validating an invalid value that you can retrieve with +`Validator::getError()`. The `Field` contains an array of all errors occurred during `Field::validate()` and the `Gate` contains an array with all arrays of errors from the fields. The method `Gate::getErrors()` may return something like this: @@ -180,28 +172,65 @@ all arrays of errors from the fields. The method `Gate::getErrors()` may return ```php?start_inline=true return [ 'foo' => [ - [ - 'key' => 'NOT_CONTAINS', - 'value' => 'any string', - 'message' => 'value should contain "bar"', - 'parameters' => [ 'subString' => 'bar' ], - ] + new \Verja\Error( + 'NOT_CONTAINS', + 'any string', + 'value should contain "bar"', + [ 'subString' => 'bar' ] + ) ], 'pw' => [ - [ - 'key' => 'STRLEN_TOO_SHORT', - 'value' => 'abc123', - 'message' => 'value should be at least 8 characters long', - 'parameters' => [ 'min' => 8, 'max' => 0 ], - ], - [ - 'key' => 'NOT_EQUAL', - 'value' => 'abc123', - 'message' => 'value should be equal to contexts pw_conf', - 'parameters' => [ 'opposite' => 'pw_conf', 'jsonEncode' => true ] - ] + new \Verja\Error( + 'STRLEN_TOO_SHORT', + 'abc123', + 'value should be at least 8 characters long', + [ 'min' => 8, 'max' => 0 ] + ), + new \Verja\Error( + 'NOT_EQUAL', + 'abc123', + 'value should be equal to contexts pw_conf', + [ 'opposite' => 'pw_conf', 'jsonEncode' => true ] + ) ], ]; +``` + +You can then serialize this data to this json: + +```json +{ + "foo": [ + { + "key": "NOT_CONTAINS", + "message": "value should contain \"bar\"", + "parameters": { + "subString": "bar", + "value": "any string" + } + } + ], + "pw": [ + { + "key": "STRLEN_TOO_SHORT", + "message": "value should be at least 8 characters long", + "parameters": { + "min": 8, + "max": 0, + "value": "abc123" + } + }, + { + "key": "NOT_EQUAL", + "message": "value should be equal to contexts pw_conf", + "parameters": { + "opposite": "pw_conf", + "jsonEncode": true, + "value": "abc123" + } + } + ] +} ``` ### Example diff --git a/src/Error.php b/src/Error.php new file mode 100644 index 0000000..54e7bac --- /dev/null +++ b/src/Error.php @@ -0,0 +1,39 @@ +key = $key; + + if ($message !== null) { + $this->message = $message; + } else { + $this->message = sprintf('%s %s', json_encode($value), $key); + } + + if ($parameters !== null) { + $this->parameters = $parameters; + } + $this->parameters['value'] = $value; + } +} diff --git a/src/Validator.php b/src/Validator.php index 49b3832..190f6bf 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -88,31 +88,4 @@ public function getInverseError($value) { return null; } - - /** - * @param string $key - * @param mixed $value - * @param string|null $message - * @param array|null $parameters - * @return array - */ - public static function buildError(string $key, $value, string $message = null, array $parameters = null) - { - $error = [ - 'key' => $key, - 'value' => $value, - ]; - - if ($parameters !== null) { - $error['parameters'] = $parameters; - } - - if ($message !== null) { - $error['message'] = $message; - } else { - $error['message'] = sprintf('%s %s', json_encode($value), $key); - } - - return $error; - } } diff --git a/src/Validator/Callback.php b/src/Validator/Callback.php index e5b789b..5ee4e7b 100644 --- a/src/Validator/Callback.php +++ b/src/Validator/Callback.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class Callback extends Validator @@ -24,7 +25,7 @@ public function validate($value, array $context = []): bool { $result = call_user_func($this->callback, $value, $context); - if (is_array($result) && isset($result['key']) && isset($result['value']) && isset($result['message'])) { + if ($result instanceof Error) { $this->error = $result; return false; } diff --git a/src/Validator/Contains.php b/src/Validator/Contains.php index 7ad7e00..9062f8d 100644 --- a/src/Validator/Contains.php +++ b/src/Validator/Contains.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class Contains extends Validator @@ -23,7 +24,7 @@ public function __construct(string $subString) public function validate($value, array $context = []): bool { if (strpos($value, $this->subString) === false) { - $this->error = $this->buildError( + $this->error = new Error( 'NOT_CONTAINS', $value, sprintf('value should contain "%s"', $this->subString), @@ -38,7 +39,7 @@ public function validate($value, array $context = []): bool /** {@inheritdoc} */ public function getInverseError($value) { - return $this->buildError( + return new Error( 'CONTAINS', $value, sprintf('value should not contain "%s"', $this->subString), diff --git a/src/Validator/EmailAddress.php b/src/Validator/EmailAddress.php index 983fd0f..614246b 100644 --- a/src/Validator/EmailAddress.php +++ b/src/Validator/EmailAddress.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class EmailAddress extends Validator @@ -13,7 +14,7 @@ class EmailAddress extends Validator public function validate($value, array $context = []): bool { if (!preg_match('/^' . self::LOCAL_PART_PATTERN . '@' . self::DOMAIN_PART_PATTERN . '$/', $value)) { - $this->error = $this::buildError( + $this->error = new Error( 'NO_EMAIL_ADDRESS', $value, 'value should be a valid email address', @@ -28,7 +29,7 @@ public function validate($value, array $context = []): bool /** {@inheritdoc} */ public function getInverseError($value) { - return $this::buildError( + return new Error( 'EMAIL_ADDRESS', $value, 'value should not be an email address', diff --git a/src/Validator/Equals.php b/src/Validator/Equals.php index e242a97..06c6c64 100644 --- a/src/Validator/Equals.php +++ b/src/Validator/Equals.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class Equals extends Validator @@ -43,7 +44,7 @@ public function validate($value, array $context = []): bool } } - $this->error = $this->buildError( + $this->error = new Error( 'NOT_EQUAL', $value, sprintf('value should be equal to contexts %s', $this->opposite), @@ -55,7 +56,7 @@ public function validate($value, array $context = []): bool /** {@inheritdoc} */ public function getInverseError($value) { - return $this->buildError( + return new Error( 'EQUALS', $value, sprintf('value should not be equal to contexts %s', $this->opposite), diff --git a/src/Validator/NotEmpty.php b/src/Validator/NotEmpty.php index cd148f5..62e3323 100644 --- a/src/Validator/NotEmpty.php +++ b/src/Validator/NotEmpty.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class NotEmpty extends Validator @@ -10,7 +11,7 @@ class NotEmpty extends Validator public function validate($value, array $context = []): bool { if (empty($value)) { - $this->error = $this->buildError( + $this->error = new Error( 'IS_EMPTY', $value, 'value should not be empty' @@ -24,7 +25,7 @@ public function validate($value, array $context = []): bool /** {@inheritdoc} */ public function getInverseError($value) { - return $this->buildError( + return new Error( 'IS_NOT_EMPTY', $value, 'value should be empty' diff --git a/src/Validator/PregMatch.php b/src/Validator/PregMatch.php index fe1a8e7..75cacd1 100644 --- a/src/Validator/PregMatch.php +++ b/src/Validator/PregMatch.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class PregMatch extends Validator @@ -26,7 +27,7 @@ public function validate($value, array $context = []): bool return true; } - $this->error = $this->buildError( + $this->error = new Error( 'NO_MATCH', $value, sprintf('value should match "%s"', $this->pattern), @@ -38,7 +39,7 @@ public function validate($value, array $context = []): bool /** {@inheritdoc} */ public function getInverseError($value) { - return $this->buildError( + return new Error( 'MATCHES', $value, sprintf('value should not match "%s"', $this->pattern), diff --git a/src/Validator/StrLen.php b/src/Validator/StrLen.php index 33b8c4c..4181c7c 100644 --- a/src/Validator/StrLen.php +++ b/src/Validator/StrLen.php @@ -2,6 +2,7 @@ namespace Verja\Validator; +use Verja\Error; use Verja\Validator; class StrLen extends Validator @@ -30,7 +31,7 @@ public function validate($value, array $context = []): bool { $strLen = strlen($value); if ($strLen < $this->min) { - $this->error = $this->buildError( + $this->error = new Error( 'STRLEN_TOO_SHORT', $value, sprintf('value should be at least %d characters long', $this->min), @@ -38,7 +39,7 @@ public function validate($value, array $context = []): bool ); return false; } elseif ($this->max > 0 && $strLen > $this->max) { - $this->error = $this->buildError( + $this->error = new Error( 'STRLEN_TOO_LONG', $value, sprintf('value should be maximal %d characters long', $this->max), diff --git a/test.php b/test.php new file mode 100644 index 0000000..a72ef8f --- /dev/null +++ b/test.php @@ -0,0 +1,43 @@ +addValidator($validator); + $field2->addValidator($validator); + + var_dump($field1->getValidators()); + var_dump($field2->getValidators()); +} + +class DField extends Field +{ + public function getValidators() + { + return $this->validators; + } +} + +controller(); diff --git a/tests/ErrorsTest.php b/tests/ErrorsTest.php index 8cf16f1..35f5252 100644 --- a/tests/ErrorsTest.php +++ b/tests/ErrorsTest.php @@ -2,6 +2,7 @@ namespace Verja\Test; +use Verja\Error; use Verja\Field; use Verja\Gate; use Verja\Test\Examples\CustomValidator\GeneratedMessage; @@ -36,17 +37,39 @@ public function fieldCallsGetErrorWhenInvalid() } /** @test */ - public function buildErrorGeneratesMessage() + public function errorsCanBeSerialized() { - $validator = new GeneratedMessage(); - $validator->validate('value'); + $error = new Error('ERROR_KEY', 'validated value', 'Error message from validator'); - $result = $validator->getError(); + $serialized = serialize($error); - self::assertSame([ - 'key' => 'GENERATED_MESSAGE', - 'value' => 'value', - 'message' => '"value" GENERATED_MESSAGE' - ], $result); + self::assertContains('ERROR_KEY', $serialized); + self::assertContains('validated value', $serialized); + self::assertContains('Error message from validator', $serialized); + } + + /** @test */ + public function errorsCanBeUnserialized() + { + $error = new Error('ERROR_KEY', 'validated value', 'Error message from validator'); + $serialized = serialize($error); + + $result = unserialize($serialized); + + self::assertEquals($error, $result); + } + + /** @test */ + public function errorsCanBeJsonEncoded() + { + $error = new Error('ERROR_KEY', 'validated value', 'Error message from validator'); + + $json = json_encode($error); + + self::assertSame(json_encode([ + 'key' => 'ERROR_KEY', + 'message' => 'Error message from validator', + 'parameters' => ['value' => 'validated value'], + ]), $json); } } diff --git a/tests/Examples/CustomValidator/GeneratedMessage.php b/tests/Examples/CustomValidator/GeneratedMessage.php deleted file mode 100644 index 6be8479..0000000 --- a/tests/Examples/CustomValidator/GeneratedMessage.php +++ /dev/null @@ -1,14 +0,0 @@ -error = $this->buildError('GENERATED_MESSAGE', $value); - return false; - } -} diff --git a/tests/Validator/CallbackTest.php b/tests/Validator/CallbackTest.php index 27b313b..65a04ed 100644 --- a/tests/Validator/CallbackTest.php +++ b/tests/Validator/CallbackTest.php @@ -2,8 +2,8 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; -use Verja\Validator; use Verja\Validator\Callback; class CallbackTest extends TestCase @@ -28,16 +28,12 @@ public function callsCallbackToValidate() public function usesArrayReturnValueAsError() { $validator = new Callback(function ($value) { - return Validator::buildError('KEY', $value); + return new Error('KEY', $value); }); $validator->validate('value'); - self::assertSame([ - 'key' => 'KEY', - 'value' => 'value', - 'message' => '"value" KEY' - ], $validator->getError()); + self::assertEquals(new Error('KEY', 'value', '"value" KEY'), $validator->getError()); } /** @test */ diff --git a/tests/Validator/ContainsTest.php b/tests/Validator/ContainsTest.php index 7e74f58..dba3b52 100644 --- a/tests/Validator/ContainsTest.php +++ b/tests/Validator/ContainsTest.php @@ -2,6 +2,7 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; use Verja\Validator\Contains; @@ -37,12 +38,10 @@ public function returnsFalseForNotContainedStrings() $result = $validator->validate('noSpaces'); self::assertFalse($result); - self::assertSame([ - 'key' => 'NOT_CONTAINS', - 'value' => 'noSpaces', - 'parameters' => ['subString' => ' '], - 'message' => 'value should contain " "' - ], $validator->getError()); + self::assertEquals( + new Error('NOT_CONTAINS', 'noSpaces', 'value should contain " "', ['subString' => ' ']), + $validator->getError() + ); } public function provideNotContainedStrings() @@ -59,11 +58,9 @@ public function returnsContainsError() $result = $validator->getInverseError('with space'); - self::assertSame([ - 'key' => 'CONTAINS', - 'value' => 'with space', - 'parameters' => ['subString' => ' '], - 'message' => 'value should not contain " "' - ], $result); + self::assertEquals( + new Error('CONTAINS', 'with space', 'value should not contain " "', ['subString' => ' ']), + $result + ); } } diff --git a/tests/Validator/EmailAddressTest.php b/tests/Validator/EmailAddressTest.php index ccd8aa5..147e1dd 100644 --- a/tests/Validator/EmailAddressTest.php +++ b/tests/Validator/EmailAddressTest.php @@ -2,6 +2,7 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; use Verja\Validator\EmailAddress; @@ -39,11 +40,10 @@ public function setsError() $validator = new EmailAddress(); self::assertFalse($validator->validate('@')); - self::assertSame([ - 'key' => 'NO_EMAIL_ADDRESS', - 'value' => '@', - 'message' => 'value should be a valid email address', - ], $validator->getError()); + self::assertEquals( + new Error('NO_EMAIL_ADDRESS', '@', 'value should be a valid email address'), + $validator->getError() + ); } /** @test */ @@ -51,10 +51,9 @@ public function returnsInverseError() { $validator = new EmailAddress(); - self::assertSame([ - 'key' => 'EMAIL_ADDRESS', - 'value' => 'john.doe@example.com', - 'message' => 'value should not be an email address' - ], $validator->getInverseError('john.doe@example.com')); + self::assertEquals( + new Error('EMAIL_ADDRESS', 'john.doe@example.com', 'value should not be an email address'), + $validator->getInverseError('john.doe@example.com') + ); } } diff --git a/tests/Validator/EqualsTest.php b/tests/Validator/EqualsTest.php index 38470ea..20948a3 100644 --- a/tests/Validator/EqualsTest.php +++ b/tests/Validator/EqualsTest.php @@ -2,6 +2,7 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; use Verja\Validator\Equals; @@ -62,12 +63,15 @@ public function jsonEncodingCanBeDisabled() $result = $validator->validate(['foo' => 'bar'], ['opposite' => (object) ['foo' => 'bar']]); self::assertFalse($result); - self::assertSame([ - 'key' => 'NOT_EQUAL', - 'value' => ['foo' => 'bar'], - 'parameters' => ['opposite' => 'opposite', 'jsonEncode' => false], - 'message' => 'value should be equal to contexts opposite' - ], $validator->getError()); + self::assertEquals( + new Error( + 'NOT_EQUAL', + ['foo' => 'bar'], + 'value should be equal to contexts opposite', + ['opposite' => 'opposite', 'jsonEncode' => false] + ), + $validator->getError() + ); } /** @test */ @@ -77,11 +81,14 @@ public function returnsInverseError() $result = $validator->getInverseError('value'); - self::assertSame([ - 'key' => 'EQUALS', - 'value' => 'value', - 'parameters' => ['opposite' => 'opposite', 'jsonEncode' => true], - 'message' => 'value should not be equal to contexts opposite' - ], $result); + self::assertEquals( + new Error( + 'EQUALS', + 'value', + 'value should not be equal to contexts opposite', + ['opposite' => 'opposite', 'jsonEncode' => true] + ), + $result + ); } } diff --git a/tests/Validator/NotEmptyTest.php b/tests/Validator/NotEmptyTest.php index d057298..50f5911 100644 --- a/tests/Validator/NotEmptyTest.php +++ b/tests/Validator/NotEmptyTest.php @@ -2,6 +2,7 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; use Verja\Validator\NotEmpty; @@ -63,11 +64,10 @@ public function setsNotEmptyError() $result = $validator->getError(); - self::assertSame([ - 'key' => 'IS_EMPTY', - 'value' => 0, - 'message' => 'value should not be empty' - ], $result); + self::assertEquals( + new Error('IS_EMPTY', 0, 'value should not be empty'), + $result + ); } /** @test */ @@ -77,10 +77,9 @@ public function returnsInverseError() $result = $validator->getInverseError('value'); - self::assertSame([ - 'key' => 'IS_NOT_EMPTY', - 'value' => 'value', - 'message' => 'value should be empty' - ], $result); + self::assertEquals( + new Error('IS_NOT_EMPTY', 'value', 'value should be empty'), + $result + ); } } diff --git a/tests/Validator/PregMatchTest.php b/tests/Validator/PregMatchTest.php index be50bf7..f4355d9 100644 --- a/tests/Validator/PregMatchTest.php +++ b/tests/Validator/PregMatchTest.php @@ -2,6 +2,7 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; use Verja\Validator\PregMatch; @@ -25,12 +26,10 @@ public function setsError() $result = $validator->validate('bar'); self::assertFalse($result); - self::assertSame([ - 'key' => 'NO_MATCH', - 'value' => 'bar', - 'parameters' => ['pattern' => '#foo#'], - 'message' => 'value should match "#foo#"' - ], $validator->getError()); + self::assertEquals( + new Error('NO_MATCH', 'bar', 'value should match "#foo#"', ['pattern' => '#foo#']), + $validator->getError() + ); } /** @test */ @@ -38,11 +37,9 @@ public function returnsInverseError() { $validator = new PregMatch('#foo#'); - self::assertSame([ - 'key' => 'MATCHES', - 'value' => 'some foo for you', - 'parameters' => ['pattern' => '#foo#'], - 'message' => 'value should not match "#foo#"' - ], $validator->getInverseError('some foo for you')); + self::assertEquals( + new Error('MATCHES', 'some foo for you', 'value should not match "#foo#"', ['pattern' => '#foo#']), + $validator->getInverseError('some foo for you') + ); } } diff --git a/tests/Validator/StrLenTest.php b/tests/Validator/StrLenTest.php index e433f54..a8fbaef 100644 --- a/tests/Validator/StrLenTest.php +++ b/tests/Validator/StrLenTest.php @@ -2,6 +2,7 @@ namespace Verja\Test\Validator; +use Verja\Error; use Verja\Test\TestCase; use Verja\Validator\StrLen; @@ -33,12 +34,10 @@ public function limitsLengthTest() $result = $validator->validate('long'); self::assertFalse($result); - self::assertSame([ - 'key' => 'STRLEN_TOO_LONG', - 'value' => 'long', - 'parameters' => ['min' => 0, 'max' => 2], - 'message' => 'value should be maximal 2 characters long' - ], $validator->getError()); + self::assertEquals( + new Error('STRLEN_TOO_LONG', 'long', 'value should be maximal 2 characters long', ['min' => 0, 'max' => 2]), + $validator->getError() + ); } /** @test */ @@ -49,12 +48,15 @@ public function requiresMinLength() $result = $validator->validate('short'); self::assertFalse($result); - self::assertSame([ - 'key' => 'STRLEN_TOO_SHORT', - 'value' => 'short', - 'parameters' => ['min' => 6, 'max' => 0], - 'message' => 'value should be at least 6 characters long' - ], $validator->getError()); + self::assertEquals( + new Error( + 'STRLEN_TOO_SHORT', + 'short', + 'value should be at least 6 characters long', + ['min' => 6, 'max' => 0] + ), + $validator->getError() + ); } /** @test */