Validation icon indicating copy to clipboard operation
Validation copied to clipboard

How to get an individual error for each missing key of an array?

Open burzum opened this issue 4 years ago • 1 comments

$user = [];

try {
    v::keyset(
        v::key('username', v::allOf(
            v::notEmpty(),
            v::length(3, 24)
        )),
        v::key('email', v::allOf(
            v::notEmpty(),
            v::email()
        )),
        v::key('password', v::allOf(
            v::notEmpty(),
            v::length(8, 60),
        )),
    )
    ->assert($data);
} catch (ValidatorException $e) {
    print_r($e->getMessages());
}

Gives me:

Array ( [keySet] => Must have keys { "username", "email", "password" } )

What I would like to get is an array like this to be able to map the erros to the form inputs:

[
     'username' => [
         'notEmpty' => 'Message...',
         'length' => 'Message...',
     ],
     'email' => [/*...*/],
     'password' => [/*...*/],
]

Is there any way to get this done? 😕

burzum avatar Sep 21 '20 23:09 burzum

I've had the same issue. After I played a little bit, I came up with this "workaround".

use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Validator as v;
// ...

try {
    $validation = new v();

    $validation->addRule(v::key('username', v::allOf(
        v::notEmpty()->setTemplate('The username must not be empty'),
        v::length(3, 24)->setTemplate('Invalid length')
    ))->setTemplate('The key "username" is required'));

    $validation->addRule(v::key('email', v::allOf(
        v::notEmpty()->setTemplate('The email must not be empty'),
        v::email()->setTemplate('Invalid email address')
    ))->setTemplate('The key "email" is required'));

    $validation->addRule(v::key('password', v::allOf(
        v::notEmpty()->setTemplate('The password must not be empty'),
        v::length(8, 60)->setTemplate('Invalid length')
    ))->setTemplate('The key "password" is required'));

    $validation->assert($data);
} catch(NestedValidationException $exception) {
    $messages = [];
    /** @var \Respect\Validation\Exceptions\ValidationException $message */
    foreach($exception->getIterator() as $message) {
        $key = $message->getParam('name');
        if($key === null) {
            continue;
        }
        $messages[$key] = $message->getMessage();
    }

    print_r($messages);
}

Optional fields can be added like this:

$validation->addRule(v::key('mobile', v::allOf(
    v::notEmpty()->setTemplate('The mobile number must not be empty'),
    v::phone()->setTemplate('Invalid phone number')
), false));

To translate the strings just use the _ or __ function from gettext.

Example:

$validation->addRule(v::key('username', v::allOf(
    v::notEmpty()->setTemplate(__('The username must not be empty')),
    v::length(3, 24)->setTemplate(__('Invalid length'))
))->setTemplate(__('The key %s is required', 'username'));

odan avatar Oct 05 '20 19:10 odan

Closing based on emoji 🎉 feedback 🐼

alganet avatar Feb 19 '23 18:02 alganet