Laravel, Handling validation errors in the Controller - php

So i'm working on validating a form's inputs using the following code:
$request->validate([
'title' => 'bail|required|max:255',
'body' => 'required',
]);
So basically, there are two fields in the form, a title and a body and they have the above rules. Now if the validation fails I want to catch the error directly in the controller and before being redirected to the view so that I can send the error message as a response for the Post request. What would be the best way to do it?
I understand that errors are pushed to the session but that's for the view to deal with, but i want to deal with such errors in the controller itself.
Thanks

If you have a look at the official documentation you will see that you can handle the input validation in different ways.
In your case, the best solution is to create the validator manually so you can set your own logic inside the controller.
If you do not want to use the validate method on the request, you may create a validator instance manually using the Validator facade.
Here a little example:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'bail|required|max:255',
'body' => 'required',
]);
// Check validation failure
if ($validator->fails()) {
// [...]
}
// Check validation success
if ($validator->passes()) {
// [...]
}
// Retrieve errors message bag
$errors = $validator->errors();
}

For someone who wants to know how to get validation errors after page redirection in the controller:
$errors = session()->get('errors');
if ($errors) {
//Check and get the first error of the field "title"
if ($errors->has('title')) {
$titleError = $errors->first('title');
}
//Check and get the first error of the field "body"
if ($errors->has('body')) {
$bodyError = $errors->first('body');
}
}
$errors will contain an instance of Illuminate/Contracts/Support/MessageBag
You can read more on the API here: https://laravel.com/api/8.x/Illuminate/Contracts/Support/MessageBag.html
Note: I have tested it in Laravel 8, it should work on Laravel 6+ if you get the MessageBag from the session

Related

laravel how to validate from custom request object?

I'm trying to validate a request like this.
public function reply(CustomRequest $request)
{
$request->validated();
}
The issue is that it will automatically redirect to the previous page if the validation fails. Whereas I want to do some custom logic.
For example
if($request->validation->fails()) {
// Do things
}
But I can't find a way to do this without passing in validation rules, whereas I want to use the rules from the "CustomRequest" class.
Using the Validator::make(), you can redirect your customised stuff.
Here is an example how you can return the first error in the ErrorBag:
$validator = Validator::make($request->all(), [
'field' => ['required']
]);
if ($validator->fails()) {
return redirect()->back()->with('custom_error', $validator->errors()->first());
};

Getting the ErrorMessage Bag in Laravel Validation during Validation

As the question states. I am using the validation method where the Rules and Custom Messages are placed in the Http/Requests folder. However, I want to get the messageErrorBag in Laravel I don't have any problems if I am using the code below I can easily add my own variables to be passed together with the validator message bag.
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
However, if using the code below. I cannot do it since Laravel already handles the error return as per documentation.
public function store(StoreBlogPost $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
}
My question how can I do it? before it redirects back with the error message bag.? Is it possible
If you use StoreBlogPost in Controller , it automatically returns messages but if you want your messages in body of controller you should add validator to your controller body and use this code:
if ($validator->fails())
{
foreach ($validator->messages()->getMessages() as $field_name => $messages)
{
var_dump($messages); // messages are retrieved (publicly)
}
}
hope it helps

Api validation in laravel 5.4

Hi guys I'm working on API but I need to validate some data at backend, in this case, we only need a postman to send parameters and headers.
All is working fine now but I need more useful data in each request, Laravel has by default a Validator Form Request Validation, but I donĀ“t know how to use at API side.
I need to send the error message in JSON to Postman.
I found two options, one, make validations into a controller but seems to much code and the other make a php artisan make:request StoreObjectPost and then import the request into the controller and change the request of the store method, which one do you recommend, Ty!
You could instantiate the validator yourself like this:
$validator = Validator::make($request->all(), [
'name' => 'min:5'
]);
// then, if it fails, return the error messages in JSON format
if ($validator->fails()) {
return response()->json($validator->messages(), 200);
}
$PostData = Input::all();
$Validator = Validator::make(array(
'name' => $PostData['name']
), array(
'name' => 'required'
));
if ($Validator->fails()) { //if validator is failed
return false;
} else {
// do some thing here
}
Hope this may help you
You should override response(array $errors) method of FormRequest.
public function response(array $errors)
{
//Format your error message
if ($this->expectsJson()) {
return new JsonResponse($errors, 422);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
I prefer the second option. We will be able to keep our controller clean that way, even when we use many validations for the data or using custom error message in the validation

Dynamically change CakePHP 3 custom validation rule message

I've got a custom validation method that checks a field for token values to ensure that they are all present in the content. The method works fine, it validates as OK when all the tokens exist in the content and throws a validation error when one or more tokens are missing.
I can easily apply a validation error message to state that some of the tokens are missing when I attach my custom validation rule to my table in validationDefault(). However, what I really want to do is set a validation message that reflects which of the tokens haven't been set. How can I dynamically set the validation message in CakePHP 3? In CakePHP 2 I used to use $this->invalidate() to apply an appropriate message, but this no longer appears to be an option.
My code looks like this (I've stripped out my actual token check as it isn't relevant to the issue here):-
public function validationDefault(Validator $validator)
{
$validator
->add('content', 'custom', [
'rule' => [$this, 'validateRequiredTokens'],
'message' => 'Some of the required tokens are not present'
]);
return $validator;
}
public function validateRequiredTokens($check, array $context)
{
$missingTokens = [];
// ... Check which tokens are missing and keep a record of these in $missingTokens ...
if (!empty($missingTokens)) {
// Want to update the validation message here to reflect the missing tokens.
$validationMessage = __('The following tokens are missing {0}', implode(',', $missingTokens));
return false;
}
return true;
}
Read the API docs.
Copy and paste:
EntityTrait::errors()
Sets the error messages for a field or a list of fields. When called without the second argument it returns the validation errors for the specified fields. If called with no arguments it returns all the validation error messages stored in this entity and any other nested entity.
// Sets the error messages for a single field
$entity->errors('salary', ['must be numeric', 'must be a positive number']);
// Returns the error messages for a single field
$entity->errors('salary');
// Returns all error messages indexed by field name
$entity->errors();
// Sets the error messages for multiple fields at once
$entity->errors(['salary' => ['message'], 'name' => ['another message']);
http://api.cakephp.org/3.3/class-Cake.Datasource.EntityTrait.html#_errors
Not sure if this is something that's been improved since burzums answer.
But it's actually pretty simple. A custom validation rule can return true (if the validation succeeds), false (if it doesn't), but you can also return a string. The string is interpreted as a false, but used for the error message.
So you can basically just do this:
public function validationDefault(Validator $validator)
{
$validator
->add('content', 'custom', [
'rule' => [$this, 'validateRequiredTokens'],
'message' => 'Some of the required tokens are not present'
]);
return $validator;
}
public function validateRequiredTokens($check, array $context)
{
$missingTokens = [];
if (!empty($missingTokens)) {
// Want to update the validation message here to reflect the missing tokens.
$validationMessage = __('The following tokens are missing {0}', implode(',', $missingTokens));
//Return error message instead of false
return $validationMessage;
}
return true;
}
From the CookBook:
Conditional/Dynamic Error Messages

Access validator messages in controller Laravel 4

I'm trying to access the messages from the validator in the controller using the following code.
$valid = Validator::make($input,$rules);
print_r($valid->messages());
However, I'm not getting any output even though the validation is failing.
What do I need to do to get the Laravel-generated validation messages?
You need to run $validator->fails() or $validator->passes() before checking for the messages:
$valid = Validator::make($input,$rules);
$validator->fails();
print_r($valid->messages());
But assuming you know that, well, you could be using messages()->all(), but the way you're are doing should work. Try this (standalone-ish) code in your end:
$validator = Validator::make(
array('name' => 'Dayle'),
array('name' => 'required|min:15')
);
if ($validator->fails())
{
// The given data did not pass validation
}
print_r($validator->messages()->all());
If it works then the problem is realated to your $input and/or $rules.

Categories