diff --git a/docs/feature-guide.md b/docs/feature-guide.md index 7e0eadcdc..4c6184d32 100644 --- a/docs/feature-guide.md +++ b/docs/feature-guide.md @@ -28,7 +28,7 @@ $usernameValidator = v::alnum()->noWhitespace()->length(1, 15); $usernameValidator->validate('alganet'); // true ``` -## Validating object attributes +## Validating object properties Given this simple object: @@ -38,11 +38,11 @@ $user->name = 'Alexandre'; $user->birthdate = '1987-07-01'; ``` -Is possible to validate its attributes in a single chain: +Is possible to validate its properties in a single chain: ```php -$userValidator = v::attribute('name', v::stringType()->length(1, 32)) - ->attribute('birthdate', v::date()->minAge(18)); +$userValidator = v::property('name', v::stringType()->length(1, 32)) + ->property('birthdate', v::date()->minAge(18)); $userValidator->validate($user); // true ``` @@ -180,7 +180,7 @@ try { The `getMessages()` returns an array in which the keys are the name of the validators, or its reference in case you are using [Key](rules/Key.md) or -[Attribute](rules/Attribute.md) rule: +[Property](rules/Property.md) rule: ```no-highlight Array @@ -230,7 +230,7 @@ in the chain fails. ## Validator name -On `v::attribute()` and `v::key()`, `{{name}}` is the attribute/key name. For others, +On `v::property()` and `v::key()`, `{{name}}` is the property/key name. For others, is the same as the input. You can customize a validator name using: ```php diff --git a/docs/list-of-rules.md b/docs/list-of-rules.md index c6fee8bc7..9d8335418 100644 --- a/docs/list-of-rules.md +++ b/docs/list-of-rules.md @@ -157,7 +157,6 @@ - [AllOf](rules/AllOf.md) - [AnyOf](rules/AnyOf.md) -- [Attribute](rules/Attribute.md) - [Call](rules/Call.md) - [Each](rules/Each.md) - [Key](rules/Key.md) @@ -169,6 +168,7 @@ - [Nullable](rules/Nullable.md) - [OneOf](rules/OneOf.md) - [Optional](rules/Optional.md) +- [Property](rules/Property.md) - [When](rules/When.md) ## Numbers @@ -197,9 +197,9 @@ ## Objects -- [Attribute](rules/Attribute.md) - [Instance](rules/Instance.md) - [ObjectType](rules/ObjectType.md) +- [Property](rules/Property.md) ## Strings @@ -240,10 +240,10 @@ ## Structures -- [Attribute](rules/Attribute.md) - [Key](rules/Key.md) - [KeyNested](rules/KeyNested.md) - [KeySet](rules/KeySet.md) +- [Property](rules/Property.md) ## Types @@ -277,7 +277,6 @@ - [AnyOf](rules/AnyOf.md) - [ArrayType](rules/ArrayType.md) - [ArrayVal](rules/ArrayVal.md) -- [Attribute](rules/Attribute.md) - [Base](rules/Base.md) - [Base64](rules/Base64.md) - [Between](rules/Between.md) @@ -386,6 +385,7 @@ - [PostalCode](rules/PostalCode.md) - [PrimeNumber](rules/PrimeNumber.md) - [Printable](rules/Printable.md) +- [Property](rules/Property.md) - [Punct](rules/Punct.md) - [Readable](rules/Readable.md) - [Regex](rules/Regex.md) diff --git a/docs/rules/Attribute.md b/docs/rules/Attribute.md deleted file mode 100644 index acb8bfdf6..000000000 --- a/docs/rules/Attribute.md +++ /dev/null @@ -1,47 +0,0 @@ -# Attribute - -- `Attribute(string $name)` -- `Attribute(string $name, Validatable $rule)` -- `Attribute(string $name, Validatable $rule, bool $mandatory)` - -Validates an object attribute, even private ones. - -```php -$obj = new stdClass; -$obj->foo = 'bar'; - -v::attribute('foo')->validate($obj); // true -``` - -You can also validate the attribute itself: - -```php -v::attribute('foo', v::equals('bar'))->validate($obj); // true -``` - -Third parameter makes the attribute presence optional: - -```php -v::attribute('lorem', v::stringType(), false)->validate($obj); // true -``` - -The name of this validator is automatically set to the attribute name. - -## Categorization - -- Nesting -- Objects -- Structures - -## Changelog - -Version | Description ---------|------------- - 0.3.9 | Created - -*** -See also: - -- [Key](Key.md) -- [KeyNested](KeyNested.md) -- [ObjectType](ObjectType.md) diff --git a/docs/rules/Key.md b/docs/rules/Key.md index 3213910df..44706a949 100644 --- a/docs/rules/Key.md +++ b/docs/rules/Key.md @@ -44,8 +44,8 @@ Version | Description See also: - [ArrayVal](ArrayVal.md) -- [Attribute](Attribute.md) - [Each](Each.md) - [KeyNested](KeyNested.md) - [KeySet](KeySet.md) - [KeyValue](KeyValue.md) +- [Property](Property.md) diff --git a/docs/rules/KeyNested.md b/docs/rules/KeyNested.md index 803127427..7189c52f2 100644 --- a/docs/rules/KeyNested.md +++ b/docs/rules/KeyNested.md @@ -45,8 +45,8 @@ Version | Description *** See also: -- [Attribute](Attribute.md) - [Key](Key.md) - [KeyValue](KeyValue.md) +- [Property](Property.md) [Yii2 ArrayHelper]: https://github.com/yiisoft/yii2/blob/68c30c1/framework/helpers/BaseArrayHelper.php "Yii2 ArrayHelper" diff --git a/docs/rules/ObjectType.md b/docs/rules/ObjectType.md index 7e89b26f9..72d452475 100644 --- a/docs/rules/ObjectType.md +++ b/docs/rules/ObjectType.md @@ -24,7 +24,6 @@ Version | Description See also: - [ArrayType](ArrayType.md) -- [Attribute](Attribute.md) - [BoolType](BoolType.md) - [BoolVal](BoolVal.md) - [CallableType](CallableType.md) @@ -33,6 +32,7 @@ See also: - [IntType](IntType.md) - [NullType](NullType.md) - [Number](Number.md) +- [Property](Property.md) - [ResourceType](ResourceType.md) - [StringType](StringType.md) - [StringVal](StringVal.md) diff --git a/docs/rules/Property.md b/docs/rules/Property.md new file mode 100644 index 000000000..4d063da47 --- /dev/null +++ b/docs/rules/Property.md @@ -0,0 +1,48 @@ +# Property + +- `Property(string $name)` +- `Property(string $name, Validatable $rule)` +- `Property(string $name, Validatable $rule, bool $mandatory)` + +Validates an object property, even private ones. + +```php +$obj = new stdClass; +$obj->foo = 'bar'; + +v::property('foo')->validate($obj); // true +``` + +You can also validate the property itself: + +```php +v::property('foo', v::equals('bar'))->validate($obj); // true +``` + +Third parameter makes the property presence optional: + +```php +v::property('lorem', v::stringType(), false)->validate($obj); // true +``` + +The name of this validator is automatically set to the property name. + +## Categorization + +- Nesting +- Objects +- Structures + +## Changelog + +Version | Description +--------|------------- + 3.0.0 | Renamed from `Attribute` to `Property` + 0.3.9 | Created + +*** +See also: + +- [Key](Key.md) +- [KeyNested](KeyNested.md) +- [ObjectType](ObjectType.md) diff --git a/library/ChainedValidator.php b/library/ChainedValidator.php index 401b10d5b..041d2a3b7 100644 --- a/library/ChainedValidator.php +++ b/library/ChainedValidator.php @@ -30,7 +30,7 @@ public function arrayType(): ChainedValidator; public function arrayVal(): ChainedValidator; - public function attribute( + public function property( string $reference, ?Validatable $validator = null, bool $mandatory = true diff --git a/library/Exceptions/AttributeException.php b/library/Exceptions/PropertyException.php similarity index 61% rename from library/Exceptions/AttributeException.php rename to library/Exceptions/PropertyException.php index 0c351d170..1f1427077 100644 --- a/library/Exceptions/AttributeException.php +++ b/library/Exceptions/PropertyException.php @@ -9,7 +9,7 @@ namespace Respect\Validation\Exceptions; -final class AttributeException extends NestedValidationException implements NonOmissibleException +final class PropertyException extends NestedValidationException implements NonOmissibleException { public const NOT_PRESENT = 'not_present'; public const INVALID = 'invalid'; @@ -19,12 +19,12 @@ final class AttributeException extends NestedValidationException implements NonO */ protected array $defaultTemplates = [ self::MODE_DEFAULT => [ - self::NOT_PRESENT => 'Attribute {{name}} must be present', - self::INVALID => 'Attribute {{name}} must be valid', + self::NOT_PRESENT => 'Property {{name}} must be present', + self::INVALID => 'Property {{name}} must be valid', ], self::MODE_NEGATIVE => [ - self::NOT_PRESENT => 'Attribute {{name}} must not be present', - self::INVALID => 'Attribute {{name}} must not validate', + self::NOT_PRESENT => 'Property {{name}} must not be present', + self::INVALID => 'Property {{name}} must not validate', ], ]; diff --git a/library/Rules/Attribute.php b/library/Rules/Property.php similarity index 78% rename from library/Rules/Attribute.php rename to library/Rules/Property.php index debbb80ff..3ec91550e 100644 --- a/library/Rules/Attribute.php +++ b/library/Rules/Property.php @@ -15,11 +15,11 @@ use function is_object; use function property_exists; -final class Attribute extends AbstractRelated +final class Property extends AbstractRelated { - public function __construct(string $reference, ?Validatable $rule = null, bool $mandatory = true) + public function __construct(string $name, ?Validatable $rule = null, bool $mandatory = true) { - parent::__construct($reference, $rule, $mandatory); + parent::__construct($name, $rule, $mandatory); } public function getReferenceValue(mixed $input): mixed diff --git a/library/StaticValidator.php b/library/StaticValidator.php index 8ced57755..4b81e5d9a 100644 --- a/library/StaticValidator.php +++ b/library/StaticValidator.php @@ -29,7 +29,7 @@ public static function arrayType(): ChainedValidator; public static function arrayVal(): ChainedValidator; - public static function attribute( + public static function property( string $reference, ?Validatable $validator = null, bool $mandatory = true diff --git a/tests/integration/assert-with-attributes.phpt b/tests/integration/assert-with-attributes.phpt index 3cf91745c..a72d747e1 100644 --- a/tests/integration/assert-with-attributes.phpt +++ b/tests/integration/assert-with-attributes.phpt @@ -27,22 +27,22 @@ exceptionFullMessage(static function (): void { ]; $object = json_decode((string) json_encode($array)); v::create() - ->attribute( + ->property( 'mysql', v::create() - ->attribute('host', v::stringType(), true) - ->attribute('user', v::stringType(), true) - ->attribute('password', v::stringType(), true) - ->attribute('schema', v::stringType(), true), + ->property('host', v::stringType(), true) + ->property('user', v::stringType(), true) + ->property('password', v::stringType(), true) + ->property('schema', v::stringType(), true), true ) - ->attribute( + ->property( 'postgresql', v::create() - ->attribute('host', v::stringType(), true) - ->attribute('user', v::stringType(), true) - ->attribute('password', v::stringType(), true) - ->attribute('schema', v::stringType(), true), + ->property('host', v::stringType(), true) + ->property('user', v::stringType(), true) + ->property('password', v::stringType(), true) + ->property('schema', v::stringType(), true), true ) ->setName('the given data') diff --git a/tests/integration/issue-1376.phpt b/tests/integration/issue-1376.phpt index 0f3b40578..87e48aed8 100644 --- a/tests/integration/issue-1376.phpt +++ b/tests/integration/issue-1376.phpt @@ -15,10 +15,10 @@ $input = (object) [ 'author' => 'foo', ]; -$postValidator = v::attribute('title', v::length(2, 3)->stringType()) - ->attribute('description', v::stringType()) - ->attribute('author', v::intType()->length(1, 2)) - ->attribute('user', v::intVal()->length(1, 2)); +$postValidator = v::property('title', v::length(2, 3)->stringType()) + ->property('description', v::stringType()) + ->property('author', v::intType()->length(1, 2)) + ->property('user', v::intVal()->length(1, 2)); try { $postValidator->assert($input); } catch (NestedValidationException $e) { @@ -39,30 +39,30 @@ try { ?> --EXPECT-- - All of the required rules must pass for `stdClass { +$author="foo" }` - - Attribute title must be present - - Attribute description must be present + - Property title must be present + - Property description must be present - All of the required rules must pass for author - author must be of type integer - author must have a length between 1 and 2 - - Attribute user must be present + - Property user must be present array(2) { ["level"]=> int(0) ["message"]=> - string(31) "Attribute title must be present" + string(30) "Property title must be present" } array(2) { ["level"]=> int(0) ["message"]=> - string(37) "Attribute description must be present" + string(36) "Property description must be present" } array(2) { ["level"]=> int(0) ["message"]=> - string(30) "Attribute author must be valid" + string(29) "Property author must be valid" } array(2) { ["level"]=> @@ -86,5 +86,5 @@ array(2) { ["level"]=> int(0) ["message"]=> - string(30) "Attribute user must be present" + string(29) "Property user must be present" } diff --git a/tests/integration/readme/example_1.phpt b/tests/integration/readme/example_1.phpt index b09de71f0..39b03955a 100644 --- a/tests/integration/readme/example_1.phpt +++ b/tests/integration/readme/example_1.phpt @@ -16,8 +16,8 @@ $user = new stdClass(); $user->name = 'Alexandre'; $user->birthdate = '1987-07-01'; -$userValidator = v::attribute('name', v::stringType()->length(1, 32)) - ->attribute('birthdate', v::dateTime()->minAge(18)); +$userValidator = v::property('name', v::stringType()->length(1, 32)) + ->property('birthdate', v::dateTime()->minAge(18)); $userValidator->assert($user); diff --git a/tests/unit/Exceptions/NestedValidationExceptionTest.php b/tests/unit/Exceptions/NestedValidationExceptionTest.php index ca29a0033..f8bce8c4c 100644 --- a/tests/unit/Exceptions/NestedValidationExceptionTest.php +++ b/tests/unit/Exceptions/NestedValidationExceptionTest.php @@ -23,7 +23,7 @@ final class NestedValidationExceptionTest extends TestCase #[Test] public function getChildrenShouldReturnExceptionAddedByAddRelated(): void { - $composite = new AttributeException('input', 'id', [], new Formatter('strval', new KeepOriginalStringName())); + $composite = new PropertyException('input', 'id', [], new Formatter('strval', new KeepOriginalStringName())); $node = new IntValException('input', 'id', [], new Formatter('strval', new KeepOriginalStringName())); $composite->addChild($node); self::assertCount(1, $composite->getChildren()); @@ -33,7 +33,7 @@ public function getChildrenShouldReturnExceptionAddedByAddRelated(): void #[Test] public function addingTheSameInstanceShouldAddJustOneSingleReference(): void { - $composite = new AttributeException('input', 'id', [], new Formatter('strval', new KeepOriginalStringName())); + $composite = new PropertyException('input', 'id', [], new Formatter('strval', new KeepOriginalStringName())); $node = new IntValException('input', 'id', [], new Formatter('strval', new KeepOriginalStringName())); $composite->addChild($node); $composite->addChild($node); diff --git a/tests/unit/Rules/AttributeTest.php b/tests/unit/Rules/PropertyTest.php similarity index 68% rename from tests/unit/Rules/AttributeTest.php rename to tests/unit/Rules/PropertyTest.php index b5bc0ba62..b836809ba 100644 --- a/tests/unit/Rules/AttributeTest.php +++ b/tests/unit/Rules/PropertyTest.php @@ -17,57 +17,57 @@ #[Group('rule')] #[CoversClass(AbstractRelated::class)] -#[CoversClass(Attribute::class)] -final class AttributeTest extends RuleTestCase +#[CoversClass(Property::class)] +final class PropertyTest extends RuleTestCase { /** - * @return array + * @return array */ public static function providerForValidInput(): array { return [ - 'attribute is present without extra validator' => [new Attribute('public'), new WithProperties()], + 'attribute is present without extra validator' => [new Property('public'), new WithProperties()], 'private attribute is present without extra validator' => [ - new Attribute('private'), + new Property('private'), new WithProperties(), ], 'attribute is present with extra validator' => [ - new Attribute('public', new AlwaysValid()), + new Property('public', new AlwaysValid()), new WithProperties(), ], 'attribute is present but uninitialized' => [ - new Attribute('uninitialized'), + new Property('uninitialized'), new WithUninitialized(), ], 'non mandatory attribute is not present' => [ - new Attribute('nonexistent', null, false), + new Property('nonexistent', null, false), new WithProperties(), ], 'non mandatory attribute is not present with extra validator' => [ - new Attribute('nonexistent', new AlwaysValid(), false), + new Property('nonexistent', new AlwaysValid(), false), new WithProperties(), ], 'attribute is present but uninitialized with extra validator' => [ - new Attribute('uninitialized', new AlwaysValid()), + new Property('uninitialized', new AlwaysValid()), new WithUninitialized(), ], ]; } /** - * @return array + * @return array */ public static function providerForInvalidInput(): array { return [ - 'attribute is absent without extra validator' => [new Attribute('barr'), new WithProperties()], + 'attribute is absent without extra validator' => [new Property('barr'), new WithProperties()], 'private attribute is not valid based on extra validator' => [ - new Attribute('private', new AlwaysInvalid()), + new Property('private', new AlwaysInvalid()), new WithProperties(), ], - 'value provided is an empty string' => [new Attribute('barr'), ''], + 'value provided is an empty string' => [new Property('barr'), ''], 'validator related to attribute does not validate' => [ - new Attribute('public', new AlwaysInvalid()), + new Property('public', new AlwaysInvalid()), new WithProperties(), ], ];