Skip to content

Conversation

@elpete
Copy link
Contributor

@elpete elpete commented Nov 17, 2021

This PR has three main components:

Nested Constraints

Nested structs can be validated using the constraints or nestedConstraints validator.

validateOrFail(
    target = {
        "owner": { "firstName": "John", "lastName": "Doe" }
    },
    constraints = {
        "owner": {
            "constraints": {
                "firstName": { "required": true, "type": "string" },
                "lastName": { "required": true, "type": "string" },
            }
        }
    }
);

Using the nestedConstraints validator requires the item it is used on be a struct. Otherwise a validation error will occur.
When using nestedConstraints the field name of the errors will be the dot-delimited path of the target.

validateOrFail(
    target = {
        "owner": { "firstName": "John" }
    },
    constraints = {
        "owner": {
            "constraints": {
                "firstName": { "required": true, "type": "string" },
                "lastName": { "required": true, "type": "string" },
            }
        }
    }
);

// ValidationError -> { field: "owner.lastName", message: "The `lastName` field is required" }

The field name change also applies to items or arrayItem validators.

validateOrFail(
    target = {
        "luckyNumbers": [ 7, "not a number", 11 ]
    },
    constraints = {
        "luckyNumbers": {
            "items": {
                "required": true,
                "type": "numeric"
            }
        }
    }
);

// ValidationError -> { field: "luckyNumbers[2]", message: "The 'item' has an invalid type, expected type is numeric" }

The field name changes will allow you to match the validation errors to your fields in your forms.
While cbvalidation can nest constraints down as far as you'd like to go, remember that each nested level increases complexity.

Array and Struct Shorthand Syntax

To make defining array item and nested constraint validators easier, you can use a shorthand on the field name, like so:

validateOrFail(
    target = {
        "owner": {
            "firstName": "John",
            "lastName": "Doe",
            "luckyNumbers": [ 7, 11, 21 ],
            "addresses": [
                {
                    "streetOne": "123 Elm Street",
                    "city": "Anytown",
                    "state": "IL",
                    "zip": 60606
                }
            ]
        }
    },
    constraints = {
        "owner.firstName": { "required": true, "type": "string" },
        "owner.lastName": { "required": true, "type": "string" },
        "owner.luckyNumbers.*": { "required": true, "type": "numeric" },
        "owner.addresses.*.streetOne": { "required": true, "type": "string" },
        "owner.addresses.*.streetTwo": { "required": false, "type": "string" },
        "owner.addresses.*.city": { "required": true, "type": "string" },
        "owner.addresses.*.state": { "required": true, "type": "string", "size": 2 },
        "owner.addresses.*.zip": { "required": true, "type": "numeric", "size": 5 }
    }
);

Dot-delimited strings represent nested structs while the asterisk (*) represents an array of items. This shorthand syntax is expanded to the equivalent syntax above before validating. Use whichever you prefer.

Validator Aliases

A few of the built-in validators now have an alias in addition to the longform validator name:

{
    "items": "arrayItem",
    "constraints": "nestedConstraints"
}

Co-authored by @garciadev

@elpete elpete requested a review from lmajano November 17, 2021 17:46
@elpete elpete merged commit 2b2e314 into development Nov 19, 2021
@lmajano lmajano deleted the expand_object_and_array_syntax branch January 12, 2022 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants