Laravel- How to cache custom query with Redis - laravel

How can I cache custom query into redis. I am trying the following
public function __construct()
{
$this->orders_sql = Cache::remember('orders', 10, function () {
return $query = DB::connection('db1')->table('orders as o')
->leftJoin('addresses as pa', 'o.id', '=', 'pa.order_id')
->leftJoin('users as u', 'o.user_id', '=', 'u.id')
->leftJoin('clients', 'clients.user_id', '=', 'u.id')
->select(
'o.id as id', 'o.type as type', 'o.extra_info as extra_info', 'o.status as order_status', 'o.created_at as created_at', 'o.type as order_type', 'o.inspection_date as inspection_date', 'o.assignee as assignee', 'o.user_id as user_id', 'o.inspector_name as inspector_name',
'pa.address as address', 'pa.city as city', 'pa.state as state',
'clients.first_name as first_name', 'clients.middle_name as middle_name', 'clients.last_name as last_name'
)
->whereIn('o.status', OrderHelper::$ALLOWED_STATUS)
->where('o.type', '<>', OrderHelper::$CONSTRUCTION_EXISTING)
->where('o.deleted_at', null);
});
}
public function orders($sort_by, $sort_order, $limit, $filters)
{
if ($filters) {
$query = $this->applyFilters($filters);
}
$orders = $query->orderBy($sort_by ?? OrderHelper::$DEFAULT_SORT_COLUMN, $sort_order ?? OrderHelper::$DEFAULT_SORT_ORDER);
if ($limit === 'all') {
$orders = $orders->get();
} else {
$orders = $orders->get();
// $orders = $orders->paginate($limit ?? CommonHelper::$DEFAULT_PAGINATION_LIMIT);
}
//adding more information with orders such as Bank and address info
foreach ($orders as $order) {
$order->created_at = OrderHelper::getFormattedDate($order->id);
$order->draw = OrderHelper::draw($order->id);
$order->inspection_date = OrderHelper::getFormattedInspectionDate($order->inspection_date);
$order->client_name = $order->first_name . ' ' . $order->middle_name . ' ' . $order->last_name;
$order->type = OrderHelper::getFormattedOrderType($order);
if (empty($order->assignee)) {
$order->inspector_name = '-';
}
}
return $orders ? $orders : false;
}
And I am getting the error as
"message": "Serialization of 'Closure' is not allowed",
"exception": "Exception",
"file": "/var/www/api.local/vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php",
"line": 295,

I'm guessing that you are using one of the laravel services like queue or something if yes in your case laravel tries uses serialize() function to serialize the class properties but one problem with serialize() function is that it cannot serialize closure that you are passing
anonymous functions cannot be serialized thats php behavior
What you can do is to try to assign the result to the property or pass the result to the constructor...

Related

Need to get data with laravel when query

I am trying to filter data using when query in Laravel, where it should filter data using the filter $sortBy or $categoryId. Please note the all 3 fields like $id $sortBy $categoryId are optional and will not be presented in all queries
public function Products(Request $request)
{
$page = $request->has('page') ? $request->get('page') : 1;
$limit = $request->has('itemsPerPage') ? $request->get('itemsPerPage') : 10;
$sortBy = (($request->sortBy == "popularity") ? "viewCount" : "created_at");
$categoryId= $request->get('categoryId');
$sellerId = $request->header('id')?SellersBranding::findOrFail($request->header('id')):"Null";
$productLive = ProductsLive::select('productTitle', 'product_id', 'brand_id', 'category_id')
->when($sellerId=="Null", function($query) use ($page, $limit){
return $query->where('status', 'active')
->limit($limit)->offset(($page - 1) * $limit);
})
->when($sortBy, function ($query) use ($sortBy, $sellerId, $page, $limit){
return $query->orderBy($sortBy, 'DESC')
->where('Sid', $sellerId->id)
->where('status','active')
->limit($limit)->offset(($page - 1) * $limit);
})
->when($categoryId, function ($query) use ($categoryId, $sellerId, $page, $limit) {
->where('Sid', $sellerId->id)
->where(['category_id' => $categoryId, 'status' => 'active'])
->limit($limit)->offset(($page - 1) * $limit)
->inRandomOrder();
})->get();
}
i am new in php and also in laravel please help how to get filtered data
i cleanup your code you can check this
public function Products(Request $request)
{
$page = $request->has('page') ? $request->get('page') : 1;
$limit = $request->has('itemsPerPage') ? $request->get('itemsPerPage') : 10;
$sortBy = (($request->sortBy == "popularity") ? "viewCount" : "created_at");
$categoryId= $request->filled('categoryId');
$seller = $request->header('id') ? SellersBranding::findOrFail($request->header('id')): null;
$productLive = ProductsLive::select('productTitle', 'product_id', 'brand_id', 'category_id')
->when($seller ,function ($query) use ($seller){
$query->where('Sid', $seller->id);
})
->when($categoryId ,function ($query)){
$query->where('category_id', request('categoryId'))
->inRandomOrder();
})
->where('status','active')
->orderBy($sortBy, 'DESC')
->limit($limit)->offset(($page - 1) * $limit);
return $productLive;
}
here when() something filter is coming we are only applying condition.
Not returning each filter as you did

Codeigniter count_all_results with having

I have composed a query using Codeigniter's Query Builder class. The query utilizes aliases and the having method. When I call the count_all_results method on this query, an exception occurs. Inspecting the log, I see that the query has stripped out the 'having' clauses. Is there a way to keep these clauses in while calling count_all_results? Thanks for your help.
EDIT: I first believed the problem was knowledge-based and not code-based and so did not share the code, but here it is. Please let me know if more is needed.
Here's the call on the model in the controller.
$where_array = array(
$parent_key.' is not NULL' => null
);
$search_post = $request_data['search'];
if (isset($request_data['filter'])) {
$filter_array = $request_data['filter'];
foreach ($filter_array as $filter_pair) {
if (isset($filter_pair['escape'])) {
$where_array[$filter_pair['filterBy']] = null;
} else {
if ($filter_pair['filterBy'] == 'table3_id') {
$where_array['table3.'.$filter_pair['filterBy']] = isset($filter_pair['filterId']) ?
$filter_pair['filterId'] : null;
} else {
$where_array[$table.'.'.$filter_pair['filterBy']] = isset($filter_pair['filterId']) ?
$filter_pair['filterId'] : null;
}
}
}
}
$like_array = array();
foreach ($request_data['columns'] as $key => $column) {
if (!empty($column['search']['value'])) {
$like_array[$column['data']] = $column['search']['value'];
}
}
$totalFiltered = $this->$model_name->modelSearchCount($search, $where_array, $like_array);
Here's the model methods.
public function modelSearchCount($search, $where_array = null, $like_array = null)
{
$this->joinLookups(null, $search);
if ($where_array) {
$this->db->where($where_array);
}
if ($like_array) {
foreach($like_array as $key => $value) {
$this->db->having($key." LIKE '%". $value. "%'");
}
}
return $this->db->from($this->table)->count_all_results();
}
protected function joinLookups($display_config = null, $search = null)
{
$select_array = null;
$join_array = array();
$search_column_array = $search ? array() : null;
$i = 'a';
$config = $display_config ? $display_config : $this->getIndexConfig();
foreach ($config as $column) {
if (array_key_exists($column['field'], $this->lookups)) {
$guest_model_name = $this->lookups[$column['field']];
$this->load->model($guest_model_name);
$join_string =$this->table.'.'.$column['field'].'='.$i.'.'.
$this->$guest_model_name->getKey();
$guest_display = $this->$guest_model_name->getDisplay();
if ($search) {
$search_column_array[] = $i.'.'.$guest_display;
}
$join_array[$this->$guest_model_name->getTable().' as '.$i] = $join_string;
$select_array[] = $i.'.'.
$guest_display;
} else {
$select_array[] = $this->table.'.'.$column['field'];
if ($search) {
$search_column_array[] = $this->table.'.'.$column['field'];
}
}
$i++;
}
$select_array[] = $this->table.'.'.$this->key;
foreach ($join_array as $key => $value) {
$this->db->join($key, $value, 'LEFT');
}
$this->db->join('table2', $this->table.'.table2_id=table2.table2_id', 'LEFT')
->join('table3', 'table2.table3_id=table3.table3_id', 'LEFT')
->join('table4', $this->table.'.table4_id=table4_id', 'LEFT')
->join('table5', 'table4.table5_id=table5.table5_id', 'LEFT');
$this->db->select(implode($select_array, ', '));
if ($search) {
foreach (explode(' ', $search) as $term) {
$this->db->group_start();
$this->db->or_like($this->table.'.'.$this->key, $term);
foreach ($search_column_array as $search_column) {
$this->db->or_like($search_column, $term);
}
$this->db->group_end();
}
}
$this->db->select('table2_date, '. $this->table.'.table2_id, table4_id, '. 'table5.table5_description');
}
Since count_all_results() will basically run a Select count(*) and not count the rows in your resultset (basically rendering the query useless for your purposes) you may use other Codeigniter methods to get the resultset and the row count.
Try running the query into a variable:
$query = $this->db->get();
From then, you can do pretty much anything. Besides returning the result with $query->result(); you can get the number of rows into another variable with:
$rownum = $query->num_rows();
You can then return that into your controller or even just return the $query object and then run the num_rows() method on the controller
To answer this question, count_all_results() transforms the original query by replacing your selects with SELECT COUNT(*) FROM table. the aliased column would not be selected, and the having clause would not recognize the column. This is why count_all_results() does not work with having.

How to create api for search in lumen/laravel?

How to create api for search in lumen/laravel .. I tried using keyword but not working.
public function index(){
$Employees = Employees::all();
$page = Input::get('page', 1);
$keyword = Input::get('keyword', '');
if ($keyword!='') {
$keyword = Employees::
where("firstname", "LIKE","%$keyword%")
->orWhere("lastname", "LIKE", "%$keyword%");
}
$itemPerPage=5;
$count = Employees::count();
$offSet = ($page * $itemPerPage) - $itemPerPage;
$itemsForCurrentPage = array_slice($Employees->toArray(), $offSet, $itemPerPage);
return new LengthAwarePaginator($itemsForCurrentPage, count($Employees), $itemPerPage, $page,$keyword);
}
You should change this line :
if ($keyword!='') {
$Employees = Employees::
where("firstname", "LIKE","%$keyword%")
->orWhere("lastname", "LIKE", "%$keyword%")
->get();
}
Also i think You should the pagination within the model query, not on the returned result.
you can also do this
define your logic in a scope created in you model and consume it in your controller.here is what i mean
This should be in your model
public function scopeFilter($query, $params)
{
if ( isset($params['name']) && trim($params['name'] !== '') )
{
$query->where('name', 'LIKE', trim($params['name']) . '%');
}
if ( isset($params['state']) && trim($params['state'] !== '') )
{
$query->where('state', 'LIKE', trim($params['state']) . '%');
}
return $query;
}
and in your controller have something like
public function filter_property(Request $request)
{
$params = $request->except('_token');
$product = Product::filter($params)->get();
return response($product);
}
you can get more by reading scope on laravel doc and this blog post here

Codeigniter confusing with $this->db queries

I'm trying to access data by using another model's method in my model but it gives me error because it confuses by previous $this->db parameters:
$this->db->select('*');
$this->db->group_start();
$this->db->like('title',$keyword);
$this->db->or_like('keyword',$keyword);
$this->db->group_end();
$locations = $this->place_model->search_ids_by_name($location);
and the search_ids_by_name() of Place_model is like this:
public function search_ids_by_name($q) {
$this->db->select('id');
$this->db->like('name',$q);
$qry = $this->db->get('places');
$results = $qry->result_array();
$place_ids = array();
foreach ($results as $result) {
array_push($place_ids, $result['id']);
}
return $place_ids;
}
But it gives me below error
Error Number: 1054, Unknown column 'category' in 'where clause'
Filename: models/Place_model.php
It seems in my place_model function also using like and or_like methods. How can I seperate them.
I found a solution. I made another connection:
public function search_ids_by_name($q) {
$places_db = $this->load->database('default', TRUE);
$places_db->select('id');
$places_db->like('name',$q);
$qry = $places_db->get('places');
$results = $qry->result_array();
$place_ids = array();
foreach ($results as $result) {
array_push($place_ids, $result['id']);
}
return $place_ids;
}

Laravel: dynamic where clause with Elouquent

I am calling URL with search params which are dynamic. How could I form proper Eloquent query?
In theory:
query
query where(someParam1)
query where(someParam2)
query orderby(someParam3)
query get
I need this kind of structure so I can use where clause if param exists.
If there is some other way in Laravel, please let me know.
It's easy with Laravel. Just do something like this:
$query = User::query();
if ($this == $that) {
$query = $query->where('this', 'that');
}
if ($this == $another_thing) {
$query = $query->where('this', 'another_thing');
}
if ($this == $yet_another_thing) {
$query = $query->orderBy('this');
}
$results = $query->get();
You can just use the where statement.
For ex: on users table or User model, you want dynamic search on name, id. You can do this
$where = [];
$firstName = $request->get('first_name');
if ($firstName) $where[] = ['first_name', 'like'. '%' . $firstName . '%'];
$id = $request->get('id');
if ($id) $where[] = ['id', $id];
$users = User::where($where)->get();
By default, it will return all the users, if anything exists in $where array, it will apply the where condition on that.
You can use like this
$validateUserDetail = User::query();
if (!empty($userDetails['email'])) {
$validateUserDetail->whereemail($userDetails['email']);
}if (!empty($userDetails['cellphone'])) {
$validateUserDetail->wherecellphone($userDetails['cellphone']);
}
$validateUserDetail->select('username');
$validateUserDetail->get()
You can pass dynamic value by below example
$user_auctions = $this->with('userAuctions')
->where('users.id', '=', $id)
->get();
I came here from Google. If you are going to be iterating over more then 5 if statements, its more effective to use a switch statement
if(empty($request->except('_token')))
return 'false';
$models = Vehicle::query();
$request_query = $request->all();
$year_switch = false;
foreach ($request_query as $key => $field_value){
if($field_value != 'any'){
switch($field_value){
case 'X':
case 'Y':
$year_switch = true;
break;
case'Z':
//Dynamic
$models->where($key,'LIKE', $field_value);
break;
}
}
}
You can pass a callback to the where function.
So, you can do something like this:
class TestService {
TestRepository $testeRepository;
public function __construct(TesteRepository $teste) {
$this->testeRepository = $teste;
}
public function getAll(array $filters)
{
$where = function (Builder $query) use ($filters) {
collect($filters)
->each(function ($value, $param) use ($query) {
if ($param === 'test') {
$query->where($param, '=', $value);
} else if ($param === 'test2') {
$query->orWhere($param, '>', $value);
}
});
};
return $this->testRepository->gelAll($where);
}
class TestRepository
{
public function getAll(\Closure $where)
{
$query = TestModel::query();
$query->where($where);
//and put more stuff here, like:
//$query->limit(15)->offset(30)
...
return $query->get();
}
}
And in your controller you pass the filters:
class TestControler ...
{
public function $index()
{
$filters = request()->query();
return $this->testService->getAll($filters);
}
}

Resources