[SOLVED]afterSave() / afterDelete() won't get called.

I have a method in my model(ContestCategory.php), called saveContestCategory(), which saves data for several related models

It looks like:




public function saveContestCategory($postData=array(),$modelInstances=array())

    {

        $result=array();

        $connection=Yii::app()->db;

        $transaction=$connection->beginTransaction();

        try

        {

            extract($modelInstances);

            $model->attributes=$postData['ContestCategory'];

            $model_save=$model->save();

            $detail->attributes=$postData['ContestCategoryDetail'];

            $detail->category_id=$model->category_id;

            $detail_save=$detail->save();

            

            if($model_save===false||$detail_save===false)

            {

                $transaction->rollBack();

                $message=Yii::t('app','The form submission failed with the message:<br /> %s.');

                $errors=implode('<br />',Common::parseModelError($model->getErrors(),$detail->getErrors()));

                return array('result'=>'error', 'msg'=>sprintf($message,$errors));

            }

            $transaction->commit();

            $message=Yii::t('app','The form was successfully processed.');

            return array('result'=>'success', 'msg'=>$message);

        }

        catch(Exception $e)

        {

            $transaction->rollBack();

            $message=Yii::t('app','The form submission failed with the message:<br /> %s.');

            return array('result'=>'error', 'msg'=>sprintf($message,$e));

        }

    }



Further, i have some events in same model file:




protected function afterSave()

    {

        if(parent::afterSave())

        {

            Yii::app()->cache->delete(md5('frontend-categories-list'));

            Yii::app()->cache->delete('adminCategoriesSelectBox'.$model->category_id);

            Yii::app()->cache->delete('adminCategoriesList'.$model->category_id);

        }

        return true;

    }


protected function afterDelete()

    {

        if(parent::afterDelete())

        {

            Yii::app()->cache->delete(md5('frontend-categories-list'));

            Yii::app()->cache->delete('adminCategoriesSelectBox'.$model->category_id);

            Yii::app()->cache->delete('adminCategoriesList'.$model->category_id);

        }

        return true;

    }



The thing is these those two events are never called, i mean i have an beforeSave() event that works perfectly, but for these two, it doesn’t seem to be working.

Any thoughts ?

Have you tried using a behavior?

doodle

Thanks for the answer, but there’s no need for using abehavior.

The thing is that the "before" events needs to be checked against the parent method, so a

beforeSave() event needs to be like:




protected function beforeSave()

{

   if(parent::beforeSave())

   {

    // do something 

   }

}



Whereas, the “after” events needs to be directly executed as they don’t expect a result from the parent method

so a afterDelete() event needs to be like




protected function afterDelete()

{

   parent::afterDelete();

   //do something .

}



Hope it helps somebody else :)

Did you ever try a behavior?

Because I’ve never had to reference the parent using a behavior, but thanks for the tip, :) maybe if I understood your application I would know why a behavior wouldn’t be preferred.

doodle

I don’t believe that is the case to create a behavior class and load it when i can just call a parent function of the same loaded model.

I believe it is faster this way and under these circumstances.

On the other hand, i don’t fully understand the behaviors right now, so if you care to explain me a bit would be great.

Take a look at CTimeStampBehavior

It’s an excellent example. Look at the code in the framework files.

doodle

Okay, thanks for pointing it out.

I just took a look and as far as i saw, the behavior needs to have methods that are called by events, therefore, for using a behavior there needs to be an event attached of the component. I might be wrong at this point, but i’ll look deeper into these.

I found here a great explanation: http://www.yiiframework.com/forum/index.php?/topic/3941-component-event-and-component-behavior/

@twisted, I’m pretty new to behaviors too so thanks for the links, I’ve seen a few of them before but maybe I should review. I thought I would share a simple example behavior with you.

This behavior send an email to an administrator when a comment is made to a blog entry.

In the comments model we define the behavior(s).


        public function behaviors()

	{

	    return array(

	        	'CTimestampBehavior' => array(

			'class' => 'zii.behaviors.CTimestampBehavior',

			'createAttribute' => 'create_time',

			'updateAttribute' => null,

		),

                        'CommentsBehavior'=>array(

                            'class'=>'CommentsBehavior',

			),

	    );

	}



The timestamp behavior handles timestamping the comment and my own home rolled CommentsBehavior emails the admin.


    public function afterSave($event)

    {

          // this is the record being saved.

        if ($this->getOwner()->getIsNewRecord())

        {

          $this->MailAdmin();

        }


    }


    function MailAdmin ()

    {

                            

        $model = $this->getOwner();

        $post = Post::model()->findByPk($model->post_id);


                                $message = '<p><b>'.$post->title.'</b></p>';

                                $message .= $post->content.'<br />';

                                $message .= '<p><b>Comment:</b>'.$model->content;

                                $message .= '<br /><a href="http://www.tatacentre.ca/admin/index.php?r=post/view&id='.$post->id.'">Click here to view the blog entry</a>';


                                $mailer = Yii::createComponent('application.extensions.mailer.EMailer');

                    /* other stuff removed for clarity */

                                $mailer->MsgHTML($message);

                                $mailer->Send();


        return;


    }


    }

Notice that email is only sent when the record is created, when the admin logs in and approves the comment no further action occurs. This is a down and dirty example of a behavior and it is quite specific to the model, ideally behaviors can be re-used on various models, like the timestamp example.

I still need to better understand events :blink:

In this case, I did not raise an event, the event was the record being saved.

doodle

Thanks for sharing the code, i got the idea about behaviors now.

Regarding events/event handler, i found a topic on stackoverflow: http://stackoverflow.com/questions/3051609/how-to-raise-ccomponent-event-in-yii

It gives you an idea on how an event should be created in order to be attached .

Anyway, these two topics(event&behavior) are very little explained and i believe there needs to be clear example on how these should be used.

Searching google will return a single relevant article from the Yii wiki, but that article is not explained in detail, after reading it, you have more questions than before doing it, so it seems that for now, everyone is on his own when learning events/behaviors.