Custom Laravel validation messages
Asked Answered
M

14

84

I'm trying to create customized messages for validation in Laravel 5. Here is what I have tried so far:

$messages = [
    'required'  => 'Harap bagian :attribute di isi.',
    'unique'    => ':attribute sudah digunakan',
];
$validator = Validator::make($request->all(), [
    'username' => array('required','unique:Userlogin,username'),
    'password' => 'required',
    'email'    => array('required','unique:Userlogin,email'),$messages
]);

if ($validator->fails()) { 
    return redirect('/')
        ->withErrors($validator) // send back all errors to the login form
        ->withInput();
} else {
    return redirect('/')
        ->with('status', 'Kami sudah mengirimkan email, silahkan di konfirmasi');   
}   

But it's not working. The message is still the same as the default one. How can I fix this, so that I can use my custom messages?

Margarine answered 10/7, 2017 at 9:6 Comment(1)
All these years and nobody pointed out the simple typo. Inside Validator::make(), the $messages variable was accidentally put inside the rules array.Raver
L
105

If you use $this->validate() simplest one, then you should write code something like this..

$rules = [
        'name' => 'required',
        'email' => 'required|email',
        'message' => 'required|max:250',
    ];

    $customMessages = [
        'required' => 'The :attribute field is required.'
    ];

    $this->validate($request, $rules, $customMessages);
Lemaceon answered 10/7, 2017 at 9:44 Comment(1)
With what should i fill the $request var?Niel
B
129

Laravel 5.7.*

Also You can try something like this. For me is the easiest way to make custom messages in methods when you want to validate requests:

public function store()
{
    request()->validate([
        'file' => 'required',
        'type' => 'required'
    ],
    [
        'file.required' => 'You have to choose the file!',
        'type.required' => 'You have to choose type of the file!'
    ]);
}
Broccoli answered 1/12, 2018 at 17:47 Comment(3)
This was the easiest for me as I was pressed for time and needed to do this in only one place. It is quite handy but if you are going to need custom messages in a number of places, it would be more prudent to have them all in one place. It makes tracking easier and makes the code more legible than if you have custom messages in each validation statement. I upvoted your answer because of my unique usecase and I want to say thank you for it (even though, SO advises against thanks and me too posts, you need to know that you helped me out of a bind and I delivered in time).Recapture
Thank You so much @Recapture Im glad that I could help!Broccoli
@Geo4you Thanks a lot, it really helped me.Loudmouthed
L
105

If you use $this->validate() simplest one, then you should write code something like this..

$rules = [
        'name' => 'required',
        'email' => 'required|email',
        'message' => 'required|max:250',
    ];

    $customMessages = [
        'required' => 'The :attribute field is required.'
    ];

    $this->validate($request, $rules, $customMessages);
Lemaceon answered 10/7, 2017 at 9:44 Comment(1)
With what should i fill the $request var?Niel
V
33

For Laravel 8.x, 7.x, 6.x
With the custom rule defined, you might use it in your controller validation like so :

$validatedData = $request->validate([
       'f_name' => 'required|min:8',
       'l_name' => 'required',
   ],
   [
    'f_name.required'=> 'Your First Name is Required', // custom message
    'f_name.min'=> 'First Name Should be Minimum of 8 Character', // custom message
    'l_name.required'=> 'Your Last Name is Required' // custom message
   ]
);

For localization you can use :

['f_name.required'=> trans('user.your first name is required'],

Hope this helps...

Venture answered 3/6, 2020 at 12:2 Comment(1)
This is fantastic. I missed this in the docs. Thank you!Stew
N
32

You can provide custom message like :

$rules = array(
            'URL' => 'required|url'
        );    
$messages = array(
                'URL.required' => 'URL is required.'
            );
$validator = Validator::make( $request->all(), $rules, $messages );

if ( $validator->fails() ) 
{
    return [
        'success' => 0, 
        'message' => $validator->errors()->first()
    ];
}

or

The way you have tried, you missed Validator::replacer(), to replace the :variable

Validator::replacer('custom_validation_rule', function($message, $attribute, $rule, $parameters){
    return str_replace(':foo', $parameters[0], $message);
});

You can read more from here and replacer from here

Niello answered 10/7, 2017 at 9:10 Comment(2)
any example how to use it ?Margarine
added example for first method.Niello
K
12
$rules = [
  'username' => 'required,unique:Userlogin,username',
  'password' => 'required',
  'email'    => 'required,unique:Userlogin,email'
];

$messages = [
  'required'  => 'The :attribute field is required.',
  'unique'    => ':attribute is already used'
];

$request->validate($rules,$messages);
//only if validation success code below will be executed
Kurzawa answered 16/11, 2019 at 15:35 Comment(1)
This is the same as a previous answer posted a year ago.Raver
M
7
//Here is the shortest way of doing it.
 $request->validate([
     'username' => 'required|unique:Userlogin,username',
     'password' => 'required',
     'email'    => 'required|unique:Userlogin,email'
 ],
 [
     'required'  => 'The :attribute field is required.',
     'unique'    => ':attribute is already used'
 ]);
//The code below will be executed only if validation is correct.
Mafala answered 23/9, 2020 at 6:43 Comment(0)
J
7

run below command to create a custom rule on Laravel
ı assuming that name is CustomRule

php artisan make:rule CustomRule

and as a result, the command was created such as PHP code

if required keyword hasn't on Rules,That rule will not work

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CustomRule implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        //return  true or false
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The validation error message.';
    }
}


and came time using that first, we should create a request class if we have not

php artisan make:request CustomRequest

CustomRequest.php

<?php


namespace App\Http\Requests\Payment;

use App\Rules\CustomRule;
use Illuminate\Foundation\Http\FormRequest;

class CustomRequest extends FormRequest
{


    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'custom' => ['required', new CustomRule()],
        ];
    }

    /**
     * @return array|string[]
     */
    public function messages(): array
    {
        return [
            'custom.required' => ':attribute can not be empty.',
        ];
    }
}

and on your controller, you should inject custom requests to the controller

your controller method

class FooController
{
    public function bar(CustomRequest $request)
    {
        
    }
}

Janettejaneva answered 13/1, 2022 at 8:16 Comment(0)
C
7

In the case you are using Request as a separate file:

 public function rules()
 {
    return [
        'preparation_method' => 'required|string',
    ];
 }

public function messages()
{
    return [
        'preparation_method.required' => 'Description is required',
    ];
}

Tested out in Laravel 6+

Callan answered 13/4, 2022 at 8:9 Comment(0)
E
5

For those who didn't get this issue resolve (tested on Laravel 8.x):

$validated = Validator::make($request->all(),[
   'code' => 'required|numeric'
  ],
  [
    'code.required'=> 'Code is Required', // custom message
    'code.numeric'=> 'Code must be Number', // custom message       
   ]
);

//Check the validation
if ($validated->fails())
{        
    return $validated->errors();
}
Executioner answered 11/10, 2021 at 16:22 Comment(0)
B
5
    $rules = [
        'name' => 'required',
        'email' => 'required|email',
        'message' => 'required|max:250',
    ];

    $customMessages = [
        'required' => 'The :attribute field is required.',
        'max' => 'The :attribute field is may not be greater than :max.'
    ];

    $this->validate($request, $rules, $customMessages);
Blazer answered 11/1, 2022 at 9:31 Comment(0)
G
4

You can also use the methods setAttributeNames() and setCustomMessages(), like this:

$validation = Validator::make($this->input, static::$rules);

$attributeNames = array(
    'email' => 'E-mail',
    'password' => 'Password'
);

$messages = [
    'email.exists' => 'No user was found with this e-mail address'
];

$validation->setAttributeNames($attributeNames);
$validation->setCustomMessages($messages);
Giffy answered 22/7, 2021 at 16:19 Comment(1)
I really like this method. It's great when used with an after hook on a FormRequest, eg. laravel.com/docs/8.x/…Pastrami
C
1

Laravel 10.x

If you are using Form Requests, add another method called messages(): array in your request.

class YourRequest extends FormRequest
{

    public function rules(): array
    {
        return [
            'name' => 'required',
            'email' => 'required|email',
            ...
        ];
    }

    //Add the following method

    public function messages(): array
    {
        return [
            'email.required' => 'Custom message for Email Required',
        ];
    }
}

Then the message will be displayed automatically once the request is send from the form.

Corticate answered 14/2, 2023 at 7:49 Comment(0)
G
0

you can customise the message for different scenarios based on the request.

Just return a different message with a conditional.


<?php

namespace App\Rules;

use App\Helpers\QueryBuilderHelper;
use App\Models\Product;
use Illuminate\Contracts\Validation\Rule;

class ProductIsUnique implements Rule
{

    private array $attributes;
    private bool $hasAttributes;

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct(array $attributes)
    {
        $this->attributes = $attributes;
        $this->hasAttributes = true;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $brandAttributeOptions = collect($this->attributes['relationships']['brand-attribute-options']['data'])->pluck('id');

        $query = Product::query();

        $query->when($brandAttributeOptions->isEmpty(), function ($query) use ($value) {
            $query->where('name', $value);
            $this->hasAttributes = false;
        });

        
        return !$query->exists();
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return ($this->hasAttributes) ? 'The Selected attributes & Product Name are not unique' : 'Product Name is not unique';
    }
}

Gilbertgilberta answered 25/8, 2022 at 1:30 Comment(0)
U
0

First of all i've noticed you've passed the $messages within the array of validation rules which causes Laravel to behave unexpectedly. The correct way is to place $messages array right after your rules array. something like:

$validator = Validator::make($request->all(), [
'name'     => ['required'],
'email'    => ['required', 'unique:email'],
'message' => 'required',
], $messages);

Meanwhile I've been working on validation on livewire and I also discovered that this method is quite easier to grasp and implement. You can pass individual arrays as arguments in the validate() method. Laravel handles them seamlessly, just as it does when we create a separate request class and define these three methods respectively for validation:

  1. rules
  2. messages
  3. attributes
$request->validate([
        'name'      =>  'required',
        'email'     =>  'required|email',
        'message'   =>  'required|max:50',
    ],
    [
        // custom message Array | Define your custom messages here
        '*.required' =>  ':attribute is required',
        'message.max' => ':attribute should not exceed :max character',
    ],
    [
        // custom attributes Array | Define your custom attributes here
        'name'  =>  'Name',
        'email' =>  'Email Address',
        'message' => 'Message',
    ]);

Correct me if I'm wrong. Thanks

Unaneled answered 16/5 at 11:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.