在Yii 1.1.16 Observer Design Pattern中使用 events& behaivours (事件可以在扩展CComponents)的所有组件之间共享。我有以下模型:
- User.php (见下文)
- Work.php (见下文)
- Activity.php
醇>
我想要完成的是: 让我们说 DefaultController:
<?php
public function actionExampleWork()
{
$work = new Work();
$work->description = 'some random description';
$work->created_at = new CDbException('NOW()');
$work->user_id = 1;
//$work->attach() INVOKE EVENT that will be handled by all models which listen to this event
$work->save();
}
public function actionExampleUser()
{
$user = new User();
$user->email = 'foo@example.com';
$user->username = 'example';
$user->password = '123';
//$user->attach( something ) invoke Event that should be handled only by Activity model
$user-> save();
}
?>
实际上我已经看到了很多Yii做相关事情的例子,但到目前为止找不到适合我需要的答案却没有成功:(
user.php的
<?php class User extends CActiveRecord
{
public function tableName()
{
//@return string the associated database table name
};
public function rules()
{
//@return array validation rules for model attributes.
};
public function relations()
{
return array(
'works' => [self::HAS_MANY, 'Works', 'user_id'],
);
}
public function attributeLabels()
{
//@return array customized attribute labels (name=>label)
}
public function search()
{
//@return CActiveDataProvider the data provider that can return the models
// based on the search/filter conditions.
}
public function updateLastActivity($user_id, $activity_type){
$user = $user->model()->findByPk($user_id);//find user
$user->activity_type = $activity_type;
$user->last_action = new CDbExpression('NOW()');//update DB column
$user->save; //save user
}
} ?>
Work.php
<?php
class Work extends CActiveRecord
{
public function tableName()
{
//@return string the associated database table name
}
public function rules()
{
//@return array validation rules for model attributes.
}
public function relations()
{
return array(
'user' => [self::BELONGS_TO, 'User', 'user_id'],
);
}
public function attributeLabels()
{
//@return array customized attribute labels (name=>label)
}
public function search()
{
//@return CActiveDataProvider the data provider that can return the models
// based on the search/filter conditions.
}
?>
答案 0 :(得分:1)
您的方案不需要观察者类。
使用内置事件处理程序 Yii模型类有一些内置函数,可以在类中覆盖。
有关更多详细信息,请查看CActiveRecord的官方文档。 http://www.yiiframework.com/doc/api/1.1/CActiveRecord 提示:搜索beforeXXXX,afterXXXX,onXXXXX
例如,这是我的用户模型的预先持久化处理程序。
/**
* Runs just before the models save method is invoked. It provides a change to
* ...further prepare the data for saving. The CActiveRecord (parent class)
* ...beforeSave is called to process any raised events.
*
* @param <none> <none>
* @return boolean the decision to continue the save or not.
*
* @access public
*/
public function beforeSave() {
// /////////////////////////////////////////////////////////////////////
// Some scenarios only require certain fields to be updated. We handle
// ...this separately.
// /////////////////////////////////////////////////////////////////////
if ($this->scenario == self::SCENARIO_LOGIN)
{
/** Login scenario */
$this->last_login = new CDbExpression('NOW()');
}
if ($this->scenario == self::SCENARIO_ACTIVATION)
{
/** Account activation scenario */
if ($this->activation_status == 'activated')
{
$this->activation_code = '';
$this->status = 'active';
$this->activation_time = new CDbExpression('NOW()');
}
}
if ( ($this->scenario == self::SCENARIO_CHANGE_PASSWORD) ||
($this->scenario == self::SCENARIO_REGISTER) ||
($this->scenario == 'insert') ||
($this->scenario == 'update')
)
{
/** Password change scenario */
// /////////////////////////////////////////////////////////////////////
// Encrypt the password. Only do this if the password is set
// /////////////////////////////////////////////////////////////////////
if (isset($this->password) && (!empty($this->password)))
{
$this->password = CPasswordHelper::hashPassword($this->password);
}
}
/** All other scenarios */
// /////////////////////////////////////////////////////////////////////
// Set the create time and user for new records
// /////////////////////////////////////////////////////////////////////
if ($this->isNewRecord) {
$this->created_time = new CDbExpression('NOW()');
$this->created_by = '1'; // Special case for not logged in user
$this->modified_by = '1';
}
else
{
$this->modified_by = isset(Yii::app()->user->id)?Yii::app()->user->id:1;
}
// /////////////////////////////////////////////////////////////////////
// The modified log details is set for record creation and update
// /////////////////////////////////////////////////////////////////////
$this->modified_time = new CDbExpression('NOW()');
return parent::beforeSave();
}
请注意,在保存发生之前,我可以完全访问记录(即,在处理新记录时无法访问主键。
还要注意内置方案“插入”和“更新”。
另请注意,在退出父级中的级联事件之前,我会调用父之前的事件。
使用自定义事件
您可以创建自定义活动。
创建一个事件类,例如。保护/组件/ Newuser.php:
class NewUser extends CModelEvent{
public $userRecord;
}
然后在您的控制器中
$userModel->attachEventHandler('onNewUser',newuserEventHandler);
function newuserEventHandler($event){
// Add custom handling code here
do_some_things_here($event->new, $event->id);
}
在您的模型中,您需要举起活动
$event=new NewUserEvent;
// Add custom data to event.
$event->new=$this->isNewRecord;
$event->order=$this->id;
$this->raiseEvent('onNewUser',$event);