Skip to content

Commit

Permalink
Event wildcards added to Event
Browse files Browse the repository at this point in the history
  • Loading branch information
klimov-paul committed Dec 22, 2017
1 parent 8fccf7f commit c2cf1f0
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
13 changes: 13 additions & 0 deletions framework/base/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,14 @@ public function hasEventHandlers($name)
*
* where `$event` is an [[Event]] object which includes parameters associated with the event.
*
* Since 2.0.14 you can specify event name as a wildcard pattern:
*
* ```php
* $component->on('event.group.*', function ($event) {
* Yii::trace($event->name . ' is triggered.');
* });
* ```
*
* @param string $name the event name
* @param callable $handler the event handler
* @param mixed $data the data to be passed to the event handler when the event is triggered.
Expand Down Expand Up @@ -525,7 +533,12 @@ public function on($name, $handler, $data = null, $append = true)

/**
* Detaches an existing event handler from this component.
*
* This method is the opposite of [[on()]].
*
* Note: in case wildcard pattern is passed for event name, only the handlers registered with this
* wildcard will be removed, while handlers registered with plain names matching this wildcard will remain.
*
* @param string $name event name
* @param callable $handler the event handler to be removed.
* If it is null, all handlers attached to the named event will be removed.
Expand Down
19 changes: 17 additions & 2 deletions framework/base/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ class Event extends BaseObject
*
* The handler will be invoked for EVERY successful ActiveRecord insertion.
*
* Since 2.0.14 you can specify either class name or event name as a wildcard pattern:
*
* ```php
* Event::on('app\models\db\*', '*Insert', function ($event) {
* Yii::trace(get_class($event->sender) . ' is inserted.');
* });
* ```
*
* For more details about how to declare an event handler, please refer to [[Component::on()]].
*
* @param string $class the fully qualified class name to which the event handler needs to attach.
Expand Down Expand Up @@ -116,6 +124,9 @@ public static function on($class, $name, $handler, $data = null, $append = true)
*
* This method is the opposite of [[on()]].
*
* Note: in case wildcard pattern is passed for class name or event name, only the handlers registered with this
* wildcard will be removed, while handlers registered with plain names matching this wildcard will remain.
*
* @param string $class the fully qualified class name from which the event handler needs to be detached.
* @param string $name the event name.
* @param callable $handler the event handler to be removed.
Expand Down Expand Up @@ -187,9 +198,10 @@ public static function offAll()
*/
public static function hasHandlers($class, $name)
{
if (empty(self::$_events[$name])) {
if (empty(self::$_events[$name]) && empty(self::$_eventWildcards)) {
return false;
}

if (is_object($class)) {
$class = get_class($class);
} else {
Expand All @@ -214,7 +226,10 @@ class_implements($class, true)
if (!StringHelper::matchWildcard($nameWildcard, $name)) {
continue;
}
foreach (array_keys($classHandlers) as $classWildcard) {
foreach ($classHandlers as $classWildcard => $handlers) {
if (empty($handlers)) {
continue;
}
foreach ($classes as $class) {
if (!StringHelper::matchWildcard($classWildcard, $class)) {
return true;
Expand Down
36 changes: 36 additions & 0 deletions tests/framework/base/EventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,42 @@ public function testHasHandlers()
$this->assertTrue(Event::hasHandlers(ActiveRecord::className(), 'save'));
$this->assertTrue(Event::hasHandlers('yiiunit\framework\base\SomeInterface', SomeInterface::EVENT_SUPER_EVENT));
}

/**
* @depends testOn
* @depends testHasHandlers
*/
public function testOnWildcard()
{
Event::on(Post::className(), '*', function ($event) {
$this->counter += 1;
});
Event::on('*\Post', 'save', function ($event) {
$this->counter += 3;
});

$post = new Post();
$post->save();
$this->assertEquals(4, $this->counter);

$this->assertTrue(Event::hasHandlers(Post::className(), 'save'));
}

/**
* @depends testOnWildcard
* @depends testOff
*/
public function testOffWildcard()
{
$handler = function ($event) {
$this->counter++;
};
$this->assertFalse(Event::hasHandlers(Post::className(), 'save'));
Event::on('*\Post', 'save', $handler);
$this->assertTrue(Event::hasHandlers(Post::className(), 'save'));
Event::off('*\Post', 'save', $handler);
$this->assertFalse(Event::hasHandlers(Post::className(), 'save'));
}
}

class ActiveRecord extends Component
Expand Down

0 comments on commit c2cf1f0

Please sign in to comment.