How to make a good validation on laravel? - laravel

I have data, they look like this:
{
sender_name : "Real fake sender name",
recipient_name : "Real fake recipient name",
goods: [
{
"no" : 1
"name":"Pen",
"unit": "1",
"qty":"50",
"price":"50",
"amount":"2500",
"vat_percent":"5",
"vat_sum": "125",
"total_sum": "2625"
}
]
}
I need to validate "goods" using extend validator. Here is his code:
Validator::extend('invoiceGoods' , function($attribute, $value, $parameters, $validator) {
$rulesForGoods = [
'no' => 'integer|required',
'name' => 'string|max:64|required',
'unit' => 'required|integer',
'qty' => 'required|string',
'price' => 'required|numeric',
'amount' => 'required|numeric',
'vat_percent' => 'nullable|numeric',
'vat_sum' => 'nullable|numeric',
'total_sum' => 'required|numeric'
];
foreach ($value as $good) {
$validator = Validator::make($good , $rulesForGoods);
if ($validator->fails()) {
return false;
}
}
return true;
});
This is the main code.
$validator = Validator::make($data , [
'goods' => 'invoiceGoods',
'sender_name' => 'string',
'recipient_name' => 'string',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'message' => 'Validation error.',
'data' => $validator->errors()
]);
}
If the goods validation error occurs, I get this answer:
But I would like to display errors like this: the wrong unit in the goods with no 1.
I know that the third argument can be passed an array with custom messages, but how to return it from the extended validator if it should return true or false?

https://laravel.com/docs/5.8/validation#custom-error-messages
$messages = [
'Validation.invoice_goods' => 'Errror message!',];
$validator = Validator::make($input, $rules, $messages);

Related

Laravel make custom error validation messages

Greeting, this is my code and I need to make custom error messages for every rule
$validator = Validator::make($request->all(), [
'name' => 'required|min:3|max:100',
'phone' => 'required',
'date' => 'required',
'address' => 'required|min:3|max:100',
'test' => 'required|min:3|max:100',
]);
if ($validator->fails()) {
$errors = $validator->errors();
return response()->json($errors);
}
Its better to create a separate request for validation purpose
public function rules(): array
{
return [
'name' => 'required|min:3|max:100',
'phone' => 'required',
'date' => 'required',
'address' => 'required|min:3|max:100',
'test' => 'required|min:3|max:100',
]
}
public function messages(): array
{
return [
'name' => 'Please enter name'
];
}
you can create your own custom validation messages in two ways:
1- in resources/lang/en/validation.php you can change the validation message for every rule
2- you can pass your custom message for each validation like this:
$validator = Validator::make($input, $rules, $messages = [
'required' => 'The :attribute field is required.',
]);
you can check here for more information
specific to your question:
$messages = [
'required' => 'The :attribute field is required.',
'min' => ':attribute must be more than 3 chars, less than 100'
]
$validator = Validator::make($request->all(), [
'name' => 'required|min:3|max:100',
'phone' => 'required',
'date' => 'required',
'address' => 'required|min:3|max:100',
'test' => 'required|min:3|max:100',
], $messages);

Validate json object key in laravel request file

I have below type of json in my laravel request, I want to validate json object key in my laravel request file. I want to validate title value is required of data json. I found solution but it's for controller, I want to validate it in my request file
{"ID":null,"name":"Doe","first-name":"John","age":25,"data":[{"title":"title1","titleval":"title1_val"},{"title":"title2","titleval":"title2_val"}]}
Why not use Validator
$data = Validator::make($request->all(), [
'ID' => ['present', 'numeric'],
'name' => ['present', 'string', 'min:0'],
'first-name' => ['present', 'string', 'min:0',],
'age' => ['present', 'numeric', 'min:0', 'max:150'],
'data' => ['json'],
]);
if ($data->fails()) {
$error_msg = "Validation failed, please reload the page";
return Response::json($data->errors());
}
$json_validation = Validator::make(json_decode($request->input('data')), [
'title' => ['present', 'string', 'min:0']
]);
if ($json_validation->fails()) {
$error_msg = "Json validation failed, please reload the page";
return Response::json($json_validation->errors());
}
public function GetForm(Request $request)
{
return $this->validate(
$request,
[
'title' => ['required'],
],
[
'title.required' => 'title is required, please enter a title',
]
);
}
public function store(Request $request)
{
$FormObj = $this->GetForm($request);
$FormObj['title'] = 'stackoveflow'; // custom title
$result = Project::create($FormObj); // Project is a model name
return response()->json([
'success' => true,
'message' => 'saved successfully',
'saved_objects' => $result,
], 200);
}

Modify unique attribute validation in Laravel

Trying to customize the error message for unique attribute. Tried changing my validation.php.
$messages = [
'custom' => [
'email' => [
'unique:users' => 'Oops, email is taken. Please try again!'
]
]
],
and I call the validation in controller:
request()->validate([
'email' => 'unique:users',
'password' => 'required|min:3',
]);
And I still get this:
The email has already been taken.
using custom validator
You can create a custom validator and pass your messages into it
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);
For you this would mean
$messages = [
'email' => [
'unique' => 'Oops, email is taken. Please try again!'
]
];
$rules = [
'email' => 'unique:users',
'password' => 'required|min:3',
];
$validator = Validator::make(request()->all(), $rules, $messages);
if ($validator->fails()) {
return redirect('route/when/failed')
->withErrors($validator)
->withInput();
}
using language file
In resources/lang/{{language}}/validation.php you can add
'custom' => [
'email' => [
'unique' => 'Oops, email is taken. Please try again!',
],
]

Laravel more dimesions array validation

There is a request.How I can validate it? I trying with foreach, but i does not work. Thanks.
The request:
'show_data' => [
0 => [
'buyer_search_property_id' => 1,
'date_of_show' => '2019-01-01',
'comment' => 'Nice flat',
],
1 => [
'buyer_search_property_id' => 2,
'date_of_show' => '2019-01-31',
'comment' => 'Too small',
], etc...
],
I tried this, but it does not work (of course... :))
public function rules()
{
$rules = [];
foreach ($this['show_data'] as $key => $item) {
$rules["show_data[$key]['buyer_search_property_id']"] = 'required';
$rules["show_data[$key]['date_of_show']"] = 'required|date';
$rules["show_data[$key]['comment']"] = 'required';
}
return $rules;
}
This is from laravel documentation:
You may also validate each element of an array. For example, to validate that each e-mail in a given array input field is unique, you may do the following:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Read more here
You can validate array in laravel easily like this:
public function rules()
{
return [
"show_data.*.buyer_search_propery_id" => "required",
"show_data.*.date_of_show" => "required|date",
"show_data.*.comment" => "required",
];
}
if you want your method to work, do this:
public function rules()
{
$rules = [];
foreach ($this['show_data'] as $key => $item) {
$rules["show_data.$key.buyer_search_property_id"] = 'required';
$rules["show_data.key.date_of_show"] = 'required|date';
$rules["show_data.$key.comment"] = 'required';
}
return $rules;
}
just remove the inner square brackets and the quotes and add dots to the indices, so change $rules["show_data[$key]['date_of_show']"] to $rules["show_data.$key.date_of_show"]
$data['show_data'] = [
0 => [
'buyer_search_property_id' => 1,
'date_of_show' => '2019-01-01',
'comment' => 'Nice flat',
],
1 => [
'buyer_search_property_id' => 2,
'date_of_show' => '2019-01-31',
'comment' => 'Too small',
],
];
$rules = [
'show_data.*.buyer_search_property_id' => 'required',
'show_data.*.date_of_show' => 'required|date',
'show_data.*.comment' => 'required',
];
$validator = Validator::make($data, $rules);
Note asteriks at rules. With this you don't need a foreach loop. And it looks and feels a lot cleaner.

Laravel after function parameters

I have some code
$validator->after(function ($validator) {
var_dump($request->input('answer'));
if (true) {
$validator->errors()->add('Question', 'The answer is not correct!');
}
});
But I'm facing the problem where I need to pass $request->input('answer') down. It gives me an error that $request is not defined. How can I do that?
public function contact(Request $request) {
$validator = Validator::make($request->all(), [
'id' => 'required',
'boat' => 'required',
'name' => 'required',
'answer' => 'required',
'email' => 'required|email',
'message' => 'required'
]);
if ((int)$request->input('answer') != $request->session()->get('contact-seller-answer')) {
}
$validator->after(function ($validator, **$request**) {
var_dump($request->input('answer'));
if (true) {
$validator->errors()->add('Question', 'The answer is not correct!');
}
});
if ($validator->fails()) {
return redirect('ad/'.$request->input('id').'/'.$request->input('boat').'#form')
->withErrors($validator)
->withInput($request->all());
}
}

Resources