cakephp array's and find statement - sql

I have two find statements and need the results of one find statement to use in the second find statement however the two methods I have tried to use have come back with errors
here is the first find statement, it lists the sender_id's
$sender=$this->Invoice->Find('list', array('fields'=>('sender_id')));
here is the second find statement, it takes that list of sender_id's and returns the corresponding company_name
$senderName=$this->Account->Find('all', array(
'conditions' => array(
$sender=>'account.id')));
this returns the right information however returns this error Warning (2): Illegal offset type [APP\Controller\InvoicesController.php, line 185]
so i tried doing it this way
$senderName=$this->Account->Find('all', array(
'conditions' => array(
'id'=>$sender['Invoice']['sender_id'])));
and get an undefined index on invoice.

$senderName=$this->Account->Find('all', array(
'conditions' => array(
'Account.id' => array_values($sender),
),
));
The key is the field and the value is, well, the value(s).

Related

My schedule command deletes all my records

I have a table called offers and this is how I store in my controller:
$offer = Offer::Create([
'user_id' => Auth::id(),
'property_id' => $request->property_id,
'offer_price' => $request->offer_price,
'offer_period' => $request->offer_period,
'offer_message' => $request->offer_message,
'cash_amount' => $request->cash_amount,
'buyer_type' => $request->buyer_type,
'expires_at' => now()->addMinutes($request->offer_period),
]);
I want to delete all the offers where the expires_at is older than the updated_at date. I am using the timestamps.
This is what I have in my kernel:
$schedule->call(function () {
Offer::where('updated_at', '>', 'expires_at' )->delete();
})->everyMinute();
When I ran the command:
php artisan schedule:run
I noticed that all the offers were deleted from my database.
I ran the command at 11:22, and even the rows that were meant to expire at 11:30 were deleted.
Is there anything that I possibly did wrong?
Instead of:
Offer::where('updated_at', '>', 'expires_at' )->delete();
you should use:
Offer::whereColumn('updated_at', '>', 'expires_at' )->delete();
Initially you used simple where. Laravel doesn't know that expires_at is here column name so where would be something like this:
SELECT * FROM offers where updated_at > 'expires_at'
And using second method Laravel will generate:
SELECT * FROM offers where updated_at > expires_at
without quotes (ant this is what you need here).
Instead of second method you can also use DB::raw construction like this:
Offer::where('updated_at', '>', \DB::raw('expires_at'))->delete();

How to get last executed query Yii

How to get Last executed query after model save, update, delete in yii.
i.e:
$model->save();
like $this->db->last_query(); in CI
Thanks
Put this on your config.php file , you can see other details along with your query ...
'db'=>array(
'enableProfiling'=>true,
'enableParamLogging' => true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
…
array(
'class'=>'CProfileLogRoute',
'levels'=>'profile',
'enabled'=>true,
),
),
),
The simplest way to show last executed query is to make an sql error in that query! :p Give an invalid column name in query, then Yii error reporting will show that query as error, but you can see that query.

Yii dropDownList nested conditions (not nested dropDown)

in a dropdown I would like to find data in 2 levels. Maybe my logic is wrong, but as I remember I have done such things before, the only difference was that I got always 1 simple result back, but now, I should handle an array. Here's my code:
echo $form->dropDownList($model, 'szeriaGyartmanyId', GxHtml::listDataEx(
SzeriaGyartmany::model()->findAllAttributes(
null, true, 'rajz_osszetett_technologia_id IN (:rajz_osszetett_technologia_id) AND keszDb<db', array(
':rajz_osszetett_technologia_id' => RajzOsszetettTechnologia::model()->findAllAttributes(
null, true, 'osszetett_technologia_id = :osszetett_technologia_id', array(
':osszetett_technologia_id' => OsszetettTechnologia::model()->find("name='Horganyzás alatt'")->id
)
)->id
)
)
), array('style' => 'width: auto', 'prompt' => ''));
the core gives back one single ID, it's no problem, but the second level gives back an array (or array of objects? I'm not sure). The point is, is it possible here somehow to implode resulting rajz_osszetett_technologia_ids, or do I have to do completely differently? I've tried to implode it right in place, but I got an error: Argument must be an array. So that's why I guess the result is an array of objects.
Is it clear what I would like to achieve? For me it seems kinda obvious to do it somehow like this, but maybe my logic is completely wrong. Can somebody please point me to the right direction?
Thanks a lot!
BR
c
GxActiveRecord::findAllAttributes(null,true..) returns an array of objects with only the required properties set. In order to obtain an array of ids as required you need to wrap it in GxHtml::listDataEx() and then use array_keys to obtain only the keys.
echo $form->dropDownList($model, 'szeriaGyartmanyId', GxHtml::listDataEx(
....
':rajz_osszetett_technologia_id' => implode(',',
array_keys(
GxHtml::listDataEx(
RajzOsszetettTechnologia::model()->findAllAttributes(
....
)
)
)
)
....
)
Perhaps a custom query would be easier and clearer than this.

How show all queries to database in yii framework

In CodeIgniter I would do:
print_r ($this->db->queries);
In Yii I tried:
print_r (Yii::app()->db)
But this doesn't show any queries.
UPDATE:
I understand my problem: when I want to show db queries on a POST action, I don't show it. When using GET, it's ok.
As #bool.dev said, you can use CWebLogRoute or in my case i use CFileLogRoute to store these queries in file.
array (
'class' => 'CFileLogRoute',
'categories' => 'system.db.*',
'logFile' => 'sql.log',
),
To complement #snippLeaf-com's answer, you can trace this file filtering by the keywords you want like this:
// filter by "INSERT" or "UPDATE"
$ tail -f /path_to/protected/runtime/sql.log |grep 'INSERT\|UPDATE'
// filter (case insensitive) by "SELECT" in table "x2_users"
$ tail -f /path_to/protected/runtime/sql.log |grep -i SELECT.*x2_users
OBS: to get fresh data you could need refresh database cache:
rm -f protected/runtime/cache/*.bin
If you really want every query log in yii use yii db profiler extension.
Step1. Download extension from --> link
Step2. Unpack to protected/extensions/
Step3. Rename folder name yii-db-profiler-master to db_profiler
Step4. Update the following to your protected/config/main.php:
<?php
return array(
// …
'components' => array(
// …
'db' => array(
// …
'enableProfiling'=>true,
'enableParamLogging' => true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
// …
array(
'class'=>'ext.db_profiler.DbProfileLogRoute',
'countLimit' => 1, // How many times the same query should be executed to be considered inefficient
'slowQueryMin' => 0.01, // Minimum time for the query to be slow
),
),
),
),
);

Need listbox with multiple selection - in yii

I need listbox of multiple selection in yii, i have code of form area
but its saving to database as a word "Array" in field, How to handle
this problem?
how to get back while view and update and grid view also
<?php echo $form->dropDownList($model,'clients',
CHtml::listData(client::model()->findAll(array('order'=>'id')), 'id', 'name'),
array('empty'=>'','multiple'=>'multiple','style'=>'width:400px;','size'=>'10'));
?>
Thank you.
For me works this:
'multiple'=>true
Your code must be something like that:
<?php echo $form->dropDownList($model,'clients',
CHtml::listData(client::model()->findAll(array('order'=>'id')), 'id', 'name'),
array('empty'=>'','multiple'=>true ,'style'=>'width:400px;','size'=>'10'));
?>
$htmlOptions = array('size' => '5', 'multiple' => 'true','style'=>'width: 333px');
$model->field_id = array_of_data_to_be_selected
$form->listBox($model,'field_id',$listData, $htmlOptions);
If it is a relation you may want to use this : http://yiiext.github.com/activerecord-relation-behavior/ which takes care of saving array into many to many relation junction table.
Otherwise, like Orlymee said, you need to save each item of the array by looping through it or you can serialize the array or implode it into comma separated values and do the reverse of whatever method you chose to save, while viewing.
keep this code in controller
$arr = implode(",",$model->attributes['hobbies']);
$model->hobbies=$arr;
in controler create,update in the first if condition
in database you can see the values with comma as delimiter
How does this work in CHtml::listBox()
if(!empty($htmlOptions['multiple']))
{
if(substr($name,-2)!=='[]')
$name.='[]';
}
So you can try this
<?php echo $form->dropDownList($model,'clients',
CHtml::listData(client::model()->findAll(array('order'=>'id')), 'id', 'name'),
array(
>>> 'name'=>CHtml::resolveName($model, 'clients').'[]',
'empty'=>'',
'multiple'=>'multiple',
'style'=>'width:400px;',
'size'=>'10',
)
);?>
But it's better to use CHtml::listBox()