Undefined variable: data", exception: "ErrorException",…} - laravel

I have an alias in this code that is RIGHT (no_antrian, 3) as code
when I call the alias with $ code, laravel says Undefined variable: data ", exception:" ErrorException ", ...}
$result = DB::table('data_antrian')->select(DB::raw('RIGHT(no_antrian,3) as kode'))->where('tanggal', '=', $tanggal)->orderBy('id', 'desc')->take(1)->get();
$rows = DB::table('data_antrian')->where('tanggal', '=', $tanggal)->count();
if ($rows > 0) {
// $data = mysql_fetch_assoc($result);
// $kode = $data['kode']+1;
$kode = $data['kode']+1;
} else {
$kode = '001';
}

You do not have data defined, meanwhile also you treat your $result variable as a single entity and it is a collection. Therefor i think this is what you want to do.
$result = DB::table('data_antrian')->select(DB::raw('RIGHT(no_antrian,3) as kode'))->where('tanggal', '=', $tanggal)->orderBy('id', 'desc')->take(1)->first();
$rows = DB::table('data_antrian')->where('tanggal', '=', $tanggal)->count();
if ($rows > 0) {
$kode = $result->kode + 1;
} else {
$kode = '001';
}
In the first query instead of get(), i only get a single result which you can since you only take(1). Using result instead of data and using it as an object since it is an object.

Related

Get object value from array in cache laravel

I have an array in Redis cache like that
127.0.0.1:6379> MGET laravel:campaign1107
1) "a:1:{s:21:\"unsubscriberCount1107\";i:2;}"
127.0.0.1:6379>
Now I need to get unsubscriber1107 value. I tried to this way
dd(cache()->get($arrayCacheKey[$cacheKey]));
but, it's doesn't work. How can I access this object?
My code for set cache
public function updateUnsubscriberCountCache($campaign_id, $type)
{
$assoc = [];
$arrayCacheKey = 'campaign'.$campaign_id.'';
$cacheKey = 'unsubscriberCount'.$campaign_id.'';
if($type == 'unsubscriberLogCount') {
$cacheKey = 'unsubscriberCount'.$campaign_id.'';
if( cache()->get($cacheKey) > 0) {
cache()->increment($cacheKey);
//cache()->forget($cacheKey);
} else {
$total = UnsubscribeLog::select('unsubscribe_logs.*')->leftJoin('tracking_logs', 'tracking_logs.message_id', '=', 'unsubscribe_logs.message_id')->where('tracking_logs.campaign_id', '=', $campaign_id)->distinct('subscriber_id')->count('subscriber_id');
//cache()->forever($cacheKey, $total);
$assoc[$cacheKey] = $total;
cache()->forever($arrayCacheKey, $assoc);
}
}
}
You're storing the value as an array using $arrayCacheKey but earlier in the code you're trying to access it using the $cacheKey which has a different value.
If you want to get the value of unsubscriber1107 you will need to use a combination of both keys:
$campaignData = cache()->get($arrayCacheKey); //To get the array value from the cache
$count = $campaignData ? $campaignData[$cacheKey] : null; //get the count
The above assumes that the va

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.

Undefined property: Illuminate\Database\Eloquent\Builder::$where(city_id,1)

I'm trying to make conditions on my search query, when I use this code I got this error :
my code :
$condition = null;
foreach (session()->get('filters') as $items)`
{
$condition .= "where(".$items['type'].",".$items['value'].")->";
}
$cars = Car::where('is_active','active')->$condition->get();
My error:
Undefined property: Illuminate\Database\Eloquent\Builder::$where(city_id,1)
If you want to add methods to an existing query, start your query with $query = Car::newQuery(). Then just append your methods to that variable.
$query = Car::newQuery();
$query = $query->where('is_active', 'active');
foreach (session()->get('filters') as $items) {
$query = $query->where($items['type'], $items['value']);
}
$cars = $query->get();

Call to a member function row() on a non-object

i am getting error Call to a member function row() on a non-object in codeigniter my controller is
public function edit_survey_pro($id)
{
$id = intval($id);
$survey = $this->model->get("surveys",array("ID" => $id),100000);
if (sizeof($survey) == 0) $this->template->error(lang("error_32"));
$this->template->loadContent("user/edit_survey_pro", array(
"survey" => $survey->row()
)
);
}
my model is
function get($table,$where='',$perpage=0,$start=0,$order_by='',$arr='')
{
$this->db->from($table);
if($perpage != 0 && $perpage != NULL)
$this->db->limit($perpage,$start);
if($where){
$this->db->where($where);
}
if($order_by){
$this->db->order_by($order_by);
}
if($arr=='')
$query = $this->db->get()->result();
else
$query = $this->db->get()->result('array');
if(!empty($query))
if($perpage != 0 && $perpage != NULL)
$result = $query;
else
$result = $query[0];
else
$result = array();
return $result;
}
here loadContent() is just load the content with view path
public function loadContent($view,$data=array(),$die=0){
//something to load the content
}
in my model I am getting the result as an array of object in $query and then it is returned as $result like this -
$query = $this->db->get()->result(); but at the controller $survey stores array of object and i want to show the content of that array of object ,previously I use
$this->template->loadContent("user/edit_survey_pro", array(
"survey" => $survey->row()
)
);
to get that data but the problem is $survey->row() cannot return that data bcoz it is not an object it is array of object so it can't be returned through row() method
so instead of this I just call the first element of that data like this-
$this->template->loadContent("user/edit_survey_pro", array(
"survey" => $survey[0]
)
);
Somehow its works for me bcoz I want to show the first row of the data
if sembody wants to show all data then I think he shuld try logic to increment the key value of that array of object for me it is $survey[] you can use foreach loop for increment the of value of the key element
The problems i see are your model, I will dissect it and add comments to your original code to point out the issues:
function get($table,$where='',$perpage=0,$start=0,$order_by='',$arr='')
//above there are problems, you are setting some of your parameters to
//equal blank, but below, in your conditionals, you are checking if they
// exist. They will always exist if they are set to blank. Fix them by
// setting them = NULL like this:
// get($table,$where=null,$perpage=0,$start=0,$order_by=null,$arr=null)
{
$this->db->select();// <-- you forgot this
$this->db->from($table);
if($perpage != 0 && $perpage != NULL)
//when will $perpage = null? , if never, then you dont need it.
$this->db->limit($perpage,$start);
if($where){
//change this to if(isset($where)). Also why do you use
//curly braces here, but not in the above if statement if only
//one line is affected in your if. I would remove the
//curly braces here.
$this->db->where($where);
}
if($order_by){
// change this to if(isset($order_by)). Same thing as
//above about the curly braces here
$this->db->order_by($order_by);
}
if($arr=='')
// change this to if(isset($arr)).
$query = $this->db->get()->result();
else
$query = $this->db->get()->result('array');
//change this to: $query = $this->db->get()->result_array();
if(!empty($query))
//change the above to if($query->num_rows > 0). Also, here since
//your code body is longer then one line, you will need curly braces
//around your if statement
if($perpage != 0 && $perpage != NULL)
//again, will $perpage ever be NULL? However, why do you need
//this conditional at all, if the limit above is already
//doing this job?
$result = $query;
else
$result = $query[0];
else
$result = array();
return $result;
}
after applying all the changes:
MODEL:
function get($table, $where=null, $perpage=0, $start=0, $order_by=null, $arr=null)
{
$this->db->select();
$this->db->from($table);
if($perpage != 0)
$this->db->limit($perpage, $start);
if(isset($where))
$this->db->where($where);
if(isset($order_by))
$this->db->order_by($order_by);
if(isset($arr)) {
$result = $this->db->get()->result_array();
} else {
$result = $this->db->get()->result();
}
return $result;
}
CONTROLLER
public function edit_survey_pro($id) {
$id = intval($id);
$survey = $this->model->get("surveys",array("ID" => $id),100000);
if (!$survey) {
$this->template->error(lang("error_32"));
} else {
$data["survey"] = $survey;
$this->template->loadContent("user/edit_survey_pro", $data);
}
}
I think when you use $this->db->get(), you need to pass the table name as param like this:
$this->db->get('table_name')->result();

Laravel how to get query with bindings?

I have some query that I need to pass to another query using query builder
$query = DB::table('table')->whereIn('some_field', [1,2,30])->toSql();
Model::join(DB::raw("({$query}) as table"), function($join) {
$join->on('model.id', '=', 'table.id');
})
which should results with
Select * from model join (select * from table where some_field in (1,2,30)) as table on model.id = table.id
but the bindings are not passed, which force me to do
$query = DB::table('table')->whereRaw('some_field in ('. join(',', [1,2,30]) .')')->toSql();
what can be unsafe at times. How can I get the query with bindings?
Check out the getBindings() method on the Builder class
getBindings()
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$sql = $query->toSql();
$bindings = $query->getBindings();
Laravel now offers debugging directly on your Builder!!!
https://laravel.com/docs/queries#debugging
\App\User::where('age', '18')->dump();
\App\User::where('age', '18')->dd();
Outputs
"select * from `users` where `age` = ?"
[
0 => "18"
]
public static function getQueries(Builder $builder)
{
$addSlashes = str_replace('?', "'?'", $builder->toSql());
return vsprintf(str_replace('?', '%s', $addSlashes), $builder->getBindings());
}
You can define below code block as helper function and use wherever required.
It will bind numeric as well as string value with quotations.
public static function getSqlWithBindings($query)
{
return vsprintf(str_replace('?', '%s', $query->toSql()), collect($query->getBindings())->map(function ($binding) {
return is_numeric($binding) ? $binding : "'{$binding}'";
})->toArray());
}
Example:
$query = Document::where('model', 'contact')->where('model_id', '1');
dd(Document::getSqlWithBindings($query));
Output:
"select * from `document` where `model` = 'contact' and `model_id` = 1"
Building upon Douglas.Sesar's answer.
I found I also needed to put the bindings in single quotations to be able to easily paste it into my database IDE.
$sql = $query->toSql();
$bindings = $query->getBindings();
$sql_with_bindings = preg_replace_callback('/\?/', function ($match) use ($sql, &$bindings) {
return json_encode(array_shift($bindings));
}, $sql);
$sqlQuery = Str::replaceArray(
'?',
collect($query->getBindings())
->map(function ($i) {
if (is_object($i)) {
$i = (string)$i;
}
return (is_string($i)) ? "'$i'" : $i;
})->all(),
$query->toSql());
The following function ensures the resulting SQL doesn't confuse bindings with columns by enclosing the ? to be '?'
public static function getFinalSql($query)
{
$sql_str = $query->toSql();
$bindings = $query->getBindings();
$wrapped_str = str_replace('?', "'?'", $sql_str);
return str_replace_array('?', $bindings, $wrapped_str);
}
If you want to get an executed query including bindings from the query log:
\DB::enableQueryLog();
\DB::table('table')->get();
dd(str_replace_array('?', \DB::getQueryLog()[0]['bindings'],
\DB::getQueryLog()[0]['query']));
I created this function. It is partial, might be parameters which are not covered, for me it was enough.
More than welcomed to add your improvements in a comment!
function getFullSql($query) {
$sqlStr = $query->toSql();
foreach ($query->getBindings() as $iter=>$binding) {
$type = gettype($binding);
switch ($type) {
case "integer":
case "double":
$bindingStr = "$binding";
break;
case "string":
$bindingStr = "'$binding'";
break;
case "object":
$class = get_class($binding);
switch ($class) {
case "DateTime":
$bindingStr = "'" . $binding->format('Y-m-d H:i:s') . "'";
break;
default:
throw new \Exception("Unexpected binding argument class ($class)");
}
break;
default:
throw new \Exception("Unexpected binding argument type ($type)");
}
$currentPos = strpos($sqlStr, '?');
if ($currentPos === false) {
throw new \Exception("Cannot find binding location in Sql String for bundung parameter $binding ($iter)");
}
$sqlStr = substr($sqlStr, 0, $currentPos) . $bindingStr . substr($sqlStr, $currentPos + 1);
}
$search = ["select", "distinct", "from", "where", "and", "order by", "asc", "desc", "inner join", "join"];
$replace = ["SELECT", "DISTINCT", "\n FROM", "\n WHERE", "\n AND", "\n ORDER BY", "ASC", "DESC", "\n INNER JOIN", "\n JOIN"];
$sqlStr = str_replace($search, $replace, $sqlStr);
return $sqlStr;
}
You can do something like this:
$escapedBindings = array();
foreach($query->getBindings() as $item) {$escapedBindings[] = '"'.$item.'"';}
$sql_with_bindings = Str::replaceArray('?', $escapedBindings, $query->toSql());
This is a very old question (2015), but since this is the first Google result I got I think it's worth to give my solution as well, in case it's useful for the next person.
Eloquent (5.7 onwards I think, I haven't tested more recent or earlier versions) has a method to change a Builder's from to wrap a subquery:
# Taken from Illuminate/Database/Query/Builder.php - Line 272
public function fromSub($query, $as) {
[$query, $bindings] = $this->createSub($query);
return $this->fromRaw('('.$query.') as '.$this->grammar->wrapTable($as), $bindings);
}
This however requires an already existing instance of \Illuminate\Database\Query\Builder. In order to make an empty one, you can do:
use Illuminate\Database\Capsule\Manager as DB;
$fancy = DB::table("videogames")->where("uses_sdl2", 1);
$empty = DB::table(null);
# Wrap the fancy query and set it as the "from" clause for the empty one
# NOTE: the alias is required
$empty = $empty->fromSub($fancy, "performant_games");
This will warranty that bindings are treated correctly, since they'll be handled by Eloquent itself.
Since the other answers do not properly quote the expressions, here is my approach. It uses the escaping function that belongs to the current database connection.
It replaces the question marks one by one with the corresponding binding, which is retrieved from $bindings via array_shift(), consuming the array in the process. Note, that $bindings has to be passed by reference for this to work.
function getSql($query)
{
$bindings = $query->getBindings();
return preg_replace_callback('/\?/', function ($match) use (&$bindings, $query) {
return $query->getConnection()->getPdo()->quote(array_shift($bindings));
}, $query->toSql());
}
Simple and elegant solution:
foreach (DB::getQueryLog() as $q) {
$queryStr = \Str::replaceArray('?', $q['bindings'], $q['query']);
echo $queryStr . ";\n";
}
(if you use a non-default connection, use DB::connection('yourConn')->getQueryLog() in the foreach command).
Output to the log all queries with inserted bindings sorted from the slowest query to the fastest:
\DB::enableQueryLog();
// Put here your queries
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$query2 = DB::table('table2')->where('some_field', '=', 10);
$logQueries = \DB::getQueryLog();
usort($logQueries, function($a, $b) {
return $b['time'] <=> $a['time'];
});
foreach ($logQueries as $item) {
\Log::info(str_replace_array('?', $item['bindings'], $item['query']));
\Log::info($item['time']. ' ms');
}
It is all explained here.....
https://ajcastro29.blogspot.com/2017/11/laravel-join-derived-tables-properly.html
I created a scope query for that thing. I think it can also be in macros..
public function scopeJoinDerived($query, $derivedQuery, $table, $one, $operator = null, $two = null, $type = 'inner', $where = false)
{
$query->join(DB::raw("({$derivedQuery->toSql()}) as `{$table}`"), $one, $operator, $two, $type, $where);
$join = last($query->getQuery()->joins);
$join->bindings = array_merge($derivedQuery->getBindings(), $join->bindings);
return $query;
}

Resources