2
votes

Currently the Validator in Laravel only appears to return one error message per field, despite the field potentially having multiple rules and messages. (Note: I'm currently passing an empty array as $data to Validator::make)

What I'm trying to do is build an array of each field's rules and messages that could potentially be re-used for front end validation. Something like this:

{
    "name": {
        "required": [
            "The name field is required."
        ],
        "max:255": [
            "The name field may not be greater than 255."
        ]
    },
    "email": {
        "required": [
            "The email field is required."
        ],
        "email": [
            "The email field must be a valid email address."
        ],
        "max:255": [
            "The email field may not be greater than 255."
        ]
    }
}

The getMessage method in Illuminate\Validation\Validator looks like it would get me close to being able to construct something myself, however it is a protected method.

Does anyone know of a way to get a Validator instance to output all rules and messages?

1

1 Answers

2
votes

Currently the Validator in Laravel only appears to return one error message per field, despite the field potentially having multiple rules and messages.

Validation of given field stops as soon as a single validation rule fails. That's the reason you're getting only single error message per field.

As of fetching the validation messages like in the example you provided, Laravel's validator does not provide such option, but you could easily achieve that by extending the Validator class.

First, create your new class:

<?php namespace Your\Namespace;

use Illuminate\Validation\Validator as BaseValidator;

class Validator extends BaseValidator {
  public function getValidationMessages() {
    $messages = [];
    foreach ($this->rules as $attribute => $rules) {
      foreach ($rules as $rule) {
        $messages[$attribute][$rule] = $this->getMessage($attribute, $rule);
      }
    } 

    return $messages;
  }
}

As you can see the output is a bit different than your example. There is no need to return an array of messages for given attribute and rule, as there will be always only one message in the array, so I'm just storing a string there.

Second, you need to make sure that your validator class is used. In order to achieve that, you'll need to register your own validator resolver with Validator facade:

Validator::resolver(function($translator, array $data, array $rules, array $messages, array $customAttributes) {
  return new \Your\Namespace\Validator($translator, $data, $rules, $messages, $customAttributes);
});

You can do this in your AppServiceProvider::boot() method.

Now, in order to get validation messages for given validator, you just need to call:

Validator::make($data, $rules)->getValidationMessages();

Keep in mind this code hasn't been tested. Let me know if you see any issues or typos with the code and I'll be more than happy to get that working for you.