Using a trait

The EventHandlerTrait is very easy way to add event handling to any class. It has some nice advantages:

  • The events are isolated within the class. This means you don't have to specify the target class.
  • The callbacks have access to the calling class via $this. See example below.

Basic example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

namespace Project;

use Psr\Log\LoggerInterface;

class Foo
{
    use Vespula\Event\EventHandlerTrait;

    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->registerEvents();
    }

    protected function registerEvents()
    {
        // We can access $this->logger in the callback
        $this->on('update', function ($id) {
            $this->logger->info('Item ' . $id . ' was updated');
        });
    }

    public function update($id)
    {
        // update record logic...

        $this->trigger('update', $id);
    }
}

Callback priority

Just like the full EventHandler, you can set a callback's priority. Callbacks with the same priority are triggered First In, First Out (FIFO).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

class Foo
{
    use Vespula\Event\EventHandlerTrait;

    public function bar()
    {
        $this->on('save', function () {
            // do this first! (priority 10)
        }, 10);

        $this->on('save', function () {
            // do this after (priority 5)
        }, 5);
    }

    public function save()
    {
        // save logic
        $this->trigger('save');
    }
}

Stopping propagation

As with the EventHandler, you can stop propagation within the callback. The Event object will always be passed to your callback as the last argument.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

class Foo
{
    use Vespula\Event\EventHandlerTrait;

    public function bar()
    {
        $this->on('save', function ($event) {
            echo "I was triggered";

            if ($some_condition) {
                $event->stopPropagation();
            }
        });

        // If the callback above stops propagation, this one won't fire.
        $this->on('save', function () {
            // This was defined after the first callback.
        });
    }
}

Removing events

Events or their callbacks can be removed from the queue. You can remove all callbacks for a given event, or just a given callback. To remove a callback, it must be defined as a variable first.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
// Remove all callbacks for give event
$this->on('my-event', function () {});
$this->remove('my-event');

// Remove one event
$callback = function () {
    // do stuff
};

$this->on('my-event', $callback);

$this->remove('my-event', $callback);

You cannot remove a callback like the following. The two callbacks are unique.

1
2
3
4
5
6
7
8
9
<?php

$this->on('my-event', function () {
    echo "foo";
});

$this->remove('my-event', function () {
    echo "foo";
});