From 4ffca1354352a75110e95e2b4f038b5c5e970817 Mon Sep 17 00:00:00 2001 From: phpdevcommunity Date: Sun, 26 Jan 2025 13:45:33 +0000 Subject: [PATCH 1/3] mplement Item and Collection validation features --- README.md | 75 ++++++++++++++++++ src/Assert/AbstractValidator.php | 2 + src/Assert/Boolean.php | 34 ++++++++ src/Assert/Collection.php | 68 ++++++++++++++++ src/Assert/Item.php | 56 +++++++++++++ src/Assert/NotEmpty.php | 26 +++++++ src/Assert/StringLength.php | 2 +- src/Validation.php | 38 ++++----- src/ValidationProcessor.php | 34 ++++++++ tests/ValidationTest.php | 130 +++++++++++++++++++++++++++++++ 10 files changed, 442 insertions(+), 23 deletions(-) create mode 100755 src/Assert/Boolean.php create mode 100755 src/Assert/Collection.php create mode 100755 src/Assert/Item.php create mode 100755 src/Assert/NotEmpty.php create mode 100755 src/ValidationProcessor.php diff --git a/README.md b/README.md index f3a9cbd..0a6d238 100755 --- a/README.md +++ b/README.md @@ -103,6 +103,81 @@ if ($validation->validateArray($data) === true) { } ``` +#### Example: Validating Nested Objects with `Item` + +The `Item` rule allows you to validate nested objects or associative arrays with specific rules for each key. + +```php +use PhpDevCommunity\Validator\Validation; +use PhpDevCommunity\Validator\Rules\NotNull; +use PhpDevCommunity\Validator\Rules\Item; +use PhpDevCommunity\Validator\Rules\StringLength; +use PhpDevCommunity\Validator\Rules\Alphabetic; + +// Define validation rules for a nested object (e.g., a "person" object) +$validation = new Validation([ + 'person' => [new NotNull(), new Item([ + 'first_name' => [new NotNull(), new Alphabetic(), (new StringLength())->min(3)], + 'last_name' => [new NotNull(), new Alphabetic(), (new StringLength())->min(3)], + ])] +]); + +// Example data +$data = [ + 'person' => [ + 'first_name' => 'John', + 'last_name' => 'Doe' + ] +]; + +// Validate the data +if ($validation->validateArray($data) === true) { + echo "Person object is valid!"; +} else { + $errors = $validation->getErrors(); + echo "Validation errors: " . json_encode($errors, JSON_PRETTY_PRINT); +} +``` + +#### Example: Validating Arrays of Items with `Collection` + +The `Collection` rule is used to validate arrays where each item in the array must satisfy a set of rules. + +```php +use PhpDevCommunity\Validator\Validation; +use PhpDevCommunity\Validator\Rules\NotEmpty; +use PhpDevCommunity\Validator\Rules\Collection; +use PhpDevCommunity\Validator\Rules\Item; +use PhpDevCommunity\Validator\Rules\NotNull; +use PhpDevCommunity\Validator\Rules\StringLength; + +// Define validation rules for a collection of articles +$validation = new Validation([ + 'articles' => [new NotEmpty(), new Collection([ + new Item([ + 'title' => [new NotNull(), (new StringLength())->min(3)], + 'body' => [new NotNull(), (new StringLength())->min(10)], + ]) + ])] +]); + +// Example data +$data = [ + 'articles' => [ + ['title' => 'Article 1', 'body' => 'This is the body of the first article.'], + ['title' => 'Article 2', 'body' => 'Second article body here.'] + ] +]; + +// Validate the data +if ($validation->validateArray($data) === true) { + echo "Articles are valid!"; +} else { + $errors = $validation->getErrors(); + echo "Validation errors: " . json_encode($errors, JSON_PRETTY_PRINT); +} +``` + #### URL Validation Validate a URL to ensure it is not null and is a valid URL format. diff --git a/src/Assert/AbstractValidator.php b/src/Assert/AbstractValidator.php index 72b9303..3f923b4 100755 --- a/src/Assert/AbstractValidator.php +++ b/src/Assert/AbstractValidator.php @@ -37,6 +37,8 @@ protected function error(string $message, array $context): void $value = method_exists($value, '__toString') ? (string)$value : get_class($value); } elseif (is_array($value)) { $value = json_encode($value); + } elseif (is_bool($value)) { + $value = $value ? 'true' : 'false'; } else { $value = (string)$value; } diff --git a/src/Assert/Boolean.php b/src/Assert/Boolean.php new file mode 100755 index 0000000..220e2e2 --- /dev/null +++ b/src/Assert/Boolean.php @@ -0,0 +1,34 @@ +error($this->message, ['value' => $value, 'type' => 'boolean']); + return false; + } + + return true; + } + + public function message(string $message): self + { + $this->message = $message; + return $this; + } +} diff --git a/src/Assert/Collection.php b/src/Assert/Collection.php new file mode 100755 index 0000000..7303576 --- /dev/null +++ b/src/Assert/Collection.php @@ -0,0 +1,68 @@ + $validators + */ + private array $validators; + private array $errors = []; + + /** + * @param array $validators + */ + public function __construct(array $validators) + { + foreach ($validators as $validator) { + if ($validator instanceof ValidatorInterface === false) { + throw new \InvalidArgumentException(sprintf('The validator must be an instance of %s', ValidatorInterface::class)); + } + } + $this->validators = $validators; + } + public function validate($value): bool + { + if ($value === null) { + return true; + } + + if (is_array($value) === false) { + $this->error($this->message, ['value' => $value, 'type' => 'collection']); + return false; + } + + $validationProcessor = new ValidationProcessor(); + $errors = []; + foreach ($value as $key => $element) { + $errors = array_merge($errors, $validationProcessor->process($this->validators, $key, $element)); + } + + if ($errors !== []) { + $this->errors = $errors; + return false; + } + + return true; + } + + public function message(string $message): self + { + $this->message = $message; + return $this; + } + + public function getErrors(): array + { + return $this->errors; + } +} diff --git a/src/Assert/Item.php b/src/Assert/Item.php new file mode 100755 index 0000000..9be87fe --- /dev/null +++ b/src/Assert/Item.php @@ -0,0 +1,56 @@ + $validators + */ + public function __construct(array $validators) + { + $this->validation = new Validation($validators); + } + + public function validate($value): bool + { + if ($value === null) { + return true; + } + + if (is_array($value) === false) { + $this->error($this->message, ['value' => $value, 'type' => 'array']); + return false; + } + + $this->validation->validateArray($value); + if ($this->validation->getErrors() !== []) { + $this->errors = $this->validation->getErrors(); + return false; + } + + return true; + } + + public function message(string $message): self + { + $this->message = $message; + return $this; + } + + public function getErrors(): array + { + return $this->errors; + } +} diff --git a/src/Assert/NotEmpty.php b/src/Assert/NotEmpty.php new file mode 100755 index 0000000..081d1d2 --- /dev/null +++ b/src/Assert/NotEmpty.php @@ -0,0 +1,26 @@ +error($this->message, ['value' => $value]); + return false; + } + + return true; + } + + public function message(string $message): self + { + $this->message = $message; + return $this; + } +} diff --git a/src/Assert/StringLength.php b/src/Assert/StringLength.php index 9e7c378..1b409b8 100755 --- a/src/Assert/StringLength.php +++ b/src/Assert/StringLength.php @@ -9,7 +9,7 @@ final class StringLength extends AbstractValidator { - private string $invalidMessage = 'Invalid type given. String expected.'; + private string $invalidMessage = '{{ value }} is not a valid string.'; private string $minMessage = '{{ value }} must be at least {{ limit }} characters long'; private string $maxMessage = '{{ value }} cannot be longer than {{ limit }} characters'; private ?int $min = null; diff --git a/src/Validation.php b/src/Validation.php index 303fabf..1d8d4fc 100755 --- a/src/Validation.php +++ b/src/Validation.php @@ -2,6 +2,8 @@ namespace PhpDevCommunity\Validator; +use PhpDevCommunity\Validator\Assert\Collection; +use PhpDevCommunity\Validator\Assert\Item; use PhpDevCommunity\Validator\Assert\ValidatorInterface; use InvalidArgumentException; use Psr\Http\Message\ServerRequestInterface; @@ -17,6 +19,8 @@ final class Validation { + private ValidationProcessor $processor; + /** * @var array */ @@ -31,6 +35,8 @@ final class Validation public function __construct(array $fieldValidators) { + $this->processor = new ValidationProcessor(); + foreach ($fieldValidators as $field => $validators) { if (!is_array($validators)) { $validators = [$validators]; @@ -66,23 +72,23 @@ public function validate(ServerRequestInterface $request): bool public function validateArray(array $data): bool { $this->data = $data; + $this->executeValidators($this->validators, $this->data); + return $this->getErrors() === []; + } + private function executeValidators(array $validatorsByField, array &$data): void + { /** * @var $validators array */ - foreach ($this->validators as $field => $validators) { - if (!isset($this->data[$field])) { - $this->data[$field] = null; - } - - foreach ($validators as $validator) { - if ($validator->validate($this->data[$field]) === false) { - $this->addError($field, (string)$validator->getError()); - } + foreach ($validatorsByField as $field => $validators) { + if (!isset($data[$field])) { + $data[$field] = null; } + $errors = $this->processor->process($validators, $field, $data[$field]); + $this->errors = array_merge($this->errors, $errors); } - return $this->getErrors() === []; } /** @@ -101,18 +107,6 @@ public function getData(): array return $this->data; } - /** - * Add an error for a specific field. - * - * @param string $field The field for which the error occurred - * @param string $message The error message - * @return void - */ - private function addError(string $field, string $message): void - { - $this->errors[$field][] = $message; - } - /** * Add a validator for a specific field. * diff --git a/src/ValidationProcessor.php b/src/ValidationProcessor.php new file mode 100755 index 0000000..22ae408 --- /dev/null +++ b/src/ValidationProcessor.php @@ -0,0 +1,34 @@ +validate($value) === true) { + continue; + } + if ($validator->getError()) { + $errors[$field][] = $validator->getError(); + } + + if ($validator instanceof Item || $validator instanceof Collection) { + foreach ($validator->getErrors() as $key => $error) { + $fullKey = sprintf('%s.%s', $field, $key); + $errors[$fullKey] = $error; + } + } + } + + return $errors; + } + +} \ No newline at end of file diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index e076597..f9d42ca 100755 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -5,9 +5,12 @@ use PhpDevCommunity\UniTester\TestCase; use PhpDevCommunity\Validator\Assert\Alphabetic; use PhpDevCommunity\Validator\Assert\Choice; +use PhpDevCommunity\Validator\Assert\Collection; use PhpDevCommunity\Validator\Assert\Custom; use PhpDevCommunity\Validator\Assert\Email; use PhpDevCommunity\Validator\Assert\Integer; +use PhpDevCommunity\Validator\Assert\Item; +use PhpDevCommunity\Validator\Assert\NotEmpty; use PhpDevCommunity\Validator\Assert\NotNull; use PhpDevCommunity\Validator\Assert\Numeric; use PhpDevCommunity\Validator\Assert\StringLength; @@ -32,6 +35,10 @@ protected function execute(): void { $this->testOk(); $this->testError(); + $this->testPersonValidation(); + $this->testEmailValidation(); + $this->testTagsValidation(); + $this->testArticlesValidation(); } public function testOk() @@ -95,5 +102,128 @@ public function testError() $this->assertStrictEquals($errors['email'][0], 'dev@phpdevcommunity is not a valid email address.'); $this->assertStrictEquals($errors['active'][0], '"yes" is not valid'); } + public function testPersonValidation(): void + { + $validation = new Validation([ + 'person' => [new NotEmpty(), new Item([ + 'first_name' => [new NotNull(), new Alphabetic(), (new StringLength())->min(3)], + 'last_name' => [new NotNull(), new Alphabetic(), (new StringLength())->min(3)], + ])] + ]); + + $input = [ + 'person' => [ + 'first_name' => 'John', + 'last_name' => 'Doe' + ] + ]; + + $result = $validation->validate(Request::create($input)); + $this->assertTrue($result); + $this->assertEmpty($validation->getErrors()); + + $invalidInput = [ + 'person' => [ + 'first_name' => '', + 'last_name' => null + ] + ]; + + $result = $validation->validate(Request::create($invalidInput)); + $this->assertFalse($result); + $this->assertNotEmpty($validation->getErrors()); + } + + public function testEmailValidation(): void + { + $validation = new Validation([ + 'email' => [new NotNull(), new Email()] + ]); + + $input = ['email' => 'test@example.com']; + $result = $validation->validate(Request::create($input)); + $this->assertTrue($result); + $this->assertEmpty($validation->getErrors()); + + $invalidInput = ['email' => 'invalid-email']; + $result = $validation->validate(Request::create($invalidInput)); + $this->assertFalse($result); + $this->assertNotEmpty($validation->getErrors()); + } + + public function testTagsValidation(): void + { + $validation = new Validation([ + 'tags' => [new NotEmpty(), new Collection([ + (new StringLength())->min(3) + ])] + ]); + + $input = ['tags' => ['tag1', 'tag2', 'tag3']]; + $result = $validation->validate(Request::create($input)); + $this->assertTrue($result); + $this->assertEmpty($validation->getErrors()); + + $invalidInput = ['tags' => ['a', 'bc']]; + $result = $validation->validate(Request::create($invalidInput)); + $this->assertFalse($result); + $this->assertNotEmpty($validation->getErrors()); + $this->assertStrictEquals(2, count($validation->getErrors())); + + } + + public function testArticlesValidation(): void + { + $validation = new Validation([ + 'articles' => [new NotEmpty(), new Collection([ + new Item([ + 'title' => [new NotEmpty(), (new StringLength())->min(3)], + 'body' => [new NotNull(), (new StringLength())->min(3)], + 'user' => new Item([ + 'email' => [new Email()] + ]) + ]) + ])] + ]); + + $input = [ + 'articles' => [ + [ + 'title' => 'Article 1', + 'body' => 'This is the body of the article.', + 'user' => ['email' => 'user1@example.com'] + ], + [ + 'title' => 'Article 2', + 'body' => 'Another body.', + 'user' => ['email' => 'user2@example.com'] + ] + ] + ]; + + $result = $validation->validate(Request::create($input)); + $this->assertTrue($result); + $this->assertEmpty($validation->getErrors()); + + $invalidInput = [ + 'articles' => [ + [ + 'title' => '', + 'body' => '', + 'user' => ['email' => 'invalid-email'] + ], + [ + 'title' => '', + 'body' => '', + 'user' => ['email' => 'invalid-email'] + ] + ] + ]; + + $result = $validation->validate(Request::create($invalidInput)); + $this->assertFalse($result); + $this->assertNotEmpty($validation->getErrors()); + $this->assertStrictEquals(6, count($validation->getErrors())); + } } From 11bf0c404f098e430e766863a80d1b5e24ce5fa7 Mon Sep 17 00:00:00 2001 From: phpdevcommunity Date: Sun, 26 Jan 2025 14:34:15 +0000 Subject: [PATCH 2/3] Added validation helpers: created shortcut functions for validators (alphabetic, alphanumeric, boolean, choice, etc.). Each helper allows easy instantiation of validators with an optional custom message. --- composer.json | 5 +- functions/helpers.php | 205 +++++++++++++++++++++++++++++++ src/Assert/AbstractValidator.php | 3 +- src/Assert/Boolean.php | 0 src/Validation.php | 3 + tests/HelperTest.php | 180 +++++++++++++++++++++++++++ 6 files changed, 393 insertions(+), 3 deletions(-) create mode 100644 functions/helpers.php mode change 100755 => 100644 src/Assert/Boolean.php create mode 100644 tests/HelperTest.php diff --git a/composer.json b/composer.json index 7f1d0ef..eadc2d3 100755 --- a/composer.json +++ b/composer.json @@ -13,7 +13,10 @@ "psr-4": { "PhpDevCommunity\\Validator\\": "src", "Test\\PhpDevCommunity\\Validator\\": "tests" - } + }, + "files": [ + "functions/helpers.php" + ] }, "minimum-stability": "alpha", "require": { diff --git a/functions/helpers.php b/functions/helpers.php new file mode 100644 index 0000000..5068945 --- /dev/null +++ b/functions/helpers.php @@ -0,0 +1,205 @@ +message($message); + } + return $validator; + } +} + +if (!function_exists('v_alphanumeric')) { + function v_alphanumeric(string $message = null): Alphanumeric + { + $validator = new Alphanumeric(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_boolean')) { + function v_boolean(string $message = null): PhpDevCommunity\Validator\Assert\Boolean + { + $validator = new Boolean(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + + +if (!function_exists('v_choice')) { + function v_choice(array $choices, string $message = null): Choice + { + $validator = new Choice($choices); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_collection')) { + function v_collection(array $validators, string $message = null): Collection + { + $validator = new Collection($validators); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_custom')) { + function v_custom(callable $validate, string $message = null): Custom + { + $validator = new Custom($validate); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + + +if (!function_exists('v_email')) { + function v_email(string $message = null): Email + { + $validator = new Email(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_integer')) { + function v_integer(?int $min, ?int $max = null,string $invalidMessage = null): PhpDevCommunity\Validator\Assert\Integer + { + $validator = new Integer(); + if ($invalidMessage !== null) { + $validator->invalidMessage($invalidMessage); + } + + if ($min !== null) { + $validator->min($min); + } + if ($max !== null) { + $validator->max($max); + } + + return $validator; + } +} + +if (!function_exists('v_item')) { + function v_item(array $validators, string $message = null): Item + { + $validator = new Item($validators); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_not_empty')) { + function v_not_empty(string $message = null): NotEmpty + { + $validator = new NotEmpty(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_not_null')) { + function v_not_null(string $message = null): NotNull + { + $validator = new NotNull(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + + +if (!function_exists('v_numeric')) { + function v_numeric(string $message = null): Numeric + { + $validator = new Numeric(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} + +if (!function_exists('v_psr7_upload_file')) { + function v_psr7_upload_file(?int $maxSize, array $allowedMimeTypes, string $message = null): Psr7UploadFile + { + $validator = new Psr7UploadFile(); + if ($message !== null) { + $validator->message($message); + } + if ($maxSize !== null) { + $validator->maxSize($maxSize); + } + $validator->mimeTypes($allowedMimeTypes); + return $validator; + } +} + +if (!function_exists('v_string_length')) { + function v_string_length(?int $min, ?int $max = null, string $invalidMessage = null): StringLength + { + $validator = new StringLength(); + if ($invalidMessage !== null) { + $validator->invalidMessage($invalidMessage); + } + + if ($min !== null) { + $validator->min($min); + } + if ($max !== null) { + $validator->max($max); + } + + return $validator; + } +} + +if (!function_exists('v_url')) { + function v_url(string $message = null): Url + { + $validator = new Url(); + if ($message !== null) { + $validator->message($message); + } + return $validator; + } +} diff --git a/src/Assert/AbstractValidator.php b/src/Assert/AbstractValidator.php index 3f923b4..95ab3f9 100755 --- a/src/Assert/AbstractValidator.php +++ b/src/Assert/AbstractValidator.php @@ -20,8 +20,7 @@ public function getError(): ?string { return $this->error; } - - + /** * Set the error message by replacing placeholders with values from the context array * diff --git a/src/Assert/Boolean.php b/src/Assert/Boolean.php old mode 100755 new mode 100644 diff --git a/src/Validation.php b/src/Validation.php index 1d8d4fc..e9cb97b 100755 --- a/src/Validation.php +++ b/src/Validation.php @@ -41,6 +41,9 @@ public function __construct(array $fieldValidators) if (!is_array($validators)) { $validators = [$validators]; } + if (!is_string($field)) { + throw new InvalidArgumentException('The field name must be a string'); + } $this->addValidator($field, $validators); } } diff --git a/tests/HelperTest.php b/tests/HelperTest.php new file mode 100644 index 0000000..26b107a --- /dev/null +++ b/tests/HelperTest.php @@ -0,0 +1,180 @@ +testVAlphabetic(); + $this->testVAlphanumeric(); + $this->testVBoolean(); + $this->testVChoice(); + $this->testVCollection(); + $this->testVCustom(); + $this->testVEmail(); + $this->testVInteger(); + $this->testVItem(); + $this->testVNotEmpty(); + $this->testVNotNull(); + $this->testVNumeric(); + $this->testVPsr7UploadFile(); + $this->testVStringLength(); + $this->testVUrl(); + } + + public function testVAlphabetic() + { + $validator = v_alphabetic('Custom error message'); + $validator->validate('123456'); + $this->assertInstanceOf(Alphabetic::class, $validator); + $this->assertEquals('Custom error message', $validator->getError()); + } + + public function testVAlphanumeric() + { + $validator = v_alphanumeric('Custom message'); + $validator->validate('ue$ueue'); + $this->assertInstanceOf(Alphanumeric::class, $validator); + $this->assertEquals('Custom message', $validator->getError()); + } + + public function testVBoolean() + { + $validator = v_boolean('Invalid boolean'); + $validator->validate(-1); + $this->assertInstanceOf(Boolean::class, $validator); + $this->assertEquals('Invalid boolean', $validator->getError()); + } + public function testVChoice() + { + $choices = ['yes', 'no']; + $validator = v_choice($choices, 'Invalid choice'); + $validator->validate('non'); + $this->assertInstanceOf(Choice::class, $validator); + $this->assertEquals('Invalid choice', $validator->getError()); + } + + + public function testVCollection() + { + $validator = v_collection([v_alphabetic(), v_numeric()], 'Invalid collection'); + $validator->validate('["123", "456"]'); + $this->assertInstanceOf(Collection::class, $validator); + $this->assertEquals('Invalid collection', $validator->getError()); + } + + public function testVCustom() + { + $validator = v_custom(function($value) { return is_string($value); }, 'Invalid custom validation'); + $validator->validate([]); + $this->assertInstanceOf(Custom::class, $validator); + $this->assertEquals('Invalid custom validation', $validator->getError()); + } + + public function testVEmail() + { + $validator = v_email('Invalid email'); + $validator->validate('testnote@.com'); + $this->assertInstanceOf(Email::class, $validator); + $this->assertEquals('Invalid email', $validator->getError()); + } + + public function testVInteger() + { + $validator = v_integer(10, 100, 'Invalid integer'); + $validator->validate(100.25); + $this->assertInstanceOf(Integer::class, $validator); + $this->assertEquals('Invalid integer', $validator->getError()); + } + + public function testVItem() + { + $validator = v_item([ + 'email' => v_alphabetic(), + 'password' => v_numeric() + ], 'Invalid item'); + $validator->validate(''); + $this->assertInstanceOf(Item::class, $validator); + $this->assertEquals('Invalid item', $validator->getError()); + } + + public function testVNotEmpty() + { + $validator = v_not_empty('Cannot be empty'); + $validator->validate(''); + $this->assertInstanceOf(NotEmpty::class, $validator); + $this->assertEquals('Cannot be empty', $validator->getError()); + } + + public function testVNotNull() + { + $validator = v_not_null('Cannot be null'); + $validator->validate(null); + $this->assertInstanceOf(NotNull::class, $validator); + $this->assertEquals('Cannot be null', $validator->getError()); + } + + public function testVNumeric() + { + $validator = v_numeric('Invalid numeric value'); + $validator->validate('100.25€'); + $this->assertInstanceOf(Numeric::class, $validator); + $this->assertEquals('Invalid numeric value', $validator->getError()); + } + + public function testVPsr7UploadFile() + { + $validator = v_psr7_upload_file(100000, ['image/jpeg'], 'Invalid file upload instance'); + $validator->validate('test.jpg'); + $this->assertInstanceOf(Psr7UploadFile::class, $validator); + $this->assertEquals('Invalid file upload instance', $validator->getError()); + } + + public function testVStringLength() + { + $validator = v_string_length(5, 100, 'String length invalid'); + $validator->validate(12345); + $this->assertInstanceOf(StringLength::class, $validator); + $this->assertEquals('String length invalid', $validator->getError()); + } + + public function testVUrl() + { + $validator = v_url('Invalid URL'); + $validator->validate('www.phpdevcommunity.com'); + $this->assertInstanceOf(Url::class, $validator); + $this->assertEquals('Invalid URL', $validator->getError()); + } + +} From 8c2d317b91517f4c70366780ad482c5403aa4067 Mon Sep 17 00:00:00 2001 From: phpdevcommunity Date: Sun, 26 Jan 2025 14:36:43 +0000 Subject: [PATCH 3/3] improve readme --- README.md | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 0a6d238..282f758 100755 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Validate an email address to ensure it is not null and matches the standard emai ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Email; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Email; // Instantiate Validation object for email validation $validation = new Validation([ @@ -52,8 +52,8 @@ Validate the age to ensure it is a non-null integer and is 18 or older. ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Integer; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Integer; // Instantiate Validation object for age validation $validation = new Validation([ @@ -82,9 +82,9 @@ Ensure that a username is not null, has a minimum length of 3 characters, and co ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Alphanumeric; -use PhpDevCommunity\Validator\Rules\StringLength; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Alphanumeric; +use PhpDevCommunity\Validator\Assert\StringLength; // Instantiate Validation object for username validation $validation = new Validation([ @@ -109,10 +109,10 @@ The `Item` rule allows you to validate nested objects or associative arrays with ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Item; -use PhpDevCommunity\Validator\Rules\StringLength; -use PhpDevCommunity\Validator\Rules\Alphabetic; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Item; +use PhpDevCommunity\Validator\Assert\StringLength; +use PhpDevCommunity\Validator\Assert\Alphabetic; // Define validation rules for a nested object (e.g., a "person" object) $validation = new Validation([ @@ -145,11 +145,11 @@ The `Collection` rule is used to validate arrays where each item in the array mu ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotEmpty; -use PhpDevCommunity\Validator\Rules\Collection; -use PhpDevCommunity\Validator\Rules\Item; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\StringLength; +use PhpDevCommunity\Validator\Assert\NotEmpty; +use PhpDevCommunity\Validator\Assert\Collection; +use PhpDevCommunity\Validator\Assert\Item; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\StringLength; // Define validation rules for a collection of articles $validation = new Validation([ @@ -184,8 +184,8 @@ Validate a URL to ensure it is not null and is a valid URL format. ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Url; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Url; // Instantiate Validation object for URL validation $validation = new Validation([ @@ -210,8 +210,8 @@ Validate a numeric value to ensure it is not null and represents a valid numeric ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Numeric; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Numeric; // Instantiate Validation object for numeric value validation $validation = new Validation([ @@ -236,8 +236,8 @@ Implement a custom validation rule using a callback function. ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Custom; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Custom; // Custom validation function to check if the value is a boolean $isBoolean = function ($value) { @@ -273,9 +273,9 @@ Suppose you have a user registration form with fields like `username`, `email`, ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Email; -use PhpDevCommunity\Validator\Rules\Integer; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Email; +use PhpDevCommunity\Validator\Assert\Integer; // Define validation rules for each field $validation = new Validation([ @@ -315,8 +315,8 @@ Consider validating input data received via an API endpoint. Here's how you can ```php use PhpDevCommunity\Validator\Validation; -use PhpDevCommunity\Validator\Rules\NotNull; -use PhpDevCommunity\Validator\Rules\Numeric; +use PhpDevCommunity\Validator\Assert\NotNull; +use PhpDevCommunity\Validator\Assert\Numeric; // Define validation rules for API input data $validation = new Validation([ @@ -351,7 +351,7 @@ In this example: ### Additional Features - **Simple Interface**: Easily define validation rules using a straightforward interface. -- **Extensible**: Extend the library with custom validation rules by implementing the `RuleInterface`. +- **Extensible**: Extend the library with custom validation rules by implementing the `ValidatorInterface`. - **Error Handling**: Retrieve detailed validation errors for each field. ---