Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Custom Validation Messages as Array Cause Errors

In a package, I’m trying to have custom validation error messages in a file separated from the default one of Laravel. I’ve duplicated the file, changed the values (did not touch the keys), loaded it correctly in the service provider and everything worked fine. Base validations such as required, numeric, email, etc displayed the text in my file. Now, I tried to use the size rule, but since the error messages are in an array, it gives me this Exception when using $errors->get( 'content.reasons' ):

Array to string conversion in MessageBag.php (line 246)

Here the important parts of the code

Controller

$validator = Validator::make( $request->all(), $rules, trans( 'admin::validation' ) );
if ( $validator->fails() ){
    return redirect()
        ->back()
        ->withInput()
        ->withErrors( $validator );
}

$request->all()

[
    // ...
    "content" => [
        "reasons" => [
            [...],
            [...]
        ]
    ],
    // ...
]

$rules

[
    // ...
    "content.reasons" => "required|size:3"
    // ...
]

trans( 'admin::validation' )

// Exact structure of Laravel validation.php
[
    // ...
    'size'                 => [
        'numeric' => 'The field must be :size.',
        'file'    => 'The field must be :size kilobytes.',
        'string'  => 'The field must be :size characters.',
        'array'   => 'The field must contain :size items.',
    ],
    // ...
]

After the redirect

$errors = session()->get('errors') ?: new ViewErrorBag;
$field[ 'errors' ] = $errors->get( $dot_name ); // Exception thrown when $dot_name
                                                // equals `content.reasons`.

$errors

Illuminate\Support\ViewErrorBag {
    #bags: array:1 [
        "default" => Illuminate\Support\MessageBag {
            #messages: array:4 [
                "content.why_title" => array:1 [
                    0 => "The field is required."
                ]
                "content.reasons" => array:1 [
                    0 => array:4 [
                        "numeric" => "The field must be 3."
                        "file" => "The field must be 3 kilobytes."
                        "string" => "The field must be 3 characters."
                        "array" => "The field must contain 3 items."
                    ]
                ]
                "content.reasons.0.icon" => array:1 [
                    0 => "The field is required."
                ]
                "content.reasons.0.text" => array:1 [
                    0 => "The field is required."
                ]
            ]
            #format: ":message"
        }
    ]
}

I've tried passing content.reasons.array but it returns an empty array.

I've also tried to pass no messages (use Laravel's defaults) and it works, but I really need custom messages...

TL;DR: How can we pass custom messages with the same schema as Laravel?

like image 355
Karl-André Gagnon Avatar asked Aug 04 '17 15:08

Karl-André Gagnon


People also ask

How to use custom error validation message in Laravel 9 apps?

Use the following steps to use custom error validation message in laravel 9 apps: First of all, Execute the following command on the terminal to install or download laravel 9 app on your system: composer create-project --prefer-dist laravel/laravel Blog This command will install fresh new laravel setup in provided location.

What is the current_password rule in Laravel 9?

The field under validation must be numeric. The field under validation must match the authenticated user's password. This rule was renamed to current_password with the intention of removing it in Laravel 9. Please use the Current Password rule instead.

What are the different email validation styles available in Laravel?

Here's a full list of validation styles you can apply: The filter validator, which uses PHP's filter_var function, ships with Laravel and was Laravel's default email validation behavior prior to Laravel version 5.8. The dns and spoof validators require the PHP intl extension.

How to create a rule in Laravel artisan?

If this directory does not exist, Laravel will create it when you execute the Artisan command to create your rule: Once the rule has been created, we are ready to define its behavior. A rule object contains two methods: passes and message.


1 Answers

I don't know what are you trying to do, but you can pass custom messages for each validation field/rule, for example, in your controller:

    //Error messages
    $messages = [
        "name.required" => "Name is required",
        "name.string" => "Name must be a string",
        "username.required" => "Username is required",
        "username.min" => "Username must be at least 6 characters",
        "email.required" => "Email is required",
        "email.email" => "Email is not valid"
    ];

    // validate the form data
    $validator = Validator::make($request->all(), [
            'name' => 'required|string',
            'username' => 'required|min:6',
            'email' => 'required|email'
        ], $messages);

    if ($validator->fails()) {
        return back()->withErrors($validator)->withInput();
    } else {
        //Some code here
    }
like image 123
Diego Blaker Avatar answered Oct 13 '22 06:10

Diego Blaker