Passed
Push — v9 ( 467cbb...1836cb )
by Georges
03:07 queued 24s
created

EventManager::dispatch()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 4
nop 2
dl 0
loc 15
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
/**
4
 *
5
 * This file is part of Phpfastcache.
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
10
 *
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 * @author Contributors  https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
13
 */
14
15
declare(strict_types=1);
16
17
namespace Phpfastcache;
18
19
use Phpfastcache\Event\EventManagerInterface;
20
use Phpfastcache\Exceptions\PhpfastcacheEventManagerException;
21
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
22
use Phpfastcache\Helper\UninstanciableObjectTrait;
23
24
class EventManager implements EventManagerInterface
25
{
26
    use UninstanciableObjectTrait;
27
28
    public const ON_EVERY_EVENT = '__every';
29
30
    protected static EventManagerInterface $instance;
31
32
    protected array $events = [
33
        self::ON_EVERY_EVENT => []
34
    ];
35
36
    /**
37
     * @return EventManagerInterface
38
     */
39
    public static function getInstance(): EventManagerInterface
40
    {
41
        return (self::$instance ?? self::$instance = new static());
42
    }
43
44
    /**
45
     * @param EventManagerInterface $eventManagerInstance
46
     * @return void
47
     */
48
    public static function setInstance(EventManagerInterface $eventManagerInstance): void
49
    {
50
        self::$instance = $eventManagerInstance;
51
    }
52
53
54
    /**
55
     * @param string $eventName
56
     * @param array $args
57
     */
58
    public function dispatch(string $eventName, ...$args): void
59
    {
60
        /**
61
         * Replace array_key_exists by isset
62
         * due to performance issue on huge
63
         * loop dispatching operations
64
         */
65
        if (isset($this->events[$eventName]) && $eventName !== self::ON_EVERY_EVENT) {
66
            $loopArgs = array_merge($args, [$eventName]);
67
            foreach ($this->events[$eventName] as $event) {
68
                $event(...$loopArgs);
69
            }
70
        }
71
        foreach ($this->events[self::ON_EVERY_EVENT] as $event) {
72
            $event($eventName, ...$args);
73
        }
74
    }
75
76
    /**
77
     * @param string $name
78
     * @param array $arguments
79
     * @throws PhpfastcacheInvalidArgumentException
80
     * @throws PhpfastcacheEventManagerException
81
     */
82
    public function __call(string $name, array $arguments): void
83
    {
84
        if (\str_starts_with($name, 'on')) {
85
            $name = \substr($name, 2);
86
            if (\is_callable($arguments[0])) {
87
                if (isset($arguments[1]) && \is_string($arguments[0])) {
88
                    $this->events[$name][$arguments[1]] = $arguments[0];
89
                } else {
90
                    $this->events[$name][] = $arguments[0];
91
                }
92
            } else {
93
                throw new PhpfastcacheInvalidArgumentException(\sprintf('Expected Callable, got "%s"', \gettype($arguments[0])));
94
            }
95
        } else {
96
            throw new PhpfastcacheEventManagerException('An event must start with "on" such as "onCacheGetItem"');
97
        }
98
    }
99
100
    /**
101
     * @param callable $callback
102
     * @param string $callbackName
103
     */
104
    public function onEveryEvents(callable $callback, string $callbackName): void
105
    {
106
        $this->events[self::ON_EVERY_EVENT][$callbackName] = $callback;
107
    }
108
109
110
    /**
111
     * @throws PhpfastcacheEventManagerException
112
     */
113
    public function on(array $events, callable $callback): void
114
    {
115
        foreach ($events as $event) {
116
            if (!\preg_match('#^([a-zA-Z])*$#', $event)) {
117
                throw new PhpfastcacheEventManagerException(\sprintf('Invalid event name "%s"', $event));
118
            }
119
120
            $this->{'on' . \ucfirst($event)}($callback);
121
        }
122
    }
123
124
    /**
125
     * @param string $eventName
126
     * @param string $callbackName
127
     * @return bool
128
     */
129
    public function unbindEventCallback(string $eventName, string $callbackName): bool
130
    {
131
        $return = isset($this->events[$eventName][$callbackName]);
132
        unset($this->events[$eventName][$callbackName]);
133
134
        return $return;
135
    }
136
137
    /**
138
     * @return bool
139
     */
140
    public function unbindAllEventCallbacks(): bool
141
    {
142
        $this->events =  [
143
            self::ON_EVERY_EVENT => []
144
        ];
145
146
        return true;
147
    }
148
}
149