bodi87
bodi87

Reputation: 551

Laravel display validation error in multiple languages at the same time

I am working on returning validation errors in multiple languages at the same time.

I have a controller that injects a class that extends FormRequest and I am overriding 'failedValidation' and there I get the validator error messages.

    public function store(SysUserStoreRequest $request)
    {
      // ...
    }

    class SystemUserStoreRequest extends ApiRequest
    {
      // This extends another class ApiRequest
      Here I defined rules()
    }
    
    class APIRequest extends FormRequest
    {
      // Here I override the FailedValidation method.

      protected function failedValidation(Validator $validator)
      {
        throw new HttpResponseException($this->response($validator->getMessageBag()->toArray()));
      }
    }

The above code currently returns the error in the default language. I can change the response to show in a different language by changing the locale in the middleware, but I am working on requirement where I need to return a new structure of validation error with each field errors in both en and fr.

I need the structure like below:

{
  "detail": {
      "email": {
        "en-CA" : [
          "The email has already been taken."
        ],
        "fr-CA" : [
          "The french text."
        ]
      },
      "first_name": {
        "en-CA" : [
          "The first name must be at least 5.",
          "The first name must be an integer."
        ],
        "fr-CA" : [
          "The french text",
          "The french text."
        ]
      }
  }
}

So i tired to override the failedValidation method and do something like below:

        $validation_structure = [];
        if ($validator->fails()) {
            $failedRules = $validator->failed();
        }

        

after getting the al the failed rules i can then get the string from the lang folder for each locale and get the string for the field and rule and generate the message using

            $x[] = __('validation.unique', [], 'fr-CA');
            $x[] = __('validation.unique', [], 'en-CA');

this will give me the string in both labguages but I do not know how to replace the :attributes, :values and various other string replacements.

Upvotes: 1

Views: 3525

Answers (1)

David
David

Reputation: 200

You could overwrite the message bag the SystemUserStoreRequest will give back to format the messsages.

class SystemUserStoreRequest extends ApiRequest
{
    public function rules()
    {
        return [
            'email' => 'required|unique:users,email,' . $this->id,
        ];
    }

    public function messages()
    {

        return [
            'email.required' => [
               'nl' => __('validation.required', ['attribute' => __('portal.email', [],'nl')], 'nl'),
               'en' => __('validation.required', ['attribute' => __('portal.email', [],'en')], 'en'),
            ],
            'email.unique' => [
               'nl' => __('validation.unique', ['attribute' => __('portal.email', [],'nl')], 'nl'),
               'en' => __('validation.unique', ['attribute' => __('portal.email', [],'en')], 'en'),
            ]
        ];
    }
}

Then the output would look like:

{
    "message":"The given data was invalid.",
    "errors":{
        "email":[
            {
                "nl":"E-mailadres is verplicht.",
                "en":"The email field is required."
            }
        ]
    }
}

Here is some more documentation about custom messages: https://laravel.com/docs/8.x/validation#specifying-custom-messages-in-language-files

Upvotes: 2

Related Questions