php - Observer design pattern in Yii 1.1.16, attaching event handlers and rising events -


in yii 1.1.16 observer design pattern implemented using events & behaivours (events can shared between components extends ccomponents). have following models:

  1. user.php (see below)
  2. work.php (see below)
  3. activity.php

what want accomplish following: lets in 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 handled models listen event      $work->save();  }  public function actionexampleuser()  {     $user = new user();     $user->email = 'foo@example.com';     $user->username = 'example';     $user->password = '123';      //$user->attach( ) invoke event should handled activity model      $user-> save();  }  ?> 

actually have saw lot of examples yii doing related things, far no success on finding answer fit's needs :(

  • is possible in yii?
  • how can implement this?
  • **is there alternatives (except manually handling method calls in controller actions)? **

user.php

<?php class user extends cactiverecord { public function tablename() {     //@return string associated database table name };  public function rules() {     //@return array validation rules 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 data provider can return models     // based on 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 associated database table name }  public function rules() {     //@return array validation rules 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 data provider can return models     // based on search/filter conditions. }   ?> 

you don't need observer class scenario.

using built in event handlers yii model class has few built in functions can overwrite in class.

have @ official documentation cactiverecord more detaiils. http://www.yiiframework.com/doc/api/1.1/cactiverecord hint: search beforexxxx, afterxxxx, onxxxxx

as example, here pre-persist handler user model.

    /**  * runs before models save method invoked. provides change  * ...further prepare data saving. cactiverecord (parent class)  * ...beforesave called process raised events.  *  * @param <none> <none>  * @return boolean decision continue save or not.  *  * @access public  */  public function beforesave() {     // /////////////////////////////////////////////////////////////////////     // scenarios require fields updated. 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 password. if password set     // /////////////////////////////////////////////////////////////////////     if (isset($this->password) && (!empty($this->password)))     {         $this->password    =  cpasswordhelper::hashpassword($this->password);      } }   /** other scenarios */  // ///////////////////////////////////////////////////////////////////// // set create time , user new records // ///////////////////////////////////////////////////////////////////// if ($this->isnewrecord) {     $this->created_time = new cdbexpression('now()');     $this->created_by   = '1';  // special case not logged in user     $this->modified_by  = '1'; } else {     $this->modified_by   = isset(yii::app()->user->id)?yii::app()->user->id:1; }  // ///////////////////////////////////////////////////////////////////// // modified log details set record creation , update // ///////////////////////////////////////////////////////////////////// $this->modified_time = new cdbexpression('now()');  return parent::beforesave(); } 

notice have full access record before save happens (ie. no access primary-key when new record being processed.

look out built in scenarios 'insert' , 'update'.

note invoke parent beforesave before exiting cascade events in parents.

using custom events

you can create custom events.

create event class eg. protected/components/newuser.php:

class newuser extends cmodelevent{     public $userrecord; } 

then in controller

$usermodel->attacheventhandler('onnewuser',newusereventhandler);  function newusereventhandler($event){       // add custom handling code here        do_some_things_here($event->new, $event->id);     } 

in model, need raise event

$event=new newuserevent; // add custom data event. $event->new=$this->isnewrecord; $event->order=$this->id; $this->raiseevent('onnewuser',$event); 

Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

node.js - How to abort query on demand using Neo4j drivers -