From 70d3cdd0ff17715202fecf1a649c5d83e89a2feb Mon Sep 17 00:00:00 2001 From: xanish Date: Tue, 17 Aug 2021 19:37:39 +0530 Subject: [PATCH 01/21] Added support for array of values in rule parameters --- .../ArrayParameterizedRuleInterface.php | 32 +++++++++++++++++++ src/Helpers/FormatsMessages.php | 9 ++++++ src/Validator/Validator.php | 8 +++++ 3 files changed, 49 insertions(+) create mode 100644 src/Contracts/ArrayParameterizedRuleInterface.php diff --git a/src/Contracts/ArrayParameterizedRuleInterface.php b/src/Contracts/ArrayParameterizedRuleInterface.php new file mode 100644 index 0000000..85aa469 --- /dev/null +++ b/src/Contracts/ArrayParameterizedRuleInterface.php @@ -0,0 +1,32 @@ +replaceParameterPlaceholder( + $message, + $rule->allowedParameters(), + $rule->parseParameterValues($parameters) + ); + } + $message = $this->replaceValuePlaceholder($message, $value); $message = $this->replaceErrorLinePlaceholder($message, $lineNumber); diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 1159ccd..4b0e7e9 100755 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -5,6 +5,7 @@ namespace Oshomo\CsvUtils\Validator; use Oshomo\CsvUtils\Contracts\ConverterHandlerInterface; +use Oshomo\CsvUtils\Contracts\ArrayParameterizedRuleInterface; use Oshomo\CsvUtils\Contracts\ParameterizedRuleInterface; use Oshomo\CsvUtils\Contracts\ValidationRuleInterface; use Oshomo\CsvUtils\Contracts\ValidationRuleInterface as ValidationRule; @@ -357,6 +358,13 @@ protected function passesParameterCheck($rule, array $parameters): bool return $parameterCount === $ruleParameterCount; } + if ($rule instanceof ArrayParameterizedRuleInterface) { + $ruleParameterCount = count($rule->allowedParameters()); + $parameterCount = count($parameters); + + return $parameterCount >= $ruleParameterCount; + } + return true; } From b8a850b678869714dbedebab318f809cf41dff22 Mon Sep 17 00:00:00 2001 From: xanish Date: Tue, 17 Aug 2021 19:39:54 +0530 Subject: [PATCH 02/21] Added support for dependent field validations --- src/Contracts/ValidationRuleInterface.php | 5 ++++- src/Rules/AsciiOnly.php | 5 ++++- src/Rules/Between.php | 5 ++++- src/Rules/ClosureValidationRule.php | 7 +++++-- src/Rules/Url.php | 5 ++++- src/Validator/Validator.php | 4 ++-- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/Contracts/ValidationRuleInterface.php b/src/Contracts/ValidationRuleInterface.php index 5b05e2e..add5fdd 100644 --- a/src/Contracts/ValidationRuleInterface.php +++ b/src/Contracts/ValidationRuleInterface.php @@ -11,8 +11,11 @@ interface ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value + * @param array $parameters + * @param array $row + * @return bool */ - public function passes($value, array $parameters): bool; + public function passes($value, array $parameters, array $row): bool; /** * Get the validation error message. Specify the message that should diff --git a/src/Rules/AsciiOnly.php b/src/Rules/AsciiOnly.php index a811a59..9383a76 100644 --- a/src/Rules/AsciiOnly.php +++ b/src/Rules/AsciiOnly.php @@ -12,8 +12,11 @@ class AsciiOnly implements ValidationRuleInterface * Determine if the validation rule passes. * * @param mixed $value + * @param array $parameters + * @param array $row + * @return bool */ - public function passes($value, array $parameters): bool + public function passes($value, array $parameters, array $row): bool { return (mb_detect_encoding($value, 'ASCII', true)) ? true : false; } diff --git a/src/Rules/Between.php b/src/Rules/Between.php index df7151c..49246b3 100644 --- a/src/Rules/Between.php +++ b/src/Rules/Between.php @@ -18,8 +18,11 @@ public function allowedParameters(): array * Determine if the validation rule passes. * * @param mixed $value + * @param array $parameters + * @param array $row + * @return bool */ - public function passes($value, array $parameters): bool + public function passes($value, array $parameters, array $row): bool { $size = (int) $value; diff --git a/src/Rules/ClosureValidationRule.php b/src/Rules/ClosureValidationRule.php index f54b9f7..503cf1e 100755 --- a/src/Rules/ClosureValidationRule.php +++ b/src/Rules/ClosureValidationRule.php @@ -41,12 +41,15 @@ public function __construct(\Closure $callback) * Determine if the validation rule passes. * * @param mixed $value + * @param array $parameters + * @param array $row + * @return bool */ - public function passes($value, array $parameters): bool + public function passes($value, array $parameters, array $row): bool { $this->failed = false; - $this->callback->__invoke($value, function ($message) { + $this->callback->__invoke($value, $row, function ($message) { $this->failed = true; $this->message = $message; diff --git a/src/Rules/Url.php b/src/Rules/Url.php index de1072f..986f671 100644 --- a/src/Rules/Url.php +++ b/src/Rules/Url.php @@ -30,8 +30,11 @@ class Url implements ValidationRuleInterface * Determine if the validation rule passes. * * @param mixed $value + * @param array $parameters + * @param array $row + * @return bool */ - public function passes($value, array $parameters): bool + public function passes($value, array $parameters, array $row): bool { /* * This pattern is derived from Symfony\Component\Validator\Constraints\UrlValidator (4.0). diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 4b0e7e9..c1afd99 100755 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -278,7 +278,7 @@ protected function validateAttribute(string $attribute, $rule): void if ($this->isValidateAble($rule, $parameters)) { $ruleClass = $this->getRuleClass($rule); - if (!$ruleClass->passes($value, $parameters)) { + if (!$ruleClass->passes($value, $parameters, $this->currentRow)) { $this->addFailure( $this->getMessage($attribute, $ruleClass, $rule), $attribute, @@ -379,7 +379,7 @@ protected function validateUsingCustomRule( array $parameters, ValidationRuleInterface $rule ): void { - if (!$rule->passes($value, $parameters)) { + if (!$rule->passes($value, $parameters, $this->currentRow)) { $this->addFailure($rule->message(), $attribute, $value, $rule, $parameters); } } From 1eb700870b0b1c74bd6846c78655a64c0d94b82c Mon Sep 17 00:00:00 2001 From: xanish Date: Tue, 17 Aug 2021 19:44:22 +0530 Subject: [PATCH 03/21] Added required validation rule --- src/Rules/Required.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/Rules/Required.php diff --git a/src/Rules/Required.php b/src/Rules/Required.php new file mode 100644 index 0000000..8b4fb70 --- /dev/null +++ b/src/Rules/Required.php @@ -0,0 +1,34 @@ + Date: Tue, 17 Aug 2021 19:46:10 +0530 Subject: [PATCH 04/21] Added integer validation rule --- src/Rules/Integer.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/Rules/Integer.php diff --git a/src/Rules/Integer.php b/src/Rules/Integer.php new file mode 100644 index 0000000..4dbd6ee --- /dev/null +++ b/src/Rules/Integer.php @@ -0,0 +1,38 @@ + Date: Tue, 17 Aug 2021 19:46:57 +0530 Subject: [PATCH 05/21] Added numeric validation rule --- src/Rules/Numeric.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/Rules/Numeric.php diff --git a/src/Rules/Numeric.php b/src/Rules/Numeric.php new file mode 100644 index 0000000..5e2d967 --- /dev/null +++ b/src/Rules/Numeric.php @@ -0,0 +1,38 @@ + Date: Tue, 17 Aug 2021 19:49:02 +0530 Subject: [PATCH 06/21] Added alpha_num validation rule --- src/Rules/AlphaNum.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/Rules/AlphaNum.php diff --git a/src/Rules/AlphaNum.php b/src/Rules/AlphaNum.php new file mode 100644 index 0000000..aebb92f --- /dev/null +++ b/src/Rules/AlphaNum.php @@ -0,0 +1,38 @@ + Date: Tue, 17 Aug 2021 19:49:58 +0530 Subject: [PATCH 07/21] Updated url rule to pass for empty values --- src/Rules/Url.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rules/Url.php b/src/Rules/Url.php index 986f671..5eb34d5 100644 --- a/src/Rules/Url.php +++ b/src/Rules/Url.php @@ -44,7 +44,7 @@ public function passes($value, array $parameters, array $row): bool $pattern = sprintf(static::PATTERN, implode('|', ['http', 'https'])); if (null === $value || '' === $value) { - return false; + return true; } $value = (string) $value; From 08cdb6a1d773d19a94ae69d019b2ea2bf8e0b869 Mon Sep 17 00:00:00 2001 From: xanish Date: Tue, 17 Aug 2021 20:00:30 +0530 Subject: [PATCH 08/21] Added in validation rule --- .../ArrayParameterizedRuleInterface.php | 5 +- src/Contracts/ParameterizedRuleInterface.php | 2 +- src/Rules/In.php | 71 +++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/Rules/In.php diff --git a/src/Contracts/ArrayParameterizedRuleInterface.php b/src/Contracts/ArrayParameterizedRuleInterface.php index 85aa469..3e92ddc 100644 --- a/src/Contracts/ArrayParameterizedRuleInterface.php +++ b/src/Contracts/ArrayParameterizedRuleInterface.php @@ -10,13 +10,14 @@ * * Supports validation rules which need multiple parameters * that behave like an array. + * See the in rule for example. */ interface ArrayParameterizedRuleInterface { /** * Should return an array of the allowed parameters. - * Tha allowed parameters should be - * tokenized string e.g :min, :max, :first, :last etc. + * The allowed parameters should be tokenized string + * e.g :min, :max, :first, :last etc. */ public function allowedParameters(): array; diff --git a/src/Contracts/ParameterizedRuleInterface.php b/src/Contracts/ParameterizedRuleInterface.php index 73bb58c..1dff5a0 100644 --- a/src/Contracts/ParameterizedRuleInterface.php +++ b/src/Contracts/ParameterizedRuleInterface.php @@ -8,7 +8,7 @@ interface ParameterizedRuleInterface { /** * Should return an array of the allowed parameters. - * See the between rule. Tha allowed parameters should be + * See the between rule. The allowed parameters should be * tokenized string e.g :min, :max, :first, :last etc. */ public function allowedParameters(): array; diff --git a/src/Rules/In.php b/src/Rules/In.php new file mode 100644 index 0000000..560df3c --- /dev/null +++ b/src/Rules/In.php @@ -0,0 +1,71 @@ + Date: Tue, 17 Aug 2021 20:30:49 +0530 Subject: [PATCH 09/21] Added required_if validation rule --- src/Rules/RequiredIf.php | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/Rules/RequiredIf.php diff --git a/src/Rules/RequiredIf.php b/src/Rules/RequiredIf.php new file mode 100644 index 0000000..0f3b8a1 --- /dev/null +++ b/src/Rules/RequiredIf.php @@ -0,0 +1,71 @@ + Date: Tue, 17 Aug 2021 20:32:19 +0530 Subject: [PATCH 10/21] Added new and updated existing rule test cases --- tests/data/alpha_num_test.csv | 2 + tests/data/in_test.csv | 2 + tests/data/integer_test.csv | 2 + tests/data/numeric_test.csv | 2 + tests/data/required_if_test.csv | 2 + tests/data/required_test.csv | 2 + tests/src/CsvValidatorTest.php | 178 +++++++++++++++++++++++++++++--- tests/src/UppercaseRule.php | 6 +- 8 files changed, 177 insertions(+), 19 deletions(-) create mode 100644 tests/data/alpha_num_test.csv create mode 100644 tests/data/in_test.csv create mode 100644 tests/data/integer_test.csv create mode 100644 tests/data/numeric_test.csv create mode 100644 tests/data/required_if_test.csv create mode 100644 tests/data/required_test.csv diff --git a/tests/data/alpha_num_test.csv b/tests/data/alpha_num_test.csv new file mode 100644 index 0000000..9928625 --- /dev/null +++ b/tests/data/alpha_num_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,Inga N. P.O. Box 567,A,Kasper Zen,http//:well.org diff --git a/tests/data/in_test.csv b/tests/data/in_test.csv new file mode 100644 index 0000000..9ade8c4 --- /dev/null +++ b/tests/data/in_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,Inga N. P.O. Box 567,2,Kasper Zen,http//:well.org diff --git a/tests/data/integer_test.csv b/tests/data/integer_test.csv new file mode 100644 index 0000000..1dd1758 --- /dev/null +++ b/tests/data/integer_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,Inga N. P.O. Box 567,5.5,Kasper Zen,http//:well.org diff --git a/tests/data/numeric_test.csv b/tests/data/numeric_test.csv new file mode 100644 index 0000000..9928625 --- /dev/null +++ b/tests/data/numeric_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,Inga N. P.O. Box 567,A,Kasper Zen,http//:well.org diff --git a/tests/data/required_if_test.csv b/tests/data/required_if_test.csv new file mode 100644 index 0000000..99c6f39 --- /dev/null +++ b/tests/data/required_if_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,Inga N. P.O. Box 567,3,,http//:well.org diff --git a/tests/data/required_test.csv b/tests/data/required_test.csv new file mode 100644 index 0000000..9158c03 --- /dev/null +++ b/tests/data/required_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,,3,Kasper Zen,http//:well.org diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index 3422405..e6fba70 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -36,6 +36,32 @@ public function testInvalidCsvFilePath() ); } + public function testAlphaNumValidationRule() + { + $file = $this->testAssets . '/alpha_num_test.csv'; + + $validator = new Validator($file, ',', [ + 'address' => ['alpha_num'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The address value Inga N. P.O. Box 567 may only contain letters and numbers on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + public function testAsciiOnlyValidationRule() { $file = $this->testAssets . '/ascii_test.csv'; @@ -88,12 +114,12 @@ public function testBetweenValidationRule() ); } - public function testUrlValidationRule() + public function testInValidationRule() { - $file = $this->testAssets . '/url_test.csv'; + $file = $this->testAssets . '/in_test.csv'; $validator = new Validator($file, ',', [ - 'uri' => ['url'], + 'stars' => ['in:3,5,8,10'], ]); $this->assertTrue($validator->fails()); @@ -103,28 +129,146 @@ public function testUrlValidationRule() $validator->errors()['message'] ); - $validationErrors = $validator->errors(); + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); - for ($csvRow = 0; $csvRow < 3; ++$csvRow) { - $this->assertArrayHasKey( - 'errors', - $validationErrors['data'][$csvRow] - ); - } + $this->assertContains( + 'The stars value 2 does not exist in 3,5,8,10 on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + + public function testIntegerValidationRule() + { + $file = $this->testAssets . '/integer_test.csv'; + + $validator = new Validator($file, ',', [ + 'stars' => ['integer'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); $this->assertContains( - 'The uri value http//:well.org is not a valid url on line 2.', - $validationErrors['data'][0]['errors'] + 'The stars value 5.5 must be an integer on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + + public function testNumericValidationRule() + { + $file = $this->testAssets . '/numeric_test.csv'; + + $validator = new Validator($file, ',', [ + 'stars' => ['numeric'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The stars value A must be a number on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + + public function testRequiredIfValidationRule() + { + $file = $this->testAssets . '/required_if_test.csv'; + + $validator = new Validator($file, ',', [ + 'contact' => ['required_if:address,Inga N. P.O. Box 567'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The contact field is required when address is Inga N. P.O. Box 567 on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + + public function testRequiredValidationRule() + { + $file = $this->testAssets . '/required_test.csv'; + + $validator = new Validator($file, ',', [ + 'address' => ['required'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] ); $this->assertContains( - 'The uri value is not a valid url on line 3.', - $validationErrors['data'][1]['errors'] + 'The address value is required on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + + public function testUrlValidationRule() + { + $file = $this->testAssets . '/url_test.csv'; + + $validator = new Validator($file, ',', [ + 'uri' => ['url'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $validationErrors = $validator->errors(); + + $this->assertArrayHasKey( + 'errors', + $validationErrors['data'][0] ); $this->assertContains( - 'The uri value is not a valid url on line 4.', - $validationErrors['data'][2]['errors'] + 'The uri value http//:well.org is not a valid url on line 2.', + $validationErrors['data'][0]['errors'] ); } @@ -159,7 +303,7 @@ public function testValidatorWithCustomRuleClosure() $file = $this->testAssets . '/url_test.csv'; $validator = new Validator($file, ',', [ - 'uri' => [function ($value, $fail) { + 'uri' => [function ($value, $row, $fail) { if (0 !== strpos($value, 'https://')) { return $fail('The URL passed must be https i.e it must start with https://'); } diff --git a/tests/src/UppercaseRule.php b/tests/src/UppercaseRule.php index 47a20b9..2862a22 100644 --- a/tests/src/UppercaseRule.php +++ b/tests/src/UppercaseRule.php @@ -8,9 +8,11 @@ class UppercaseRule implements ValidationRuleInterface { /** * @param mixed $value - * @param $parameters + * @param array $parameters + * @param array $row + * @return bool */ - public function passes($value, array $parameters): bool + public function passes($value, array $parameters, array $row): bool { return strtoupper($value) === $value; } From d09b6ac91f36f732848648b9e925cb2e38411be4 Mon Sep 17 00:00:00 2001 From: xanish Date: Wed, 18 Aug 2021 13:34:58 +0530 Subject: [PATCH 11/21] Added alpha validation rule --- src/Rules/Alpha.php | 38 ++++++++++++++++++++++++++++++++++ tests/src/CsvValidatorTest.php | 26 +++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/Rules/Alpha.php diff --git a/src/Rules/Alpha.php b/src/Rules/Alpha.php new file mode 100644 index 0000000..0ba3a0f --- /dev/null +++ b/src/Rules/Alpha.php @@ -0,0 +1,38 @@ +testAssets . '/alpha_num_test.csv'; + + $validator = new Validator($file, ',', [ + 'name' => ['alpha'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The name value Well Health Hotels may only contain letters on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + public function testAlphaNumValidationRule() { $file = $this->testAssets . '/alpha_num_test.csv'; From 5baaf6f4be092231275939ed3dad33d551ba5d34 Mon Sep 17 00:00:00 2001 From: xanish Date: Wed, 18 Aug 2021 13:57:03 +0530 Subject: [PATCH 12/21] Fixed lint --- src/Contracts/ArrayParameterizedRuleInterface.php | 11 ----------- src/Contracts/ValidationRuleInterface.php | 3 --- src/Rules/Alpha.php | 3 --- src/Rules/AlphaNum.php | 3 --- src/Rules/AsciiOnly.php | 3 --- src/Rules/Between.php | 3 --- src/Rules/ClosureValidationRule.php | 3 --- src/Rules/In.php | 10 ++-------- src/Rules/Integer.php | 5 +---- src/Rules/Numeric.php | 5 +---- src/Rules/Required.php | 3 --- src/Rules/RequiredIf.php | 12 ++---------- src/Rules/Url.php | 3 --- src/Validator/Validator.php | 2 +- tests/src/UppercaseRule.php | 3 --- 15 files changed, 7 insertions(+), 65 deletions(-) diff --git a/src/Contracts/ArrayParameterizedRuleInterface.php b/src/Contracts/ArrayParameterizedRuleInterface.php index 3e92ddc..e13ac04 100644 --- a/src/Contracts/ArrayParameterizedRuleInterface.php +++ b/src/Contracts/ArrayParameterizedRuleInterface.php @@ -4,14 +4,6 @@ namespace Oshomo\CsvUtils\Contracts; -/** - * Interface ArrayParameterizedRuleInterface - * @package Oshomo\CsvUtils\Contracts - * - * Supports validation rules which need multiple parameters - * that behave like an array. - * See the in rule for example. - */ interface ArrayParameterizedRuleInterface { /** @@ -25,9 +17,6 @@ public function allowedParameters(): array; * Should return an array of parameter values as strings * parsed in the same order and format as allowedParameters(). * This will aid in mapping our parameters to their placeholders. - * - * @param array $parameters - * @return array */ public function parseParameterValues(array $parameters): array; } diff --git a/src/Contracts/ValidationRuleInterface.php b/src/Contracts/ValidationRuleInterface.php index add5fdd..5faa143 100644 --- a/src/Contracts/ValidationRuleInterface.php +++ b/src/Contracts/ValidationRuleInterface.php @@ -11,9 +11,6 @@ interface ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool; diff --git a/src/Rules/Alpha.php b/src/Rules/Alpha.php index 0ba3a0f..eab95fa 100644 --- a/src/Rules/Alpha.php +++ b/src/Rules/Alpha.php @@ -13,9 +13,6 @@ class Alpha implements ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Rules/AlphaNum.php b/src/Rules/AlphaNum.php index aebb92f..7e6c3fd 100644 --- a/src/Rules/AlphaNum.php +++ b/src/Rules/AlphaNum.php @@ -13,9 +13,6 @@ class AlphaNum implements ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Rules/AsciiOnly.php b/src/Rules/AsciiOnly.php index 9383a76..7e332a3 100644 --- a/src/Rules/AsciiOnly.php +++ b/src/Rules/AsciiOnly.php @@ -12,9 +12,6 @@ class AsciiOnly implements ValidationRuleInterface * Determine if the validation rule passes. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Rules/Between.php b/src/Rules/Between.php index 49246b3..5e430bf 100644 --- a/src/Rules/Between.php +++ b/src/Rules/Between.php @@ -18,9 +18,6 @@ public function allowedParameters(): array * Determine if the validation rule passes. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Rules/ClosureValidationRule.php b/src/Rules/ClosureValidationRule.php index 503cf1e..40d2080 100755 --- a/src/Rules/ClosureValidationRule.php +++ b/src/Rules/ClosureValidationRule.php @@ -41,9 +41,6 @@ public function __construct(\Closure $callback) * Determine if the validation rule passes. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Rules/In.php b/src/Rules/In.php index 560df3c..5193bfd 100644 --- a/src/Rules/In.php +++ b/src/Rules/In.php @@ -14,9 +14,6 @@ class In implements ValidationRuleInterface, ArrayParameterizedRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { @@ -50,22 +47,19 @@ public function allowedParameters(): array // the values [1, 2, 3, 4] will get mapped to :allowed_values // while checking for passes() and while writing message // using parseParameterValues() - return [ ':allowed_values' ]; + return [':allowed_values']; } /** * Should return an array of parameter values as strings * parsed in the same order and format as allowedParameters(). * This will aid in mapping our parameters to their placeholders. - * - * @param array $parameters - * @return array */ public function parseParameterValues(array $parameters): array { // make sure to convert the values to an imploded string // this will then get mapped to array index 0 which has // the placeholder for :allowed_values - return [ implode(',', $parameters) ]; + return [implode(',', $parameters)]; } } diff --git a/src/Rules/Integer.php b/src/Rules/Integer.php index 4dbd6ee..72aef94 100644 --- a/src/Rules/Integer.php +++ b/src/Rules/Integer.php @@ -13,9 +13,6 @@ class Integer implements ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { @@ -23,7 +20,7 @@ public function passes($value, array $parameters, array $row): bool return true; } - return ctype_digit((string)$value); + return ctype_digit((string) $value); } /** diff --git a/src/Rules/Numeric.php b/src/Rules/Numeric.php index 5e2d967..85db62e 100644 --- a/src/Rules/Numeric.php +++ b/src/Rules/Numeric.php @@ -13,9 +13,6 @@ class Numeric implements ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { @@ -23,7 +20,7 @@ public function passes($value, array $parameters, array $row): bool return true; } - return is_numeric((string)$value); + return is_numeric((string) $value); } /** diff --git a/src/Rules/Required.php b/src/Rules/Required.php index 8b4fb70..29da242 100644 --- a/src/Rules/Required.php +++ b/src/Rules/Required.php @@ -13,9 +13,6 @@ class Required implements ValidationRuleInterface * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Rules/RequiredIf.php b/src/Rules/RequiredIf.php index 0f3b8a1..5089e2c 100644 --- a/src/Rules/RequiredIf.php +++ b/src/Rules/RequiredIf.php @@ -20,20 +20,17 @@ public function allowedParameters(): array // marked as :other_field and an array of values // which are allowed for the dependent field marked // as :other_values - return [ ':other_field', ':other_values' ]; + return [':other_field', ':other_values']; } /** * Should return an array of parameter values as strings * parsed in the same order and format as allowedParameters(). * This will aid in mapping our parameters to their placeholders. - * - * @param array $parameters - * @return array */ public function parseParameterValues(array $parameters): array { - return [ array_shift($parameters), implode(',', $parameters) ]; + return [array_shift($parameters), implode(',', $parameters)]; } /** @@ -41,9 +38,6 @@ public function parseParameterValues(array $parameters): array * actual validation. If the validation passes return true else false. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { @@ -51,9 +45,7 @@ public function passes($value, array $parameters, array $row): bool $otherValues = $parameters; if (in_array($row[$otherField], $otherValues)) { - return null !== $value && '' !== $value; - } return true; diff --git a/src/Rules/Url.php b/src/Rules/Url.php index 5eb34d5..d92cd03 100644 --- a/src/Rules/Url.php +++ b/src/Rules/Url.php @@ -30,9 +30,6 @@ class Url implements ValidationRuleInterface * Determine if the validation rule passes. * * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index c1afd99..67d1f80 100755 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -4,8 +4,8 @@ namespace Oshomo\CsvUtils\Validator; -use Oshomo\CsvUtils\Contracts\ConverterHandlerInterface; use Oshomo\CsvUtils\Contracts\ArrayParameterizedRuleInterface; +use Oshomo\CsvUtils\Contracts\ConverterHandlerInterface; use Oshomo\CsvUtils\Contracts\ParameterizedRuleInterface; use Oshomo\CsvUtils\Contracts\ValidationRuleInterface; use Oshomo\CsvUtils\Contracts\ValidationRuleInterface as ValidationRule; diff --git a/tests/src/UppercaseRule.php b/tests/src/UppercaseRule.php index 2862a22..5af9ba9 100644 --- a/tests/src/UppercaseRule.php +++ b/tests/src/UppercaseRule.php @@ -8,9 +8,6 @@ class UppercaseRule implements ValidationRuleInterface { /** * @param mixed $value - * @param array $parameters - * @param array $row - * @return bool */ public function passes($value, array $parameters, array $row): bool { From 5465a2b8e59f9eaaabe7b8a3c0906ca1b42ef78f Mon Sep 17 00:00:00 2001 From: xanish Date: Wed, 18 Aug 2021 15:24:05 +0530 Subject: [PATCH 13/21] Fixed code-coverage for test cases --- tests/data/alpha_num_test.csv | 2 +- tests/data/in_test.csv | 1 + tests/data/integer_test.csv | 4 ++-- tests/data/numeric_test.csv | 4 ++-- tests/data/required_if_test.csv | 1 + tests/src/CsvValidatorTest.php | 5 +++++ 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/data/alpha_num_test.csv b/tests/data/alpha_num_test.csv index 9928625..99c6f39 100644 --- a/tests/data/alpha_num_test.csv +++ b/tests/data/alpha_num_test.csv @@ -1,2 +1,2 @@ name,address,stars,contact,uri -Well Health Hotels,Inga N. P.O. Box 567,A,Kasper Zen,http//:well.org +Well Health Hotels,Inga N. P.O. Box 567,3,,http//:well.org diff --git a/tests/data/in_test.csv b/tests/data/in_test.csv index 9ade8c4..d8c7e4f 100644 --- a/tests/data/in_test.csv +++ b/tests/data/in_test.csv @@ -1,2 +1,3 @@ name,address,stars,contact,uri Well Health Hotels,Inga N. P.O. Box 567,2,Kasper Zen,http//:well.org +Bad Health Hotels,Inga N. P.O. Box 568,2,,http//:well.org diff --git a/tests/data/integer_test.csv b/tests/data/integer_test.csv index 1dd1758..b80dc05 100644 --- a/tests/data/integer_test.csv +++ b/tests/data/integer_test.csv @@ -1,2 +1,2 @@ -name,address,stars,contact,uri -Well Health Hotels,Inga N. P.O. Box 567,5.5,Kasper Zen,http//:well.org +id,name,address,stars,contact,uri +,Well Health Hotels,Inga N. P.O. Box 567,5.5,Kasper Zen,http//:well.org diff --git a/tests/data/numeric_test.csv b/tests/data/numeric_test.csv index 9928625..4084d72 100644 --- a/tests/data/numeric_test.csv +++ b/tests/data/numeric_test.csv @@ -1,2 +1,2 @@ -name,address,stars,contact,uri -Well Health Hotels,Inga N. P.O. Box 567,A,Kasper Zen,http//:well.org +id,name,address,stars,contact,uri +,Well Health Hotels,Inga N. P.O. Box 567,A,Kasper Zen,http//:well.org diff --git a/tests/data/required_if_test.csv b/tests/data/required_if_test.csv index 99c6f39..a0e853f 100644 --- a/tests/data/required_if_test.csv +++ b/tests/data/required_if_test.csv @@ -1,2 +1,3 @@ name,address,stars,contact,uri Well Health Hotels,Inga N. P.O. Box 567,3,,http//:well.org +Bad Health Hotels,Inga N. P.O. Box 568,2,,http//:well.org diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index 87fbc15..7b7c771 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -42,6 +42,7 @@ public function testAlphaValidationRule() $validator = new Validator($file, ',', [ 'name' => ['alpha'], + 'contact' => ['alpha'], ]); $this->assertTrue($validator->fails()); @@ -68,6 +69,7 @@ public function testAlphaNumValidationRule() $validator = new Validator($file, ',', [ 'address' => ['alpha_num'], + 'contact' => ['alpha_num'], ]); $this->assertTrue($validator->fails()); @@ -146,6 +148,7 @@ public function testInValidationRule() $validator = new Validator($file, ',', [ 'stars' => ['in:3,5,8,10'], + 'contact' => ['in:Kasper Zen'], ]); $this->assertTrue($validator->fails()); @@ -172,6 +175,7 @@ public function testIntegerValidationRule() $validator = new Validator($file, ',', [ 'stars' => ['integer'], + 'id' => ['integer'], ]); $this->assertTrue($validator->fails()); @@ -198,6 +202,7 @@ public function testNumericValidationRule() $validator = new Validator($file, ',', [ 'stars' => ['numeric'], + 'id' => ['numeric'], ]); $this->assertTrue($validator->fails()); From 042a76c1c6be6e7e4e6721c9b8b3f1f391def563 Mon Sep 17 00:00:00 2001 From: xanish Date: Wed, 8 Sep 2021 12:55:51 +0530 Subject: [PATCH 14/21] Created min and max rules. Generalised min, max and between rules to work for both strings and numbers. --- src/Helpers/ExtractsAttributeSizeAndType.php | 32 +++++++++ src/Rules/Between.php | 15 +++- src/Rules/Max.php | 43 ++++++++++++ src/Rules/Min.php | 43 ++++++++++++ tests/data/min_max_test.csv | 2 + tests/src/CsvValidatorTest.php | 72 +++++++++++++++++++- 6 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 src/Helpers/ExtractsAttributeSizeAndType.php create mode 100644 src/Rules/Max.php create mode 100644 src/Rules/Min.php create mode 100644 tests/data/min_max_test.csv diff --git a/src/Helpers/ExtractsAttributeSizeAndType.php b/src/Helpers/ExtractsAttributeSizeAndType.php new file mode 100644 index 0000000..541c66c --- /dev/null +++ b/src/Helpers/ExtractsAttributeSizeAndType.php @@ -0,0 +1,32 @@ +getSize($value); list($min, $max) = $parameters; - return $size >= (int) $min && $size <= (int) $max; + $this->type = $this->getType($value); + + return $size >= $min && $size <= $max; } /** @@ -33,6 +40,8 @@ public function passes($value, array $parameters, array $row): bool */ public function message(): string { - return 'The :attribute value :value is not between :min - :max on line :line.'; + return 'numeric' === $this->type ? + 'The :attribute value :value must be between :min and :max on line :line.' : + 'The :attribute value :value must be between :min and :max characters on line :line.'; } } diff --git a/src/Rules/Max.php b/src/Rules/Max.php new file mode 100644 index 0000000..086f835 --- /dev/null +++ b/src/Rules/Max.php @@ -0,0 +1,43 @@ +type = $this->getType($value); + + return $this->getSize($value) <= $max; + } + + /** + * Get the validation error message. + */ + public function message(): string + { + return 'numeric' === $this->type ? + 'The :attribute value :value may not be greater than :max on line :line.' : + 'The :attribute value :value may not be greater than :max characters on line :line.'; + } +} diff --git a/src/Rules/Min.php b/src/Rules/Min.php new file mode 100644 index 0000000..5a57070 --- /dev/null +++ b/src/Rules/Min.php @@ -0,0 +1,43 @@ +type = $this->getType($value); + + return $this->getSize($value) >= $min; + } + + /** + * Get the validation error message. + */ + public function message(): string + { + return 'numeric' === $this->type ? + 'The :attribute value :value may not be less than :min on line :line.' : + 'The :attribute value :value may not be less than :min characters on line :line.'; + } +} diff --git a/tests/data/min_max_test.csv b/tests/data/min_max_test.csv new file mode 100644 index 0000000..d868f8a --- /dev/null +++ b/tests/data/min_max_test.csv @@ -0,0 +1,2 @@ +name,address,stars,contact,uri +Well Health Hotels,Inga N. P.O. Box 567,3,Kasper Zen,http//:well.org diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index 7b7c771..b303416 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -121,6 +121,7 @@ public function testBetweenValidationRule() $file = $this->testAssets . '/between_test.csv'; $validator = new Validator($file, ',', [ + 'name' => ['between:5,15'], 'stars' => ['between:4,10'], ]); @@ -137,7 +138,12 @@ public function testBetweenValidationRule() ); $this->assertContains( - 'The stars value 3 is not between 4 - 10 on line 2.', + 'The name value Well Health Hotels must be between 5 and 15 characters on line 2.', + $validator->errors()['data'][0]['errors'] + ); + + $this->assertContains( + 'The stars value 3 must be between 4 and 10 on line 2.', $validator->errors()['data'][0]['errors'] ); } @@ -196,6 +202,70 @@ public function testIntegerValidationRule() ); } + public function testMaxValidationRule() + { + $file = $this->testAssets . '/min_max_test.csv'; + + $validator = new Validator($file, ',', [ + 'name' => ['max:10'], + 'stars' => ['max:1'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The name value Well Health Hotels may not be greater than 10 characters on line 2.', + $validator->errors()['data'][0]['errors'] + ); + + $this->assertContains( + 'The stars value 3 may not be greater than 1 on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + + public function testMinValidationRule() + { + $file = $this->testAssets . '/min_max_test.csv'; + + $validator = new Validator($file, ',', [ + 'name' => ['min:30'], + 'stars' => ['min:4'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The name value Well Health Hotels may not be less than 30 characters on line 2.', + $validator->errors()['data'][0]['errors'] + ); + + $this->assertContains( + 'The stars value 3 may not be less than 4 on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + public function testNumericValidationRule() { $file = $this->testAssets . '/numeric_test.csv'; From 3cad48fb824370fcfd15361c0942d1312dde7447 Mon Sep 17 00:00:00 2001 From: xanish Date: Wed, 8 Sep 2021 14:19:12 +0530 Subject: [PATCH 15/21] Updated validation rule docs --- README.md | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d417b8c..786c3f6 100644 --- a/README.md +++ b/README.md @@ -96,25 +96,20 @@ You may also utilize other place-holders in validation messages. For example the ##### Available rules -`between:min,max`: -``` -Validates that a cell value is between a :min and :max. The rule exposes the :min and :max placeholder for inline messages -``` -`ascii_only`: -``` -Validates that a cell value does not contain a non-ascii character -``` -`url`: -``` -Validates that a cell value is a valid URL. By valid URL we mean - -(#protocol) -(#basic auth) -(#a domain name or #an IP address or #an IPv6 address) -(#a port(optional)) then -(#a /, nothing, a / with something, a query or a fragment) - -``` +| Rule | Description | +| --- | --- | +| `alpha` | Validates that a cell value contains only lower and upper case alphabets | +| `alpha_num` | Validates that a cell value contains only numbers, lower and upper case alphabets | +| `ascii_only` | Validates that a cell value does not contain a non-ascii character | +| `between:min,max` | Validates that a cell value is between a :min and :max. The rule exposes the :min and :max placeholder for inline messages | +| `in:foo,bar,baz...` | Validates that a cell value is one of the values specified by the rule | +| `integer` | Validates that a cell has an integer value | +| `max:max_val` | Validates that a cell value must be less than or equal to max_val. In case of strings the length of cell value must be less than or equal or max_val | +| `min:min_val` | Validates that a cell value must be greater than or equal to min_val. In case of strings the length of cell value must be greater than or equal or min_val | +| `numeric` | Validates that a cell has a numeric value | +| `required` | Validates that a cell cannot be empty | +| `required_if:other_column,other_column_val` | Validates that a cell value must be present if a column specified by other_column has the value as other_column_val | +| `url` | Validates that a cell value is a valid URL. By valid URL we mean
(#protocol)
(#basic auth)
(#a domain name or #an IP address or #an IPv6 address)
(#a port(optional)) then
(#a /, nothing, a / with something, a query or a fragment) | ##### Writing CSV Output Data From 4d1a4974cca27897f61face3caf94336b61e7070 Mon Sep 17 00:00:00 2001 From: xanish Date: Fri, 24 Sep 2021 14:30:27 +0530 Subject: [PATCH 16/21] Added optional trimming to csv cells --- src/Validator/Validator.php | 23 +++++++++++++++++++++++ tests/data/alpha_num_test.csv | 2 +- tests/src/CsvValidatorTest.php | 4 ++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 67d1f80..f5060ac 100755 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -98,6 +98,13 @@ class Validator */ protected $rules; + /** + * Enable csv row value trimming. + * + * @var bool + */ + protected $trimCells = false; + /** * The array of custom error messages. * @@ -177,6 +184,11 @@ protected function passes(): bool if (false !== ($handle = fopen($this->filePath, 'r'))) { while (false !== ($row = fgetcsv($handle, 0, $this->delimiter))) { ++$this->currentRowLineNumber; + + if ($this->trimCells) { + $row = array_map('trim', $row); + } + if (empty($this->headers)) { $this->setHeaders($row); continue; @@ -415,4 +427,15 @@ protected function getValue(string $attribute) { return $this->currentRow[$attribute]; } + + /** + * Set if cell values should be trimmed + * before validation. + * + * @return void + */ + public function enableCellValueTrim(bool $trimValues = false) + { + $this->trimCells = $trimValues; + } } diff --git a/tests/data/alpha_num_test.csv b/tests/data/alpha_num_test.csv index 99c6f39..594214f 100644 --- a/tests/data/alpha_num_test.csv +++ b/tests/data/alpha_num_test.csv @@ -1,2 +1,2 @@ name,address,stars,contact,uri -Well Health Hotels,Inga N. P.O. Box 567,3,,http//:well.org + Well Health Hotels ,Inga N. P.O. Box 567,3,,http//:well.org diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index b303416..37b20a4 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -45,6 +45,8 @@ public function testAlphaValidationRule() 'contact' => ['alpha'], ]); + $validator->enableCellValueTrim(true); + $this->assertTrue($validator->fails()); $this->assertSame( @@ -72,6 +74,8 @@ public function testAlphaNumValidationRule() 'contact' => ['alpha_num'], ]); + $validator->enableCellValueTrim(true); + $this->assertTrue($validator->fails()); $this->assertSame( From e81839632ee4c42f01a0decb2c75fd3d37c9fe5c Mon Sep 17 00:00:00 2001 From: xanish Date: Fri, 24 Sep 2021 15:33:20 +0530 Subject: [PATCH 17/21] Removed generalised min, max and between functionality for string and numbers since it doesnt work as expected, would require dependence on all available rules and value type. --- src/Helpers/ExtractsAttributeSizeAndType.php | 32 -------------------- src/Rules/Between.php | 15 ++------- src/Rules/Max.php | 15 +++------ src/Rules/Min.php | 15 +++------ tests/src/CsvValidatorTest.php | 18 ----------- 5 files changed, 10 insertions(+), 85 deletions(-) delete mode 100644 src/Helpers/ExtractsAttributeSizeAndType.php diff --git a/src/Helpers/ExtractsAttributeSizeAndType.php b/src/Helpers/ExtractsAttributeSizeAndType.php deleted file mode 100644 index 541c66c..0000000 --- a/src/Helpers/ExtractsAttributeSizeAndType.php +++ /dev/null @@ -1,32 +0,0 @@ -getSize($value); - list($min, $max) = $parameters; - $this->type = $this->getType($value); - - return $size >= $min && $size <= $max; + return $value >= $min && $value <= $max; } /** @@ -40,8 +31,6 @@ public function passes($value, array $parameters, array $row): bool */ public function message(): string { - return 'numeric' === $this->type ? - 'The :attribute value :value must be between :min and :max on line :line.' : - 'The :attribute value :value must be between :min and :max characters on line :line.'; + return 'The :attribute value :value must be between :min and :max on line :line.'; } } diff --git a/src/Rules/Max.php b/src/Rules/Max.php index 086f835..3be2598 100644 --- a/src/Rules/Max.php +++ b/src/Rules/Max.php @@ -1,17 +1,14 @@ type = $this->getType($value); - - return $this->getSize($value) <= $max; + return $value <= $max; } /** @@ -36,8 +31,6 @@ public function passes($value, array $parameters, array $row): bool */ public function message(): string { - return 'numeric' === $this->type ? - 'The :attribute value :value may not be greater than :max on line :line.' : - 'The :attribute value :value may not be greater than :max characters on line :line.'; + return 'The :attribute value :value may not be greater than :max on line :line.'; } } diff --git a/src/Rules/Min.php b/src/Rules/Min.php index 5a57070..af8dba4 100644 --- a/src/Rules/Min.php +++ b/src/Rules/Min.php @@ -1,17 +1,14 @@ type = $this->getType($value); - - return $this->getSize($value) >= $min; + return $value >= $min; } /** @@ -36,8 +31,6 @@ public function passes($value, array $parameters, array $row): bool */ public function message(): string { - return 'numeric' === $this->type ? - 'The :attribute value :value may not be less than :min on line :line.' : - 'The :attribute value :value may not be less than :min characters on line :line.'; + return 'The :attribute value :value may not be less than :min on line :line.'; } } diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index 37b20a4..6720af6 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -125,7 +125,6 @@ public function testBetweenValidationRule() $file = $this->testAssets . '/between_test.csv'; $validator = new Validator($file, ',', [ - 'name' => ['between:5,15'], 'stars' => ['between:4,10'], ]); @@ -141,11 +140,6 @@ public function testBetweenValidationRule() $validator->errors()['data'][0] ); - $this->assertContains( - 'The name value Well Health Hotels must be between 5 and 15 characters on line 2.', - $validator->errors()['data'][0]['errors'] - ); - $this->assertContains( 'The stars value 3 must be between 4 and 10 on line 2.', $validator->errors()['data'][0]['errors'] @@ -211,7 +205,6 @@ public function testMaxValidationRule() $file = $this->testAssets . '/min_max_test.csv'; $validator = new Validator($file, ',', [ - 'name' => ['max:10'], 'stars' => ['max:1'], ]); @@ -227,11 +220,6 @@ public function testMaxValidationRule() $validator->errors()['data'][0] ); - $this->assertContains( - 'The name value Well Health Hotels may not be greater than 10 characters on line 2.', - $validator->errors()['data'][0]['errors'] - ); - $this->assertContains( 'The stars value 3 may not be greater than 1 on line 2.', $validator->errors()['data'][0]['errors'] @@ -243,7 +231,6 @@ public function testMinValidationRule() $file = $this->testAssets . '/min_max_test.csv'; $validator = new Validator($file, ',', [ - 'name' => ['min:30'], 'stars' => ['min:4'], ]); @@ -259,11 +246,6 @@ public function testMinValidationRule() $validator->errors()['data'][0] ); - $this->assertContains( - 'The name value Well Health Hotels may not be less than 30 characters on line 2.', - $validator->errors()['data'][0]['errors'] - ); - $this->assertContains( 'The stars value 3 may not be less than 4 on line 2.', $validator->errors()['data'][0]['errors'] From c8d297f0efc02bc51da4669c1d982f7f7aa8f16e Mon Sep 17 00:00:00 2001 From: xanish Date: Fri, 24 Sep 2021 15:39:50 +0530 Subject: [PATCH 18/21] Added min and max length validators --- src/Rules/MaxLength.php | 36 +++++++++++++++++++++++ src/Rules/MinLength.php | 36 +++++++++++++++++++++++ tests/src/CsvValidatorTest.php | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 src/Rules/MaxLength.php create mode 100644 src/Rules/MinLength.php diff --git a/src/Rules/MaxLength.php b/src/Rules/MaxLength.php new file mode 100644 index 0000000..edc6aac --- /dev/null +++ b/src/Rules/MaxLength.php @@ -0,0 +1,36 @@ += $length; + } + + /** + * Get the validation error message. + */ + public function message(): string + { + return 'The :attribute value :value may not have less than :length characters on line :line.'; + } +} diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index 6720af6..f784022 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -226,6 +226,32 @@ public function testMaxValidationRule() ); } + public function testMaxLengthValidationRule() + { + $file = $this->testAssets . '/min_max_test.csv'; + + $validator = new Validator($file, ',', [ + 'name' => ['max_length:15'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The name value Well Health Hotels may not have more than 15 characters on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + public function testMinValidationRule() { $file = $this->testAssets . '/min_max_test.csv'; @@ -252,6 +278,32 @@ public function testMinValidationRule() ); } + public function testMinLengthValidationRule() + { + $file = $this->testAssets . '/min_max_test.csv'; + + $validator = new Validator($file, ',', [ + 'name' => ['min_length:20'], + ]); + + $this->assertTrue($validator->fails()); + + $this->assertSame( + $validator::ERROR_MESSAGE, + $validator->errors()['message'] + ); + + $this->assertArrayHasKey( + 'errors', + $validator->errors()['data'][0] + ); + + $this->assertContains( + 'The name value Well Health Hotels may not have less than 20 characters on line 2.', + $validator->errors()['data'][0]['errors'] + ); + } + public function testNumericValidationRule() { $file = $this->testAssets . '/numeric_test.csv'; From aaf5e8bddeaebb7d10952ad91292c4a4a3dbf25c Mon Sep 17 00:00:00 2001 From: xanish Date: Fri, 24 Sep 2021 15:58:19 +0530 Subject: [PATCH 19/21] Added typecasting for values in min, max and between rules --- src/Rules/Between.php | 2 +- src/Rules/Max.php | 2 +- src/Rules/Min.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Rules/Between.php b/src/Rules/Between.php index aca16a8..12c023c 100644 --- a/src/Rules/Between.php +++ b/src/Rules/Between.php @@ -23,7 +23,7 @@ public function passes($value, array $parameters, array $row): bool { list($min, $max) = $parameters; - return $value >= $min && $value <= $max; + return +$value >= +$min && +$value <= +$max; } /** diff --git a/src/Rules/Max.php b/src/Rules/Max.php index 3be2598..92d4b5c 100644 --- a/src/Rules/Max.php +++ b/src/Rules/Max.php @@ -23,7 +23,7 @@ public function passes($value, array $parameters, array $row): bool { list($max) = $parameters; - return $value <= $max; + return +$value <= +$max; } /** diff --git a/src/Rules/Min.php b/src/Rules/Min.php index af8dba4..e026352 100644 --- a/src/Rules/Min.php +++ b/src/Rules/Min.php @@ -23,7 +23,7 @@ public function passes($value, array $parameters, array $row): bool { list($min) = $parameters; - return $value >= $min; + return +$value >= +$min; } /** From 6c96eafb700284622f8a0e465f121f61c8cb796c Mon Sep 17 00:00:00 2001 From: xanish Date: Fri, 24 Sep 2021 16:01:08 +0530 Subject: [PATCH 20/21] Updated docs for min, max, min_length and max_length rules --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 786c3f6..eb5700f 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,10 @@ You may also utilize other place-holders in validation messages. For example the | `between:min,max` | Validates that a cell value is between a :min and :max. The rule exposes the :min and :max placeholder for inline messages | | `in:foo,bar,baz...` | Validates that a cell value is one of the values specified by the rule | | `integer` | Validates that a cell has an integer value | -| `max:max_val` | Validates that a cell value must be less than or equal to max_val. In case of strings the length of cell value must be less than or equal or max_val | -| `min:min_val` | Validates that a cell value must be greater than or equal to min_val. In case of strings the length of cell value must be greater than or equal or min_val | +| `max:max_val` | Validates that a cell value must be less than or equal to max_val. | +| `max_length:length` | Validates that a cell value must contain less than or equal to length characters. | +| `min:min_val` | Validates that a cell value must be greater than or equal to min_val. | +| `min_length:length` | Validates that a cell value must contain greater than or equal to length characters. | | `numeric` | Validates that a cell has a numeric value | | `required` | Validates that a cell cannot be empty | | `required_if:other_column,other_column_val` | Validates that a cell value must be present if a column specified by other_column has the value as other_column_val | From 0045669a1a9449887e14f7215f7ac43d3d00861d Mon Sep 17 00:00:00 2001 From: xanish Date: Thu, 23 Dec 2021 14:10:38 +0530 Subject: [PATCH 21/21] Rename enableCellValueTrim to setShouldTrim --- src/Validator/Validator.php | 8 ++++---- tests/src/CsvValidatorTest.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index f5060ac..0918837 100755 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -103,7 +103,7 @@ class Validator * * @var bool */ - protected $trimCells = false; + protected $shouldTrim = false; /** * The array of custom error messages. @@ -185,7 +185,7 @@ protected function passes(): bool while (false !== ($row = fgetcsv($handle, 0, $this->delimiter))) { ++$this->currentRowLineNumber; - if ($this->trimCells) { + if ($this->shouldTrim) { $row = array_map('trim', $row); } @@ -434,8 +434,8 @@ protected function getValue(string $attribute) * * @return void */ - public function enableCellValueTrim(bool $trimValues = false) + public function setShouldTrim(bool $shouldTrim = false) { - $this->trimCells = $trimValues; + $this->shouldTrim = $shouldTrim; } } diff --git a/tests/src/CsvValidatorTest.php b/tests/src/CsvValidatorTest.php index f784022..eede04b 100755 --- a/tests/src/CsvValidatorTest.php +++ b/tests/src/CsvValidatorTest.php @@ -45,7 +45,7 @@ public function testAlphaValidationRule() 'contact' => ['alpha'], ]); - $validator->enableCellValueTrim(true); + $validator->setShouldTrim(true); $this->assertTrue($validator->fails()); @@ -74,7 +74,7 @@ public function testAlphaNumValidationRule() 'contact' => ['alpha_num'], ]); - $validator->enableCellValueTrim(true); + $validator->setShouldTrim(true); $this->assertTrue($validator->fails());