Need help in Laravel manimum and maximum user input in laravel - php

I am stuck in a problem that i want to get filter data in laravel or mysql
which later i will convert into laravel and that is i want to filter values from range slider
of warrenty
which is actually between 80 and 150 (selected by user)
and in database (mysql) i have just minimum value is 80
and maximum value is 200
but by using the following code it only returns maximum value of the given minimum value
$product = product::join('tire_brands', 'product.brand', '=', 'tire_brands.id')
->join('speedrating','product.speedrating','=','speedrating.id')
->where($whereData)
->when(!empty($category), function ($query) use ($category) {
return $query->whereIn('itemtype', $category);
})
->when(!empty($speedrating), function ($query) use ($speedrating) {
return $query->whereIn('speedrating', $speedrating);
})
->when(!empty($tirebrands), function ($query) use ($tirebrands) {
return $query->whereIn('brand', $tirebrands);
})
->when(!empty($minwarrenty) && !empty($maxwarrenty), function ($query) use ($minwarrenty,$maxwarrenty) {
return $query->whereBetween('warrenty', [$minwarrenty, $maxwarrenty]);
})
->when(!empty($minimum_load) && !empty($maximum_load), function ($query) use ($minimum_load,$maximum_load) {
return $query->whereBetween('maxload', [$minimum_load, $maximum_load]);
})
->when(!empty($curroff), function ($query) use ($curroff) {
return $query->whereIn('curr_offerid', $curroff);;
})
->when(!empty($sidewal), function ($query) use ($sidewal) {
return $query->whereIn('sidewall_id', $sidewal);;
})
->when(!empty($tyrtyp), function ($query) use ($tyrtyp) {
return $query->whereIn('tyretype_id', $tyrtyp);;
})
->get(['product.id','product.name as pronam',
'tire_brands.name as brand', 'sku','slug','warrenty','speedrating','itemtype',
'product.image','product.video','speedrating.name as speedrating','touring']);
return $product;
what am i doing wrong?

Related

Multiple conditional where clauses not working in Eloquent query

I have a function that is supposed to use a combination of filters set by the user to fetch information from a table (or no filters at all).
Keep in mind I'm not trying to override filters here, the query should dynamically add or remove filters depending on the ones set client-side by the user.
The filters work well individually, but when setting multiple of them, the query doesn't fetch the correct data at all. I'm still unable to figure out what the criteria for the incorrect data being fetched is.
The only filters that seem to work in combination with others are date_from and date_to.
This is the function:
public function getReport(Request $request)
{
// Convertir fechas a formato correcto
$request->date_from = date('Y-m-d', strtotime(str_replace('-', '/', $request->date_from)));
$request->date_to = date('Y-m-d', strtotime(str_replace('-', '/', $request->date_to)));
$query = Ticket::all();
$query->when(isset($request->date_from), function ($q) use ($request) {
return $q->where('date_created', '>=', $request->date_from);
});
$query->when(isset($request->date_to), function ($q) use ($request) {
return $q->where('date_created', '<=', $request->date_to);
});
$query->when(isset($request->user), function ($q) use ($request) {
return $q->where('user', $request->user);
});
$query->when(isset($request->paid), function ($q) use ($request) {
if ($request->paid === true) {
return $q->whereNotNull('paid');
} else {
return $q->whereNull('paid');
}
});
$query->when(isset($request->informed), function ($q) use ($request) {
return $q->where('informed', $request->informed);
});
$query->when(isset($request->endorsement), function ($q) use ($request) {
if ($request->endorsement === true) {
$query->where('policy', '<', 1);
} else {
$query->where('policy', '>', 1);
}
});
$query->when(isset($request->duplicate), function ($q) use ($request) {
return $q->where('duplicate', $request->duplicate);
});
$query->when(isset($request->active), function ($q) use ($request) {
return $q->where('active', $request->active);
});
return response()->json($query, $this->success_status);
}
I've tested the $request payload multiple times and there's no issues with the information coming client-side.
What am I doing wrong?
You can try given solution for you problem.
$query = Ticket::all();
if ($request->filled('user')) {
$user = $request->get('user');
$query->where(function ($query) use ($user) {
$query->where('user', $user);
});
}
Note: if it is working perfect then you can add all request parameter according.
First note:
$query = Ticket::all();
In this case $query is not Eloquent query but Laravel Collection.
Another note:
$request is not regular php object with properties, so you have to use ->has(), ->filled() instead of empty() or isset()
Your ->data_to and ->data_from are working, cause you have overwritten those values in the beginning, so they become regular object properties.
Also, I would simplify some parts of your code:
$query->when(isset($request->duplicate), function ($q) use ($request) {
return $q->where('duplicate', $request->duplicate);
});
I would use this construction instead to save some lines:
$query->where('duplicate', $request->get('duplicate', false));
Second param of ->get is default value. If it is not present in request you will get false anyway. So you don't have to care about param existence.
You can apply same logic to all other filters as well.
PS: I don't know your requirements, but this part seems suspicious to me:
$query->when(isset($request->endorsement), function ($q) use ($request) {
if ($request->endorsement === true) {
$query->where('policy', '<', 1);
} else {
$query->where('policy', '>', 1);
}
});
This code will never give 'policy' === 1;

Laravel 7.14 when condition not working properly

I am trying to create filters using where and wherebetween. If the user doest not enter the value in whereBetween it should not be in url.
Here's my Controller:
$prod = $request->input('productfm');
$sub = $request->input('sub-family');
$location = $request->input('location');
$thickness = [$request->input('minthick'), $request->input('maxthick')];
$width = [$request->input('minwidth'), $request->input('maxwidth')];
$weight = [$request->input('minweight'), $request->input('maxweight')];
// dd($prod);
$products = Product::where('state_id', '=', '1')
->when(!empty($prod), function ($query) use ($prod) {
return $query->where('product_family', $prod);
})
->when(!empty($sub), function ($query) use ($sub) {
return $query->where('sub_family', $sub);
})
->when(!empty($location), function ($query) use ($location) {
return $query->where('location', $location);
})
->when(!empty($thickness), function ($query) use ($thickness) {
return $query->whereBetween('thick', $thickness);
})
->when(!empty($width), function ($query) use ($width) {
return $query->whereBetween('width', $width);
})
->when(!empty($weight), function ($query) use ($weight) {
return $query->whereBetween('weight', $weight);
})
->get();
All fields are a select input in form. If I keep $prod, $sub_family and $location it works. But it's not working in whereBetween range filter.
URL still shows empty input of range filters and results don't come-up.
How do I make it clean/dynamic url? On dd($product) it returns empty array.

Filtering in Laravel using regex

I'm trying to filter products based on query string. My goal is to get products from a collection if it's given, otherwise get every product. Could someone help me what's wrong with the following code?
$products = \App\Product::where([
'collection' => (request()->has('collection')) ? request('collection') : '[a-z]+',
'type' => (request()->has('type')) ? request('type') : '[a-z]+'
])->get();
PS.: I've also tried with 'regex:/[a-z]+', it's not working...
$products = \App\Product::where(['collection' => (request()->has('collection')) ? request('collection') : 'regex:/[a-z]+'])->get();
What you can do is use when eloquent clause, so your where clause for collections will be triggered only when the request('collection') exists, same logis applie to type as well.
$products = \App\Product::
when(request()->has('collection'), function ($q) {
return $q->where('collection', request('collection'));
});
->when(request()->has('type'), function ($q) {
return $q->where('type', request('type'));
})
->get();
Or another way if you have your request values assigned to a variable something like:
$collection = request('collection');
$type= request('type');
$products = \App\Product::
when(!empty($collection), function ($q) use ($collection) {
return $q->where('collection', $collection);
});
->when(!empty($type), function ($q) use ($type) {
return $q->where('type', $type);
})
->get();

Laravel filters won't work when trying to add them

So I'm making a fliter in laravel for a project and me and my teacher are braking our head on a the following thing.
In the code below the general search for a player works but the other statements won't add to it if they are defined and in the POST request;
Controller:
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Input;
class FilterController extends Controller
{
public function filter(Request $request)
{
$player = new \App\Player;
$filters = $player->newQuery();
$query = Input::get('q');
// Search for a player based on their status.
if ($request->has('status')) {
$filters->orwhere('status', $request->input('status'));
}
// Search for a player player on their club.
if ($request->has('club')) {
$filters->orwhere('Club', $request->input('club'));
}
// Search for a player player on their team category .
if ($request->has('Category')) {
$filters->orwhere('Category', $request->input('Category'));
}
// Search for a player player if he is flagged as removed.
if ($request->has('remove')) {
$filters->orwhere('remove', $request->input('remove'));
}
// Search for a player player on their size.
if ($request->has('size')) {
$filters->orwhere('Size', $request->input('size'));
}
// General search for a player
if($request->has('q')){
$filters->orwhere('first_name','LIKE','%'.$query.'%')
->orWhere('last_name','LIKE','%'.$query.'%')
->orWhere('mobile','LIKE','%'.$query.'%')
->orWhere('street_name_nummer','LIKE','%'.$query.'%')
->orWhere('city','LIKE','%'.$query.'%');
}
// Get the results and return them.
$results = $filters->get();
if(count($results) > 0){
return view('lists/ekick')->withDetails($results,$query);
} else return view ('lists/ekick')->with('No Details found. Try to search again !');
}
}
route:
Route::any('lists/ekick', 'FilterController#filter');
output view:
img from view
To pick up on Aaron Sarays answer, you are most likely filtering the wrong way. Normally additional filters are additional conditions each record has to meet in order to be part of the result. If you consider an Excel table and you filter one column, you won't even have all options to filter for in the second column because you already limited the result and you can only limit it further.
Combine this knowledge with an improved way of filtering and you receive a query like this:
public function filter(Request $request)
{
$query = $request->input('q');
$results = \App\Player::query()
->when($request->input('status'), function ($query, $status) {
$query->where('status', $status);
})
->when($request->input('club'), function ($query, $club) {
$query->where('club', $club);
})
->when($request->input('category'), function ($query, $category) {
$query->where('category', $category);
})
->when($request->input('remove'), function ($query, $remove) {
$query->where('remove', $remove);
})
->when($request->input('size'), function ($query, $size) {
$query->where('size', $size);
})
->when($query, function ($query, $q) {
$query->where(function ($query) use ($q) {
$query->where('first_name', 'LIKE', "%$q%")
->orWhere('last_name', 'LIKE', "%$q%")
->orWhere('mobile', 'LIKE', "%$q%")
->orWhere('street_name_number', 'LIKE', "%$q%")
->orWhere('city', 'LIKE', "%$q%");
});
})
->get();
if ($results->isNotEmpty()) {
return view('lists/ekick')->withDetails($results, $query);
} else {
return view ('lists/ekick')->with('No Details found. Try to search again !');
}
}
The function when($condition, $callback) as used in the query above is used to dynamically build queries. You can consider the following two statements equivalent:
// option 1: conditional query (preferred!)
$results = Player::query()
->when($request->input('q'), function ($query, $q) {
$query->where('name', 'LIKE', "%$q%");
})
->get();
// option 2: plain php query building... (not very clean code)
$query = Player::query();
if ($request->input('q')) {
$query->where('name', 'LIKE', '%'.$request->input('q').'%');
}
$results = $query->get();
In order to do what you're doing, I think you want to not use or with your queries. You're basically saying
Give me the Player where status is something or size is something
I think what you mean to say is
Give me the Player where status is something and size is something
Depending on if the requirements exist or not in the filter.
So, you'd want to alter your code using the following as an example:
if ($request->has('status')) {
$filters->where('status', $request->input('status'));
}
// Search for a player player on their club.
if ($request->has('club')) {
$filters->where('Club', $request->input('club'));
}
You can also bypass one step by using this:
$query = \App\Player::getQuery();

Laravel/Eloquent: Add missing () in sql statements generated by eloquent

I am doing the following request to extract some data from my database. The expected result is wrong because some parenthesis is not well placed in the SQL generated request:
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero)
->orWhere('lastKnownUpAt','<>', '0');
}
])->where('ovId', '=', $ovId)->get();
The dedicated sql generated by Laravel is: (see with Laravel debugbar):
select * from `masterequipments` where `masterequipments`.`id_ov_foreign_key` in ('38') and `macAddress` in ('e8:e7:32:c1:e6:48', 'e8:e7:32:bc:b0:94', 'e8:e7:32:e4:8e:68', 'e8:e7:32:bc:a7:70', '00:e0:b1:fe:ef:a5', 'e8:e7:32:bc:a7:a4', '2c:fa:a2:10:79:74', 'e8:e7:32:b9:6d:1d', '00:e0:b1:ee:58:2d', '00:e0:b1:9d:2c:44', '00:e0:b1:b5:e6:00', '00:e0:b1:72:34:86', '00:e0:b1:fe:ee:8d', '00:e0:b1:79:53:52', '00:e0:b1:fe:f0:bd', '00:e0:b1:75:fa:8a', 'e8:e7:32:98:80:22', '00:e0:b1:75:00:8a') or `lastKnownUpAt` <> '0'
This is wrong because 2 () are missed. I would like to have:
select * from `masterequipments` where `masterequipments`.`id_ov_foreign_key` in ('38') and (`macAddress` in ('e8:e7:32:c1:e6:48', 'e8:e7:32:bc:b0:94', 'e8:e7:32:e4:8e:68', 'e8:e7:32:bc:a7:70', '00:e0:b1:fe:ef:a5', 'e8:e7:32:bc:a7:a4', '2c:fa:a2:10:79:74', 'e8:e7:32:b9:6d:1d', '00:e0:b1:ee:58:2d', '00:e0:b1:9d:2c:44', '00:e0:b1:b5:e6:00', '00:e0:b1:72:34:86', '00:e0:b1:fe:ee:8d', '00:e0:b1:79:53:52', '00:e0:b1:fe:f0:bd', '00:e0:b1:75:fa:8a', 'e8:e7:32:98:80:22', '00:e0:b1:75:00:8a') or `lastKnownUpAt` <> '0')
Use advanced where clauses to accomplish it.
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->where(function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero);
})
->orWhere(function($query) {
$query->where('lastKnownUpAt','<>', '0');
});
}
])->where('ovId', '=', $ovId)->get();
UPDATE
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->where(function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero);
})
->orWhere('lastKnownUpAt','<>', '0');
}
])->where('ovId', '=', $ovId)->get();
Yo need to do something like this:
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->where(function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero);
})
->orWhere(function($query) {
$query->where('lastKnownUpAt','<>', '0');
});
}
])->where('ovId', '=', $ovId)->get();
This article explain it well http://laraveldaily.com/and-or-and-brackets-with-eloquent/

Categories