Passed
Push — v9 ( 51468f...3f7b65 )
by Georges
03:38
created

EventManager::unbindEventCallback()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 6
rs 10
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
declare(strict_types=1);
15
16
namespace Phpfastcache;
17
18
use BadMethodCallException;
19
use Phpfastcache\Event\EventManagerInterface;
20
use Phpfastcache\Exceptions\PhpfastcacheEventManagerException;
21
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
22
23
class EventManager implements EventManagerInterface
24
{
25
    public const ON_EVERY_EVENT = '__every';
26
27
    protected static self $instance;
28
29
    protected array $events = [
30
        self::ON_EVERY_EVENT => []
31
    ];
32
33
    /**
34
     * EventManager constructor.
35
     */
36
    final protected function __construct()
37
    {
38
        // The constructor should not be instantiated externally
39
    }
40
41
    /**
42
     * @return static
43
     */
44
    public static function getInstance(): static
45
    {
46
        return (self::$instance ?? self::$instance = new static());
47
    }
48
49
    /**
50
     * @param string $eventName
51
     * @param array $args
52
     */
53
    public function dispatch(string $eventName, ...$args): void
54
    {
55
        /**
56
         * Replace array_key_exists by isset
57
         * due to performance issue on huge
58
         * loop dispatching operations
59
         */
60
        if (isset($this->events[$eventName]) && $eventName !== self::ON_EVERY_EVENT) {
61
            $loopArgs = array_merge($args, [$eventName]);
62
            foreach ($this->events[$eventName] as $event) {
63
                $event(... $loopArgs);
64
            }
65
        }
66
        foreach ($this->events[self::ON_EVERY_EVENT] as $event) {
67
            $event($eventName, ...$args);
68
        }
69
    }
70
71
    /**
72
     * @param string $name
73
     * @param array $arguments
74
     * @throws PhpfastcacheInvalidArgumentException
75
     * @throws PhpfastcacheEventManagerException
76
     */
77
    public function __call(string $name, array $arguments): void
78
    {
79
        if (str_starts_with($name, 'on')) {
80
            $name = \substr($name, 2);
81
            if (\is_callable($arguments[0])) {
82
                if (isset($arguments[1]) && \is_string($arguments[0])) {
83
                    $this->events[$name][$arguments[1]] = $arguments[0];
84
                } else {
85
                    $this->events[$name][] = $arguments[0];
86
                }
87
            } else {
88
                throw new PhpfastcacheInvalidArgumentException(\sprintf('Expected Callable, got "%s"', \gettype($arguments[0])));
89
            }
90
        } else {
91
            throw new PhpfastcacheEventManagerException('An event must start with "on" such as "onCacheGetItem"');
92
        }
93
    }
94
95
    /**
96
     * @param callable $callback
97
     * @param string $callbackName
98
     */
99
    public function onEveryEvents(callable $callback, string $callbackName): void
100
    {
101
        $this->events[self::ON_EVERY_EVENT][$callbackName] = $callback;
102
    }
103
104
105
    /**
106
     * @throws PhpfastcacheEventManagerException
107
     */
108
    public function on(array $events, callable $callback): void
109
    {
110
        foreach ($events as $event) {
111
            if (!\preg_match('#^([a-zA-z])*$#', $event)) {
112
                throw new PhpfastcacheEventManagerException(\sprintf('Invalid event name "%s"', $event));
113
            }
114
115
            $this->{'on' . \ucfirst($event)}($callback);
116
        }
117
    }
118
119
    /**
120
     * @param string $eventName
121
     * @param string $callbackName
122
     * @return bool
123
     */
124
    public function unbindEventCallback(string $eventName, string $callbackName): bool
125
    {
126
        $return = isset($this->events[$eventName][$callbackName]);
127
        unset($this->events[$eventName][$callbackName]);
128
129
        return $return;
130
    }
131
132
    /**
133
     * @return bool
134
     */
135
    public function unbindAllEventCallbacks(): bool
136
    {
137
        $this->events =  [
138
            self::ON_EVERY_EVENT => []
139
        ];
140
141
        return true;
142
    }
143
}
144