Skip to content

Conversation

@egorpromo
Copy link
Contributor

Is it possible to introlduce in Yii2 not simple Events only but Filters?

The defference is that the Event does things only, but Filter can be used for modification of variables. So we do something like:

$myEvent = new myEvent;
$myEvent->var=$variable; //we have $var and want modify it
$event = $this->trigger('myfilter', $myEvent);
//Now we have modified $event and modified $event->var inside 
$variable = $event->var; 

So it is possible to modify variables using Events system. It is like wordpress filters.

Filters can be used in core Yii2. Suppose we have Response component and want modify it in yii\web\Application::handleRequest() method
Instead simple return $response; we can do something like:

$event = $this->trigger('responseModification', $response);
return $event->data; //In $event->data we have new $responce which have been modified in Event

@qiangxue
Copy link
Member

It is already so. The $event parameter is passed along all event handlers. You can modify its member variables.

@qiangxue qiangxue closed this Nov 17, 2013
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.39%) when pulling a3b148a on egorpromo:events-enhancement into c7ff329 on yiisoft:master.

@egorpromo
Copy link
Contributor Author

Yes, but $event is not returned in client code.

@qiangxue
Copy link
Member

Since you pass in $event, why would you want it to be returned back?
Also note that if you don't pass in $event, there may not be $event object created if there's no handler attached to the event.

@egorpromo
Copy link
Contributor Author

My way helps not only execute any function, but modify some variables also. I don't know that it is needed for core Yii functionality or not, but it give a great flexibility.
For example in yii\web\Application::handleRequest() we can let the callback functions to modify $result variable which is passed in Response component. In wordpress "filters" are used like that:

add_filter( 'myfilter', $callbackFunctionForMyfilter);

And in core:

$oldResult=$result;
$result = apply_filters('myfilter', $oldResult);
//Now we have new $result variable that have been modified via 'myfilter'.
//It is convenient because anyone can modify $result for his own needs

@qiangxue
Copy link
Member

For an example how the current implementation works, see https://github.com/yiisoft/yii2/blob/master/framework/yii/base/Model.php#L321
where isValid may be modified by event handlers.

The main change in your PR is that $event may be replaced by the return result of some event handler. However, this is not much different from modifying the internal members of the existing $event.

@egorpromo
Copy link
Contributor Author

I don't understand.

$this->on('myevent', 'myfunction');
/* .... */
$myEvent=newEvent;
$myEvent->myvar=$myvar;
$this->trigger('myevent', $myEvent);

/* We can't do anything with $myvar via Event System. I think it will be convenient to have ability to modify it */
function myfunction($event)
{
    /* We do anything here with $event */
    return $event; //But the returned $event will vanish. We can't modify any variable here and return it in the client code
}

@cebe
Copy link
Member

cebe commented Nov 17, 2013

function myfunction($event)
{
    /* We do anything here with $event */
    $event->myvar = 42;
}

$this->on('myevent', 'myfunction');
/* .... */
$myEvent=new MyEvent;
$myEvent->myvar=21;
$this->trigger('myevent', $myEvent);

echo $myEvent->myvar; // will be 42

Objects are always given by reference in php.

@egorpromo
Copy link
Contributor Author

I dont' want annoy yii-developers but do you suppose that more useful for users will be a bit another code in https://github.com/yiisoft/yii2/blob/master/framework/yii/base/Model.php#L321?

        public function beforeValidate()
        {
                $event = new ModelEvent;
                $event->model = $this; //Users will have access to object in callback
                $this->trigger(self::EVENT_BEFORE_VALIDATE, $event);
                return $event->isValid;
        }

And in ModelEvent class there will be ModelEvent::model variable.

@qiangxue
Copy link
Member

Event::sender is what you want.

@egorpromo
Copy link
Contributor Author

Thanks for answers. It explains more things. The events work fine in Yii2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants