if I has a function like this
if($request->has('q')){
$q=$request->q;
$from_price=$request->from_price;
$to_price=$request->to_price;
$products = Product::where('title','like','%'.$q.'%')
->whereBetween('price',[$from_price, $to_price])
->orderBy('id','desc')->Paginate(6);
}else{
$products = Product::where('category_id',$cat_id)->orderBy('id','desc')->paginate(6);
}
where give me the title from input q
and also I used therebetween for price
but where between doesn't work except after I put 0 and exactly the product price
example:
I have iPhone 12 and it is 999$
I should write 0 and 999
and if I write 0 and 1000
it doesn't work
Please try below code
if($request->has('q')){
$q=$request->q;
$from_price=(float)$request->from_price;
$to_price=(float)$request->to_price;
$products = Product::where('title','like','%'.$q.'%')
->whereBetween('price',[$from_price, $to_price])
->orderBy('id','desc')->Paginate(6);
}else{
$products = Product::where('category_id',$cat_id)->orderBy('id','desc')->paginate(6);
}
Add this to your AppServiceProvider boot method:
Builder::macro('whereLike', function ($attributes, string $searchTerm) {
$this->where(function (Builder $query) use ($attributes, $searchTerm) {
foreach (Arr::wrap($attributes) as $attribute) {
$query->orWhere($attribute, 'LIKE', "%{$searchTerm}%");
}
});
return $this;
});
Then for your query you can use:
$products = Product::whereLike('title', $q)
->whereBetween('price',[$from_price, $to_price])
->orderBy('id','desc')
->Paginate(6);
Source:
https://freek.dev/1182-searching-models-using-a-where-like-query-in-laravel
if($request->has('q')){
$q=$request->q;
$from_price=$request->from_price;
$to_price=$request->to_price;
$products = Product::whereLike('title', $q)
->whereBetween('price',[$from_price, $to_price])
->orderBy('id','desc')
->Paginate(6);
}
else {
$products = Product::where('category_id',$cat_id)->orderBy('id','desc')->paginate(6);
}
Related
How can I search in two column in my mysql table example : I want search product name and with sku
I found some function but I cant entegreted , now only search with product name.
public function search(Builder $builder)
{
$result = [];
$query = DB::table($builder->model->searchTable());
$columns = implode(',', $builder->model->searchColumns());
$query->whereRaw("MATCH ({$columns}) AGAINST (? IN BOOLEAN MODE)", $this->getSearchKeyword($builder));
if ($builder->callback) {
$query = call_user_func($builder->callback, $query, $this);
}
$result['count'] = $query->count();
if (property_exists($builder, 'orders') && ! empty($builder->orders)) {
foreach ($builder->orders as $order) {
$query->orderBy($order['column'], $order['direction']);
}
}
if ($builder->limit) {
$query = $query->take($builder->limit);
}
if (property_exists($builder, 'offset') && $builder->offset) {
$query = $query->skip($builder->offset);
}
$result['results'] = $query->pluck($builder->model->searchKey());
return $result;
}
private function getProducts(Product $model)
{
return $model->search(request('query'))
->query()
->limit(10)
->withName()
->withBaseImage()
->withPrice()
->addSelect([
'products.id',
'products.slug',
'products.in_stock',
'products.manage_stock',
'products.qty',
'products.sku',
])
->with(['files', 'categories' => function ($query) {
$query->limit(5);
}])
->when(request()->filled('category'), $this->categoryQuery())
->get();
}
I've got some product with deals. Every product has several deals. I managed to get the whereBetween, but only on all associated deals. I would like to only return products where the lowest deal matches the whereBetween.
So get products where the lowest associated deal price is between the min & max given price.
Here is my code so far:
$products = Product::when($request->filled('brand'), function ($query)use($request) {
$brandRequest = $request->input('brand');
$brandReqArray = explode(',', $brandRequest);
$query->whereHas('brands', function($q) use ($brandReqArray) {
$q->whereIn('slug', $brandReqArray);
});
})->when($request->filled('gender'), function ($query)use($request) {
$genderRequest = $request->input('gender');
$genderReqArray = explode(',', $genderRequest);
$query->whereHas('genders', function($q) use ($genderReqArray) {
$q->whereIn('slug', $genderReqArray);
});
})->when($request->filled('price'), function ($query)use($request) {
$priceRequest = $request->input('price');
$priceReqArray = explode(';', $priceRequest);
$query->whereHas('deals', function($q) use ($priceReqArray) {
$q->whereBetween('price', $priceReqArray);
});
})->with(['deals' => function ($query) {
$query->orderBy('price','asc');
}])->paginate(24);
$input = $request->only(['brands', 'gender', 'price']);
$products->appends($input);
Try this and let me know, is that what you wanted?
$products = Product::when($request->filled('brand'), function ($query)use($request) {
$brandRequest = $request->input('brand');
$brandReqArray = explode(',', $brandRequest);
$query->whereHas('brands', function($q) use ($brandReqArray) {
$q->whereIn('slug', $brandReqArray);
});
})->when($request->filled('gender'), function ($query)use($request) {
$genderRequest = $request->input('gender');
$genderReqArray = explode(',', $genderRequest);
$query->whereHas('genders', function($q) use ($genderReqArray) {
$q->whereIn('slug', $genderReqArray);
});
})->when($request->filled('price'), function ($query)use($request) {
$priceRequest = $request->input('price');
$priceReqArray = explode(';', $priceRequest);
$query->whereHas('deals', function($q) use ($priceReqArray) {
$q->whereBetween('price', $priceReqArray)
->whereNotExists(function ($q)use($priceReqArray) {
$q->select(DB::raw(1))
->from('deals')
//->whereNull('deals.deleted_at')
->whereNotBetween('price', $priceReqArray)
->whereRaw('product.id = deals.productId');
})
->orderBy('price','asc')->limit(1);
})
})->paginate(24);
I want the following to happen - search by fields if fields are different from "all". Something like this:
// If $request['field'] != 'all' add query
if(isset($request['types'])) {
$query = Offer::whereHas('types', function ($query) use ($request) {
$typeArray = $request->get('types');
$query->whereIn('type', $typeArray);
});
}
if ($request['country'] != 'all') {
query->where('country_id', $country);
}
At the end I want to order and paginate the results like so:
$offers = $query->orderBy('created_at', 'desc')->paginate(9);
Is there any way to achieve this? If my question isn't clear enough tell me and I will edit it and try to explain better.
You can use eloquent when method to check conditions and append query. in when method you can check your conditions.
Offer::when(isset($request['types']), function($query) {
$query->whereHas('types', function ($query) {
$query->whereIn('type', request()->get('types'));
});
})
->when(request()->country != 'all', function($query) {
$query->where('country_id', request()->country);
})
->orderBy('created_at', 'desc')->paginate(9);
Can you try this:
<?php
$query = Offer::where(function($q) use ($request){
if ( !empty($request['country']) && is_numeric($request['country']) ) {
$query->where('country_id', $request['country']);
}
if( !empty($request['types']) && is_array($request['types']) ) {
$q->whereHas('types', function ($q) use ($request) {
$typeArray = $request->get('types');
$q->whereIn('type', $typeArray);
});
}
});
$offers = $query->orderBy('created_at', 'desc')->paginate(9);
I have a controller that get the four inputs from a search form.
SearchController.php code
public function results(Request $request) {
$text = $request -> text;
$pet = $request -> pet;
$category = $request -> category;
$city = $request -> city;
$searchArray = [];
if(empty($text) && empty($pet) && empty($category) && empty($city)) {
Session::flash('danger', "You didn't select any search any search.");
return redirect() -> back();
}
//SEARCH CODE HERE
}
What I am trying to do
I am trying to search 4 columns in my database
Problem is
I need also to search the 4 columns in one query.
That means that I need to check if the $text variable is not empty and $pet variable is not empty then I have to do this query:
if(!empty($text) && !empty($pet))
$result = Post::where('text', 'like', '%'.$text.'%') -> where('text', $pet) -> get();
This method will work fine but I will have multiple if statements that will check all the possibilities.
Is there faster and optimal solution?
Option 1
Build logic manually. This is the best way in many situations. An example:
$result = Post::query();
if (!empty($text)) {
$result = $result->where('text', 'like', '%'.$text.'%');
}
if (!empty($pet)) {
$result = $result->where('pet', $pet);
}
if (!empty($category)) {
$result = $result->where('category', $category);
}
if (!empty($city)) {
$result = $result->where('city', 'like', '%'.$city.'%');
}
$result = $result->get();
Option 2
Use conditional clauses. Example:
Post::when($text, function ($q) use ($text) {
return $q->where('text', 'like', '%'.$text.'%');
})
->when($pet, function ($q) use ($pet) {
return $q->where('pet', $pet);
})
->when($category, function ($q) use ($category) {
return $q->where('category', $category);
})
->when($city, function ($q) use ($city) {
return $q->where('city', 'like', '%'.$city.'%');
})
->get();
So I am trying to set up a search page and it has multiple get options But I am curious as to how to set this up correctly, I know this is far from correct as I am doing if statements inside of setting a variable, But I am so lost right now.
Any help would be greatly appreciated.
public function index()
{
$queryUsername = Request::get('u');
$queryPostcode = Request::get('p');
$queryOrderbyPhotos = Request::get('o1');
$queryOrderbyOnline = Request::get('o2');
$queryOrderbyTypes = Request::get('o3');
$users = User::rightJoin('user_profiles','users.id', '=', 'user_profiles.user_id')
if ($queryUsername)
{
->where('users.username', '=', "$queryUsername")
}
if ($queryPostcode) {
->where('user_profiles.postcode', '=', "$queryPostcode")
}
if ($queryOrderbyPhotos) {
->whereNotNull('user_profile.avatar')
}
if ($queryOrderbyOnline) {
->orderBy('users.last_online', 'DESC')
}
if ($queryOrderbyType) {
->orderBy('users.type', 'DESC')
}
->get();
return view('view', compact('users'));
}
This is how I'll approach the problem. I'll create a variable holding the query builder and then call all the additional query methods on it.
With Eloquent and actually with any class that allows Method Chaining you can do this:
$query = User::select(...)->join(..);
$query->where(...);
$query->get(...);
So in your case I'll be trying to achieve what you want in this manner:
public function index()
{
$input = Request::all();
$query = User::rightJoin('user_profiles', 'users.id', '=', 'user_profiles.user_id');
if (isset($input['u']) && $input['u'])
$query->where('users.username', '=', $input['u']);
if (isset($input['p']) && $input['p'])
$query->where('user_profiles.postcode', '=', $input ['p']);
if (isset($input['o1']) && $input['o1'])
$query->whereNotNull('user_profile.avatar');
if (isset($input['o2']) && $input['o2'])
$query->orderBy('users.last_online', 'DESC');
if (isset($input ['o3']) && $input['o3'])
$query->orderBy('users.type', 'DESC');
$users = $query->get();
return view('view', compact('users'));
}
Of course it will be a good idea that you have an additional check for valid input on each input parameter. But this can be achieved in many ways. You can read more about Laravel Controller Validation or Laravel Form Request Validation
By the way I'll suggest to move all this code in your model or in separate class as I prefer keeping controllers slim.
You can try :
$users_query = new User;
$users_query->rightJoin(....);
if ($queryUsername)
{
$users_query->where('users.username', '=', "$queryUsername")
}
// Your other conditions .....
....
$users = $users_query->get();
multiple option search
This is a trait that can be used by any models
This function will remove code repetitions into your project
public function scopeSearch($query, $keyword, $columns = [], $relativeTables = [])
{
if (empty($columns)) {
$columns = array_except(
Schema::getColumnListing($this->table), $this->guarded
);
}
$query->where(function ($query) use ($keyword, $columns) {
foreach ($columns as $key => $column) {
$clause = $key == 0 ? 'where' : 'orWhere';
$query->$clause($column, "LIKE", "%$keyword%");
if (!empty($relativeTables)) {
$this->filterByRelationship($query, $keyword, $relativeTables);
}
}
});
return $query;
}
Filter into relationship also
private function filterByRelationship($query, $keyword, $relativeTables)
{
foreach ($relativeTables as $relationship => $relativeColumns) {
$query->orWhereHas($relationship, function($relationQuery) use ($keyword, $relativeColumns) {
foreach ($relativeColumns as $key => $column) {
$clause = $key == 0 ? 'where' : 'orWhere';
$relationQuery->$clause($column, "LIKE", "%$keyword%");
}
});
}
return $query;
}