I'm wondering if there's a way to add created_by
and modified_by
similar to how created
and modified
work in CakePHP?
I like the fact that cake recognizes those fields and takes care of them automatically, regardless of the model, without me having to implement them at all. I would like to add a similar feature using the current user id (in my application, there is always a userid, even if it sometimes may be 0).
I assume the starting place is before_save()
in app_model?
--
Also, is there any way for me to get cake to recognize this as a foreign key to the user table automatically (similar to how it recognizes user_id
), or will I have to add the has/belongs to relationship manually? I ask because this will go on most of my models, so I'd prefer to reduce redundant code.
Thank you!
For the first part of your question, I use this Behavior code to do exactly what you are looking for:
class UserLinkBehavior extends ModelBehavior
{
/**
* The string to use to retrieve the user id from CakeSession
*
* @var string
*/
var $user_id_key = 'Auth.User.id';
function setup(&$model, $settings)
{
if(isset($settings['user_id_key']))
{
$this->user_id_key = $settings['user_id_key'];
}
}
function beforeSave(&$model)
{
App::uses('CakeSession', 'Model/Datasource');
$logged_user_id = CakeSession::read($this->user_id_key);
if(isset($logged_user_id))
{
$this->set_user_on_current_model($model, $logged_user_id);
}
return true;
}
/**
* Set the created_by and modified_by user id on the current model
*
* @param Model $model
* @param int $logged_user_id
* @return void
*/
private function set_user_on_current_model(&$model, $logged_user_id)
{
if(isset($logged_user_id))
{
/*
* Id is not set -> it is a creation
*/
if($model->hasField('created_by') && (!isset($model->data[$model->alias]['id']) || empty($model->data[$model->alias]['id'])))
{
if(!isset($model->data[$model->alias]['created_by']))
{
$model->data[$model->alias]['created_by'] = $logged_user_id;
/*
* If the save is called with a whitelist, add 'created_by' to the whitelist
* in order to have this field saved as well
*/
if(!empty($model->whitelist) && !in_array('created_by', $model->whitelist))
{
$model->whitelist[] = 'created_by';
}
}
}
/*
* Id is set -> it is an update
*/
if($model->hasField('modified_by') && isset($model->data[$model->alias]['id']) && !empty($model->data[$model->alias]['id']))
{
$model->data[$model->alias]['modified_by'] = $logged_user_id;
/*
* If the save is called with a whitelist, add 'modified_by' to the whitelist
* in order to have this field saved as well
*/
if(!empty($model->whitelist) && !in_array('modified_by', $model->whitelist))
{
$model->whitelist[] = 'modified_by';
}
}
}
}
}
Then just declare it in your Model or your AppModel
var $actsAs = array('UserLink');
For the second part of your question, you could probably add a beforeFind() callback to the behavior and use the model->bindModel() function to link the model having the created_by
and modified_by
fields with a User model. Personaly I prefere to declare these links in each model manually when I need them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With