Question

I have a User model which is bundled in a module installed on my Yii application. This module is third party and I do not want to alter its code.

I also have a Cv Model that has a BELONGS_TO relation with the User model.

My question is: How can I delete the cv when a user is deleted ? I know that I can achieve this with on delete cascade ... on mysql. However, i do need to delete other data such as a photo, files, etc.

What I have tried

I have created a component that is preloaded on my application. This component attaches to an onAfterDelete event

class EventListener extends CComponent 
{
    public function init() {

        Yii::import("application.modules.users.models.User");

        User::model()->attachEventHandler('onAfterDelete', array($this, 'deleteUser'));
    }


    public function deleteUser($event)
    {
        // stuff here ...
    }
}

However this does not work.

Any suggestions ?

Était-ce utile?

La solution

This may help you.

User::model() is a singleton

$user1 = User::model();
$user2 = new User; // will be used in insert action
$user3 = User::model()->findByPk(10); // will be used in update/delete action

$user1, $user2 and $user3 are completely different objects. You can attach events to objects, in this case you have to add events to all these 3 objects individually.

$user1->attachEventHandler(...);
$user2->attachEventHandler(...);
$user3->attachEventHandler(...);

look like Yii does not provide any way to add events at Class level.

Autres conseils

Well, guys, I have just stumbled upon the same problem and I solved it this way:

You should use the init() of a Model, not your event listener collection class.

In my case I have devModel class:

    public function init()
{
    parent::init(); 
    $this->onLicenseUpdated = array(new MEventProcessor, 'licenseUpdateHandler');
}

And the handler is licenseUpdateHandler($event) in a MEventProcessor class.

This way every time you work with model instance, it'll call init() for every object and attach the event handler to every instance of this Model.

Now any time the event (in my case onLicenseUpdated()) is invoked for the model - the handler will be called too.

You could also to use Behaviors.

1 - behaviors can listen to events : you just have to override their events() method

class MyBehavior extends Behavior {

public function events() {
    return [
        ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
    ];
}

public function beforeValidate($event) {
    // ...
}

}

2 - although it is more common to attach a behavior to a component in the component's behaviors() method, you can also attach them dynamically and keep the original code unmodified :

use app\components\MyBehavior;

 // attach a behavior object

 $component->attachBehavior('myBehavior1', new MyBehavior);

You will find some useful documentation here :

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top