I validate POST request like:
$validator = Validator::make($request->all(), [
"id.*" => 'required|integer'
]);
if ($validator->fails()) {
return response()->json($validator->errors, 400);
}
echo "Ok";
When I send request without parameter id it skips validation and returns echo "Ok";.
Why validation does not work?
If you expect id is array of integers you should update validation rules like this:
$validator = Validator::make($request->all(), [
"id" => 'required|array',
"id.*" => 'integer'
]);
First know when using $request->validate(); when it fail exceptions are raised!
And they are automatically handled by laravel. If it's a get, or a normal post form, then the process will redirect back to the form.
To note, when using the validate method during an AJAX request, Laravel will not generate a redirect response. Instead, Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.
If you want to not have such an automatic behavior, create manually a validator, then you can check with ->fails() method, as the example show bellow. That's can be handful in a lot of situations.
<?php
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
// Store the blog post...
}
}
And there is no better then the doc itself: https://laravel.com/docs/5.7/validation
there is a lot of options, to personalize our validation process.
Related
I wanted to validate inputs from a GET request without using the
this->validate($request... or \Validator::make($request...
and prefer to do it like
$input = $request->validate([... rules ...]);
however since get requests doesn't have $request parameters how can I achieve it?
public function sampleGet($param1, $param2) {
// How can I pass the $param1 and $param to to validate?
$input = $request->validate([
'param1' => 'required',
'param2' => 'required
]);
}
You can do so and it will have same behavior as validate
validator($request->route()->parameters(), [
'param1' => 'required',
'param2' => 'required'
....
])->validate();
If you want all the route parameters you can get them as an array:
$request->route()->parameters()
Since you already have those parameters being passed to your method you can just build an array with them:
compact('param1', 'param2');
// or
['param1' => $param1, 'param2' => $param2];
You are not going to be using the validate method on the Request though, you will have to manually create a validator. Unless you want to merge this array into the request or create a new request with these as inputs.
There is nothing special about the validate method on a Controller or on a Request. They are all making a validator and validating the data the same way you would yourself.
When manually creating a validator you still have a validate method that will throw an exception, which would be the equivalent to what is happening on Request and the Controller with their validate methods.
Laravel 7.x Docs - Validation - Manualy Creating Validators - Automatic Redirection
You can do like that.
public function getData(Request $request)
{
try {
$input['route1'] = $request->route('route1');
$input['route2'] = $request->route('route2');
$valid = Validator::make($input, [
'route1' => 'required',
'route2' => 'required'
]);
} catch (\Throwable $th) {
echo "<pre>";print_r($th->__toString());die;
}
}
Or you can follow the below link for more info.
https://laravel.com/docs/7.x/validation#manually-creating-validators
I'm trying to validate post request. I think when the validation fails, it gives me this error message.
app/Http/Controllers/InternationalShippingController.php
public function store(Request $request){
//echo '<pre>';
$post = $request->post();
$order_ids = session('international_order_ids');
//var_dump($order_ids);
//var_dump($post);
$validator = Validator::make(
$post,[
'documents.*' => 'mimes:jpg,jpeg,png,pdf|max:5000|nullable',
'company_name' => 'nullable',
'shipping_address1' => 'nullable',
'message' => 'size:1000',
],[
'image_file.*.mimes' => __('Only jpeg,png and pdf files are allowed'),
'image_file.*.max' => __('Sorry! Maximum allowed size for an document is 5MB'),
]
);
if($validator->fails()){
return redirect('internationalshippings/create2')
->withErrors($validator)
->withInput();
}
}
web.php
Route::post('internationalshippings/create2','InternationalShippingController#create2');
Route::resource('internationalshippings','InternationalShippingController');
I haven't made show() method in the controller.
Does this error mean when the validation fails, it tries to redirect to internationalshippings/show method?
When the validation fails,I'd like this to redirect back to internationalshippings/create2. How can I achieve this?
Thank you
you are using the resource controller,
in resources this url internationalshippings/SomeThing means the show method i mean this url calls the show method in resource
First way
so you can use this in your fail return:
return redirect()->route('your_route_name') OR return back()
Second way
and the second way is in your web.php, when you are defining the resource route, type in this way:
Route::resource('internationalshippings','InternationalShippingController',['except'=>['show']]);
EDIT:
in your code situation the best way is change Return, because the url that you want to redirect to it, is POST
I've searched about it on internet but it seems to be different. I'm using laravel5.1 and implemented google recaptcha. The scenario is, if the form was submitted and returns the validation with error, the recaptcha is resetting again and again, what I want is to not to reset it again, just staying as validated, because it annoys users to validate again and again. Do you have any idea about this?
Update: for code
public function postRegister(Request $request){
// Validation
$this->validate($request, [
'username' => 'required|unique:users|max:20|min:3',
'password' => 'required|min:6',
'retype_password' => 'required|same:password',
'email' => 'required|unique:users|email|max:255',
'g-recaptcha-response' => 'required|recaptcha'
]);
// Database save part here...
return redirect()->route('register')->with('info', 'Success!');
}
This is a little more verbose now that I am trying to write the code, but you get the gist.
Validate your Recaptcha field first. If it is valid, set a session variable to prevent it being rendered in your form again.
public function postRegister(Request $request)
{
// Prepare validation rules
$defaultRules = [
'username' => 'required|unique:users|max:20|min:3',
'password' => 'required|min:6',
'retype_password' => 'required|same:password',
'email' => 'required|unique:users|email|max:255',
];
$recaptchaRules = [
'g-recaptcha-response' => 'required|recaptcha',
];
// Set session if recaptcha is valid
if (Validator::make($request->all(), $recaptchaRules)->passes()) {
session(['recaptcha' => true]);
}
// Add recaptcha rules to default rules if failed to get single message bag with all errors
else {
$defaultRules = array_merge($defaultRules, $recaptchaRules);
}
// Validation
$this->validate($request, $defaultRules);
// Database save part here...
// Reset recaptcha validity so that the recaptcha is displayed on the next submission
session(['recaptcha' => false]);
return redirect()->route('register')->with('info', 'Success!');
}
Only output the Recaptcha field it if hasn't already been validated.
#unless (session('recaptcha'))
{{ Recaptcha::render() }}
#endunless
I am working with a form request file like this:
ProjectCreateRequest.php
public function rules()
{
$project_name = $this->project_name;
$meta_activity = $this->meta_activity;
return [
'project_name' => 'required|max:255|unique:projects',
'customer_name' => 'required|max:255',
'otl_project_code' => 'sometimes|max:255|unique:projects,otl_project_code,NULL,id,meta_activity,'.$meta_activity,
'estimated_start_date' => 'date',
'estimated_end_date' => 'date',
'LoE_onshore' => 'numeric',
'LoE_nearshore' => 'numeric',
'LoE_offshore' => 'numeric',
'LoE_contractor' => 'numeric',
'revenue' => 'numeric',
'win_ratio' => 'integer'
];
}
There is the otl_project_code that must be unique with the meta_activity.
In case someone enters a pair of otl_project_code and meta_activity that already exists, it goes back to the create page with the error written below.
I would like to get instead that in the controller, I can catch this information, do something on the database then redirect to an update url.
Because I am working with a form validation request file, everything is entered in my controller like this:
public function postFormCreate(ProjectCreateRequest $request)
and I don't know how to catch this specific error in my controller to execute some actions with all the fields I submitted and not go back to the create page. Of course, this needs to happen only when there is the specific error I mentionned above.
Override the FormRequest response function in your ProjectCreateRequest:
/**
* Get the proper failed validation response for the request.
*
* #param array $errors
* #return \Symfony\Component\HttpFoundation\Response
*/
public function response(array $errors)
{
if ($this->expectsJson()) {
return new JsonResponse($errors, 422);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
That's the public response on the FormRequest class so you can write your own logic to perform DB queries and redirect where needed.
I have an AJAX upload that sends the uploaded file (image in this case) to a function in Laravel 5.3. There I have this validation check in said function:
...
$validator = Validator::make($request->all(), [
'image' => 'image|mimes:jpeg,png,jpg|max:512',
]);
// If validator fails return this error to AJAX
if($validator->fails()) {
return response()->json('error', 422);
}
...
How would I be able to set the response()->json('error', 422) with a custom error. Now I only get an error that the file upload has failed. I would like more feedback then that.
For example: let the user know his file is to large or let the user know his extension is not allowed.
Thanks
You can get error messages from validator and send it to response, here is example.
if ($validator->fails()) {
return response()->json([
'success' => false,
'error' => $validator->getMessageBag()->toArray()
], 422);
}