How to validate inputs from GET request in Laravel - laravel

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

Related

Laravel Validating An Array in Update Method unique filter

I am new to Laravel. I try to validate an array in Laravel 9.
for using a unique filter I have a problem.
at first, I try to use this way
$rules = [
'*.id' => 'integer|required',
'*.key' => 'string|unique.settings|max:255|required',
'*.value' => 'array|nullable|max:255',
];
For the Create method, this works, but for updating, the logic is wrong. I need to ignore the current field.
for the update, I try to use this way
private function update(): array
{
foreach ($this->request->all() as $keys => $values) {
// dd($values['id']);
$rules[$keys .'.id' ] = 'integer|required';
$rules[$keys .'.key'] = ['string|max:255|required', Rule::unique('settings', 'key')->ignore($values['id'])];
$rules[$keys .'.value'] = 'array|nullable|max:255';
}
// dd($rules);
return $rules;
}
I got this error
BadMethodCallException: Method Illuminate\Validation\Validator::validateString|max does not exist. in file /Users/mortezashabani/code/accounting/vendor/laravel/framework/src/Illuminate/Validation/Validator.php on line 1534
how can I validate an array in the update method in Laravel 9?
PS: without Rule::unique('settings','key')->ignore($values['id'])] all filter is works without any problem
hello you can try this code in your function
$validated = $request->validate([
'id' => 'required',
'key' => 'string|unique.settings|max:255|required',
'value' => 'array|nullable|max:255',
]);

Laravel Validator - Check custom validation rule after other rules get checked

How are you? Hope you are doing great
I need one help for Laravel Validator, i have created one custom validation rule like below
$validation = Validator::make($request->all(), [
'user_id' => 'required',
'role' => ['required', new RoleExist($request->user_id)],
]);
See i have passed one argument to rule's constructor new RoleExist($request->user_id) but laravel giving me 500 error if i do not pass user_id in the request
The error is
Argument 1 passed to App\Rules\RoleExist::__construct() must be of the type integer, null given
I know user_id is not passed in the request so laravel giving above error, but here my custom rule should be execute after 'user_id' => 'required',
Custom Rule Code
private $userId;
public function __construct(Int $userId)
{
$this->userId= $userId;
}
public function passes($attribute, $value)
{
return empty(\App\User::where('user_id', $this->userId)->where('status', '1')->first());
}
Is there any way to do the same
Thank you in advance

Laravel:Method ...Controller::show does not exist

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

Skip Laravel's FormRequest Validation

I've recently added HaveIBeenPwned to my form request class to check for cracked passwords. Given that this makes an external API call, is there a way for me to skip either this validation rule or the FormRequest class altogether during testing?
Here's the request I make in my test.
$params = [
'first_name' => $this->faker->firstName(),
'last_name' => $this->faker->lastName(),
'email' => $email,
'password' => '$password',
'password_confirmation' => '$password',
'terms' => true,
'invitation' => $invitation->token
];
$response = $this->json('POST', '/register-invited', $params);
The functionality I'm testing resides on a controller. In my test I POST an array of data that passes through a FormRequest with the following rules.
public function rules()
{
return [
'first_name' => 'required|string|max:70',
'last_name' => 'required|string|max:70',
'email' =>
'required|email|unique:users,email|max:255|exists:invitations,email',
'password' => 'required|string|min:8|pwned|confirmed',
'is_trial_user' => 'nullable|boolean',
'terms' => 'required|boolean|accepted',
];
}
I want to override the 'pwned' rule on the password so I can just get to the controller without having to worry about passing validation.
With the information provided I'd say you are executing an integration test which does an actual web request. In such a context I'd say it's fine for your test suite to connect to a 3rd party since that's part of 'integrating'.
In case you still prefer to mock the validation rule you could swap out the Validator using either the swap
$mock = Mockery::mock(Validator::class);
$mock->shouldReceive('some-method')->andReturn('some-result');
Validator::swap($mock);
Or by replacing its instance in the service container
$mock = Mockery::mock(Validator::class);
$mock->shouldReceive('some-method')->andReturn('some-result');
App:bind($mock);
Alternatively you could mock the Cache::remember() call which is an interal part of the Pwned validation rule itself. Which would result into something like
Cache::shouldReceive('remember')
->once()
->andReturn(new \Illuminate\Support\Collection([]));

Validate POST request Laravel?

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.

Resources