Lumen Validation allow only one Get Parameter - php

In my project I use Lumen and I want to implement some kind of validation for my GET request.
The example URL would look like this:
[URL]/blubb/bla?tags[]=1&tags[]=2
In my code I validate the URL like this:
public function handleRequest(Request $request)
{
try {
$validatedData = $this->validate($request, [
'tags' => 'nullable|array'
]);
} catch (ValidationException $th) {
// return Error.
}
// go on.
}
My problem is that if a user uses an URL like this one, the validation does not trigger and the "go on." part is called.
[URL]/blubb/bla?invalidParameter=1
Is there a way to only allow a single "kind" of GET Parameter?
EDIT:
The "tags" is nullable because my API endpoint can be called without any GET parameters.

You could get the full array with $request->all() and have a look at the keys.
$paramValidation = $request->all()
unset $paramValidation['tags'];
if (count($paramValidation)) {
// error
}
However, maybe you just want to ignore other params. Have a look at the method $request->validated().

Related

What is the correct method to pass parameter to Laravel controller for filtering data?

This is my code of route for getting data from Laravel backend.
Route::get('/get/card',[CardController::class,'getCardList'])->name('card.list');
I call it like below,
http://127.0.0.1:8000/get/card
Controller code
public function getCardList()
{
//code goes here
}
The above code is working fine. I'm trying to add a parameter for adding filtration as follows;
Route::get('/get/card{treeItemID?}',[CardController::class,'getCardList'])->name('card.list');
public function getCardList($treeItemID)
{
}
http://127.0.0.1:8000/get/card?treeItemID=1
But, I'm getting the error "Too few arguments to function app\Http\Controllers\CardController::getCardList()..."
Can anyone notice what's wrong with my code that gives the above error when the parameter is added? Any help would be highly appreciated.
if you want to get data like below url, please replace your route and method like below and check again.
http://127.0.0.1:8000/get/card?treeItemID=1
Route::get('/get/card',[CardController::class,'getCardList'])->name('card.list');
public function getCardList(Request $request){
$treeItemID = $request->input('treeItemID');
return $treeItemID;
}
You can use get and post both type of request for filtering purpose.
Scenario 1 => If you want to hide some parameter inside request then you can use POST type of request where use can pass data in form data and get from request inside in controller.
Route::post('/get/card',[CardController::class,'getCardList'])->name('card.list');
public function getCardList(Request $request){
$treeItemID = $request->treeItemID;
return $treeItemID;
}
Scenario 2 => If you do want to hide some parameter inside the request then you can use GET type of request where use can pass data in url and get from request or get from parameter url inside in controller.
Route::get('/get/card/{treeItemID}',[CardController::class,'getCardList'])->name('card.list');
public function getCardList($treeItemID){
$treeItemID = $treeItemID;
return $treeItemID;
}

Laravel - check request method

I'm an iOS lead on an app and trying to fix some API bugs whilst our dev is 'unavailable'. I'm almost completely new to Laravel and trying to check what the request method is. I have followed some guidance from another question but have been unable to get it working:
public function defaults(Request $request, User $user){
$follow_ids = explode(',', env('FOLLOW_DEFAULTS'));
if ($request->isMethod('post')) {
return ['user' => $user];
}
$user->follows()->syncWithoutDetaching($follow_ids);
return ['user.follows' => $user->follows->toArray()];
}
Do you know where I might be going wrong here? Thanks in advance.
When the request is returned it always just seems to skip over and return ['user.follows' => $user->follows->toArray()]
$request should be an instance of Illuminate\Http\Request. This class extends Symfony's request (Symfony\Component\HttpFoundation\Request), which is actually where the isMethod() method is defined.
Basically, given the function definition as posted, it reads "if this is a POST request, just return the user data. if this is not a POST request (e.g. GET), update and return the relationship data."
So, if you send a POST request, you'll get the ['user' => $user] response. If you send any other request method (e.g. GET), you'll modify the follows relationship and get the ['user.follows' => $user->follows->toArray()] response.
To me, this seems backwards. I would think you'd want the POST request to update the data, and any other request (e.g. GET) to just return data.
If this is correct, you need to negate your isMethod check:
if (! $request->isMethod('post')) {
return ['user' => $user];
}
More appropriately you should define separate controller actions to handle POST vs GET requests, but that is outside the scope of this question, and probably more than you want to get into as a temporary maintainer.
It seems that the request is not a POST so the if check is never true. You could echo the method name like this:
$method = $request->method();
echo $method;
// or var_dump($method);

How to add the parameter name in custom validation laravel

I want to ask about custom validation. I make validation for counting the word
Validator::extend('word_count', function($attribute, $value, $parameters, $validator) {
return str_word_count($value) >= $parameters;
});
How can i give name to parameter so that i can use the parameter value in error message?
Based on your question, i will understand you care about the validation message.
If you are looking for validation message mean, you can use custom message like,
If you are using the request file means, there we can use
messages(){
return [
'word_count' => '....', //some message will be here,
];
}
If you are using controller means, then use like
return response()->json('...', 422);
or
here also you can use that above messages function.
I hope, it will help you.If any thing ask here.

test store method in Laravel

I am trying to test the store method in the simplest way possible. I don't necessarily need Mockery, I'm fine with actually adding to the database. I couldn't get Mockery to work anyway.
Now I have this:
public function testStore()
{
$data = ['name' => 'TestClub', 'code' => 'TCL'];
Input::replace($data);
$this->route('POST', 'clubs.store', $Input::all());
$this->assertResponseOk();
}
This is my controller method:
public function store() {
$validator = Validator::make($data = Input::all(), Club::$rules);
if ($validator->fails()) {
return Redirect::back()->withErrors($validator)->withInput();
}
Club::create($data);
return redirect(Session::get('backUrl'));
}
I get a return code 500, I have no idea why. Can I somehow see the request it's sending?
I am using Laravel 5.0
First, never use Input::all(). You may not know what's in the form when it's submit, instead use only.
However, you also shouldn't be putting validation logic in the Controller if you can help it. Instead, you should make a new Request and put your validation rules in the rules array. Let's look at that
php artisan make:request StoreUserRequest
Then inside of this Request, you'll add return true to your authorize function (or whatever logic you need to identify if the user should be able to make the request), and then your rules to the rules() function (to the array within the rules function, to be more specific).
Now add your new StoreUserRequest as a dependency to the first argument of the store() function.
public function store(App\Http\Requests\StoreUserRequest $request)
Now use the $request->only() method to get your fields back.
Club::create($request->only(['field1', 'field2', 'blob1', 'text1']);
Furthermore, make sure that any fields you wish to add data to are listed within the protected $fillable array in your Club model.
protected $fillable = ['field1', 'field2', 'blob1', 'text1'];
This should do it.

Using Laravel 5 Method Injection with other Parameters

So I'm working on an admin interface. I have a route set up like so:
Route::controllers([
'admin' => 'AdminController',
]);
Then I have a controller with some methods:
public function getEditUser($user_id = null)
{
// Get user from database and return view
}
public function postEditUser($user_id = 0, EditUserRequest $request)
{
// Process any changes made
}
As you can see, I'm using method injection to validate the user input, so URL's would look like this:
http://example.com/admin/edit-user/8697
A GET request would go to the GET method and a POST request to the POST method. The problem is, if I'm creating a new user, there won't be an ID:
http://examplecom/admin/edit-user/
Then I get an error (paraphrased):
Argument 2 passed to controller must be an instance of EditUserRequest, none given
So right now I'm passing an ID of 0 in to make it work for creating new users, but this app is just getting started, so am I going to have to do this throughout the entire application? Is there a better way to pass in a validation method, and optionally, parameters? Any wisdom will be appreciated.
You can reverse the order of your parameters so the optional one is a the end:
public function postEditUser(EditUserRequest $request, $user_id = null)
{
}
Laravel will then resolve the EditUserRequest first and pass nothing more if there's no user_id so the default value will kick in.

Categories