Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
EventDispatcher
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
4 / 4
15
100.00% covered (success)
100.00%
1 / 1
 listen
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 forget
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fire
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 dispatch
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
11
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Events;
6
7use Illuminate\Support\Arr;
8use Illuminate\Support\Str;
9
10class EventDispatcher
11{
12    /** @var callable[] */
13    protected array $listeners;
14
15    public function listen(array|string $events, callable|string $listener): void
16    {
17        foreach ((array) $events as $event) {
18            $this->listeners[$event][] = $listener;
19        }
20    }
21
22    public function forget(string $event): void
23    {
24        unset($this->listeners[$event]);
25    }
26
27    public function fire(string|object $event, mixed $payload = [], bool $halt = false): mixed
28    {
29        return $this->dispatch($event, $payload, $halt);
30    }
31
32    /**
33     * @param bool          $halt     Stop on first non-null return
34     */
35    public function dispatch(string|object $event, mixed $payload = [], bool $halt = false): mixed
36    {
37        if (is_object($event)) {
38            $payload = $event;
39            $event = get_class($event);
40        }
41
42        $listeners = [];
43        if (isset($this->listeners[$event])) {
44            $listeners = $this->listeners[$event];
45        }
46
47        $responses = [];
48        foreach ($listeners as $listener) {
49            if (!is_callable($listener) && is_string($listener) && !Str::contains($listener, '@')) {
50                $listener = $listener . '@handle';
51            }
52
53            $response = app()->call($listener, ['event' => $event] + Arr::wrap($payload));
54
55            // Return the events response
56            if ($halt && !is_null($response)) {
57                return $response;
58            }
59
60            // Stop further event propagation
61            if ($response === false) {
62                break;
63            }
64
65            $responses[] = $response;
66        }
67
68        return $halt ? null : $responses;
69    }
70}