Best way convert json string to Laravel Query Builder? - laravel

i have a filter string, what do you think how can i convert laravel query builder? I used some ways but I wasn't sure.
filter: [["id","=",2],"or",["id","=",3],"and",["name","LIKE", "%John%"]]
Thank you.
if ($request->get('filter')) {
$filter = json_decode($request->get('filter'));
if (gettype($filter[0]) === 'string') {
list($field, $id) = $filter;
$query->where($field, $id);
} elseif (gettype($filter[0]) === 'array') {
foreach ($filter as $value) {
if (gettype($value) === 'string') {
switch ($value) {
case 'or':
//
break;
case 'and':
//
break;
}
} elseif (gettype($value) === 'array') {
list($field, $clause, $id) = $value;
}
}
}
}

Maybe something like this:
$arr = [["id","=",2],"or",["id","=",3],"and",["name","LIKE", "%John%"]];
$query = Model::query(); // build the empty query
if(size($arr) > 0){ // if there is at least 1 element
$query->where(...$arr[0]); // apply that element
for($i = 1; $i < size($arr); $i+=2){ // for every other entry, loop through them 2 by 2 and based of the current one, apply orWhere or where
if($arr[$i] === "or")
$query->orWhere(...$arr[$i+1]);
else
$query->where(...$arr[$i+1]);
}
}
$result = $query->get();

Related

multiple orderby sorting with pagination in laravel not working

I wrote the code snippet inside my Laravel controller and I want to sort the products by product number first and then sort the previously sorted products by inventory.
My problem is that the first sort is executed inside the written command but the second sort does not happen.
My code snippet is as follows:
DB::statement("SET SQL_MODE=''");//this is for fix groupby error!
$productdetail = Sa_product::leftJoin('sa_product_allproperties', 'sa_products.productid', 'sa_product_allproperties.product_id')->where('sa_products.product_status', '1');
if (isset($data['static']) && $data['static']['search_products'] != '') {
$search_word = $data['static']['search_products'];
DB::statement("SET SQL_MODE=''");//this is for fix groupby error!
$exploded_word = explode(',', $search_word);
$counter = 0;
$productdetail = $productdetail->where(function ($q) use ($exploded_word, $counter) {
$counter = 0;
foreach ($exploded_word as $word) {
if ($counter == 0) {
$q->where('sa_products.title', 'LIKE', "%{$word}%");
} else {
$q->orwhere('sa_products.title', 'LIKE', "%{$word}%");
}
$counter++;
}
});
}
$data['staticcats'] = explode(',', $data['static']['product_cats']);
if (isset($data['static']) && $data['static'] != '') {
$explodecats = explode(',', $data['static']['product_cats']);
unset($explodecats[0]);
array_pop($explodecats);
} else {
$explodecats = [];
}
if (isset($explodecats) && $explodecats != []) {
$counter = 0;
$productdetail = $productdetail->where(function ($q1) use ($explodecats, $counter) {
$counter = 0;
foreach ($explodecats as $cats) {
if ($counter == 0) {
$q1->where('sa_products.catid', 'LIKE', "%,{$cats},%");
} else {
$q1->orWhere('sa_products.catid', 'LIKE', "%,{$cats},%");
}
$counter++;
}
});
$productdetail = $productdetail->orderBy('visited_counter', 'DESC');
}
$data['staticcats'] = explode(',', $data['static']['product_brands']);
if (isset($data['static']) && $data['static'] != '') {
$explodebrands = explode(',', $data['static']['product_brands']);
unset($explodebrands[0]);
array_pop($explodebrands);
} else {
$explodebrands = [];
}
if (isset($explodebrands) && $explodebrands != []) {
$counter = 0;
$productdetail = $productdetail->where(function ($q2) use ($explodebrands, $counter) {
$counter = 0;
foreach ($explodebrands as $brands) {
if ($counter == 0) {
//$q1->where('brand_id','LIKE', "%,{$brands},%");
$q2->where('sa_products.brand_id', "{$brands}");
} else {
//$q1->orWhere('brand_id','LIKE', "%,{$brands},%");
$q2->orWhere('sa_products.brand_id', "{$brands}");
}
$counter++;
}
});
}
$productdetail = $productdetail->orderBy('sa_products.productid','DESC')->orderBy('sa_product_allproperties.stock_count','DESC')->groupBy('sa_products.productid')->paginate(20);
if (isset($productdetail) && $productdetail->count()>0)
{
$data['searched_products'] = $productdetail;
}
After executing the above code, the received products are sorted by product number, ie the orderBy('sa_products.productid', 'DESC') occurs, but the second sorting is done with the orderBy('sa_product_allproperties.stock_count', 'DESC') Which is not run for inventory sorting.
Can anyone help me solve this problem?

Where function query withcount not working Laravel

this works perfectly fine
return Webinar::query()
->withCount('users')->orderByDesc('users_count')
->get();
but I need to use a condition for sorting, but this doesnt work
return Webinar::query()
->where(function($query) use ($sort_by) {
if($sort_by == 0) {
return $query->withCount('users')->orderByDesc('users_count');
} else {
return $query->withCount('review')->orderByDesc('review_count');
}
})
->get();
I also tried a condition inside like this to check my if else function
return Webinar::query()
->where(function($query) use ($sort_by) {
if($sort_by == 0) {
return $query->withCount('users')->orderByDesc('users_count')
->where('status', 2);
} else {
return $query->withCount('review')->orderByDesc('review_count')
->where('status', 1);
}
})
->get();
but the where status is only working not withcount. I hope someone can answer, thank you so much
How about you move condition code outside query
but I need to use a condition for sorting, but this doesnt work
if ($sort_by === 0) {
$order = 'users_count';
$count = 'users';
} else {
$order = 'review_count';
$count = 'review';
}
return Webinar::query()
->withCount('users')->orderByDesc($order)
->get();

If clauses between where composition to laravel collect

Situation:
$post_1 = 'john';
$post_2 = 30;
$arr = array(['name'=>'john','number'=>70],['name'=>'clark','number'=>50]);
$collection = collect($arr);
if($post_1 == 'john')
{
$collection->where('name',$post_1);
}
if($post_2 == 70)
{
$collection->where('number',$post_2);
}
var_dump($collection->all());
But this doesn't work. I want to include filters but it depends on the post parameters to exist.
I think you can use when
$result= $collection->when(($post_1=="john"), function ($collection)use($post_1) {
return $collection->where('name',$post_1);
})->when(($post_2 == 70), function ($collection)use($post_2) {
return $collection->where('number',$post_2);
})->all();
dd($result);
or
$collection->when(($post_1=="john"), function ($collection)use($post_1) {
return $collection->where('name',$post_1);
})->when(($post_2 == 70), function ($collection)use($post_2) {
return $collection->where('number',$post_2);
});
dd($collection->all());
Ref:https://laravel.com/docs/8.x/collections#method-when

how to return true to parent filter loop from child each loop on collection laravel

$products = $category - > products;
foreach($params as $key => $item) {
if ($key === 'attribute') {
$attributes = $item;
// dd($attributes);
foreach($attributes as $subkey => $value) {
// dd($subkey, $value);
$attr_ids = ProductAttribute::where('name', $subkey) - > pluck('id') - > toArray();
// print_r($attr_ids);
// dd($attr_ids);
foreach($attr_ids as $attr_id) {
$filtered_products = new Collection();
$filtered_products = $products - > filter(function($item) use($attr_id, $value)
{
// echo $attr_id;
$item - > characteristics - > each(function($charac) use($value)
{
// print_r($charac->value);
// dd($value);
return in_array($charac - > value, $value);
});
});
$products = $filtered_products;
}
}
}
}
I'm developing a filter.
after retrieving products by category
I'm looping through params url(which is http://127.0.0.1:8000/dariy?attribute[size][0]=xs&attribute[rang][0]=black&property[color][0]=green&property[color][1]=tomato)
in DB, I have got a table of products,productCharacteristics, and productAttributes.
I'm retrieving ids of attributes by name which are given in params(key).
productCharacteristics is being retrieved by relationship.
while I go through the product's characteristics, I check each characteristic's value against in value from params.
if right I should return true to filter. but here is where I'm stuck.
inside filter closure there's each that's why I can't return directly to filter.
How can I do that?
I'm
foreach ($params as $key => $item) {
if ($key === 'attribute' && !empty($item)) {
$filtered_products = new Collection();
$attributes = $item;
// dd($attributes);
foreach ($attributes as $subkey => $value) {
// dd($subkey, $value);
$attr_ids = ProductAttribute::where('name', $subkey)->pluck('id')->toArray();
// print_r($attr_ids);
// dd($attr_ids);
$attr_status = false; // assume there's no match
foreach ($attr_ids as $attr_id) {
$filtered_products = $products->filter(function ($item) use ($attr_id, $value, &$attr_status)
{
// assume product can't pass filter
$item->status = false;
$item->characteristics->each(function ($charac) use (&$item, $value, $attr_id)
{
// product characteristic's attribute_id and charac value match set to tru to return to filtered prducts
if($attr_id == $charac->attribute_id && in_array($charac->value, $value)){
$item->status = true; // now product can pass.
return true;
}
});
if ($item->status === true) {
$attr_status = true;
return true;
}else{
return false;
}
});
// setting there's a match for this filter.
if ($attr_status) {
continue 2; // skipping to next filter
}
}
}
$products = $filtered_products;
}
}
in first level of each closure I set a variable $attr_status = false so the each filter keeps going on.
2.in every product attribute checked the value and attribute id do match or not
if yes $product goes in the filter and I set $attr_status = true;
so the filter cycle can be skipped.

How to display last query in laravel 5?

I use :
DB::connection()->enableQueryLog();
var_dump(DB::getQueryLog());
But it's not working.
My service is like this :
public function dataCustomerList($param)
{
$status = $param['status_sort'];
$gender = $param['gender'];
$published = $param['published'];
if($published=='NO'){
$published_check = 'NO';
$published = 0;
}
else if($published=='YES'){
$published_check = 'YES';
$published = 1;
}
DB::connection()->enableQueryLog();
$customer = customer::paginate(10);
if(!empty($status)) {
// die($status);
$customer = customer::where('tb_customer.customer_status', '=', $status)->paginate(10);
}
if (!empty($gender)) {
$customer = customer::where('tb_customer.gender', '=', $gender)->paginate(10);
}
if (!empty($published_check)) {
$customer = customer::where('tb_customer.published', '=', $published)->paginate(10);
}
var_dump(DB::getQueryLog());
return $customer;
}
When I run it, query does not appear
The result is like this :
array(0) {
}
How to get the query executed in Laravel 5?
Thank you very much
You could listen to query events on DB:
DB::listen(function($query) {
var_dump($query->sql);
});

Resources