events and behaviors

I’m attaching a behavior and an event to some component like this:




    	$this->attachBehavior('mybehavior','MyBehavior');

    	$this->attachEventHandler('onBeforeRender',array($this,'beforeRender'));

    	$this->raiseEvent('onBeforeRender',new CEvent($this));



The event handler should first look in the main class and after in the attached behaviors for the event.

It doesnt

the onBeforeRender is declared in the behavior class and it is like this:




class MyBehavior extends CBehavior{

	function onBeforeRender($event){

    	return $this->raiseEvent('onBeforeRender',$event);

	}

	function beforeRender(){

    	echo '123';die;

	}

}



Am I doing everything right ?

Why are both the component and the behavior raising the same event?

I’m assuming that the component will fire the event and the bahavior will be the listener.

Component:




$this->attachBehavior('mybehavior', 'MyBehavior');

// An easy way to read the following line is: When $this guy fires the 'onBeforeRender' event, $this->myBehavior will respond with 'beforeRender'.

$this->attachEventHandler('onBeforeRender',array($this->mybehavior,'beforeRender'));

$this->onBeforeRender();

    

public function onBeforeRender()

{

    $this->raiseEvent('onBeforeRender',new CEvent($this));

}



Behavior:




class MyBehavior extends CBehavior

{

    function beforeRender($event)

    {

        echo '123';

    }

}



Note, this hasn’t been tested and I’m not sure if you can pass the behavior object ($this->myBehavior) as the event listener. Please let me know if it works, I’m curious. :rolleyes:

Cheers,

Matt

Thanks Matt

It works now, if I declare onBeforeRender in the component and attach the event to the behavior, like you said ($this->mybehavior)

But to me seens like a bug that I can’t attach an event that is declared in the behavior, since the point of the bevahior is to allow the class to have many parent classes (multiple inheritance)

What do you think ?

Cheers

PHP doesn’t support multiple inheritance (AFAIK) - and it’s a sign of bad design anyway (IMO).

You could work around this by using interfaces which does support multiple inheritance, but interfaces are not concrete.

Or you could use composition.

Or something else. :P

multiple-inheritance-in-php

Yes, thanks Jac

That is my point, Behaviors in Yii simulate multiple inheritance.

Therefore, events should look in the behaviors class for the event handler

Not quite sure what you’re after but you can attach to an event that is declared in the behavior. You can even do the attachment in the behavior. See below:

Behavior (attach in behavior):




class MyBehavior extends CBehavior

{

    public function attach(CComponent $owner)

    {

         $this->attachEventHandler('onBeforeRender',array($owner,'beforeRender'));

    }


    function doSomething($event)

    {

        $this->onBeforeRender();

    }


    public function onBeforeRender()

    {

        $this->raiseEvent('onBeforeRender',new CEvent($this));

    }

}



Component (attach in component):




$this->attachBehavior('mybehavior', 'MyBehavior');

$this->mybehavior->attachEventHandler('onBeforeRender',array($this,'beforeRender'));

$this->mybehavior->doSomething();


public function beforeRender(CEvent $event)

{

    echo '123';

}    




Code not tested.

Cheers,

Matt