Completed
Push — 4.0 ( d72a1a...2b4391 )
by Marc André
04:28 queued 02:27
created

Events::prioritySort()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
nc 3
nop 2
1
<?php
2
3
4
/**
5
 *
6
 * Copyright (c) 2010-2017 Nevraxe inc. & Marc André Audet <[email protected]>. All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without modification, are
9
 * permitted provided that the following conditions are met:
10
 *
11
 *   1. Redistributions of source code must retain the above copyright notice, this list of
12
 *       conditions and the following disclaimer.
13
 *
14
 *   2. Redistributions in binary form must reproduce the above copyright notice, this list
15
 *       of conditions and the following disclaimer in the documentation and/or other materials
16
 *       provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 * DISCLAIMED. IN NO EVENT SHALL MARC ANDRÉ "MANHIM" AUDET BE LIABLE FOR ANY
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 */
30
31
32
namespace Cervo\Libraries;
33
34
35
use Cervo\Core as _;
36
37
38
/**
39
 * Events manager for Cervo.
40
 *
41
 * @author Marc André Audet <[email protected]>
42
 */
43
final class Events
44
{
45
    /**
46
     * Holds all the events and their callbacks.
47
     * @var array
48
     */
49
    private $events = [];
50
51
    /**
52
     * Name of the event in progress, null if there are no active events.
53
     * @var string|null
54
     */
55
    private $inProgress = null;
56
57
    /**
58
     * Include all the events files that may register and/or hook to events.
59
     */
60
    public function __construct()
61
    {
62
        $config = _::getLibrary('Cervo/Config');
63
64
        foreach (glob($config->get('Cervo/Application/Directory') . '*' . \DS . $config->get('Cervo/Application/EventsPath') . '*.php', \GLOB_NOSORT | \GLOB_NOESCAPE) as $file) {
65
66
            $function = require $file;
67
68
            if (is_callable($function)) {
69
                $function($this);
70
            }
71
72
        }
73
    }
74
75
    /**
76
     * Register a new event.
77
     *
78
     * @param string $name
79
     *
80
     * @return bool
81
     */
82
    public function register(string $name) : bool
83
    {
84
        if ($this->isRegistered($name)) {
85
            return false;
86
        }
87
88
        $this->events[$name] = [];
89
90
        return true;
91
    }
92
93
    /**
94
     * Check if the event exists by it's name.
95
     *
96
     * @param string $name
97
     *
98
     * @return bool
99
     */
100
    public function isRegistered(string $name) : bool
101
    {
102
        return isset($this->events[$name]);
103
    }
104
105
    /**
106
     * Remove an event and un-hook everything related to it.
107
     *
108
     * @param string $name
109
     */
110
    public function unregister(string $name) : void
111
    {
112
        unset($this->events[$name]);
113
    }
114
115
    /**
116
     * Hook a callable to an event.
117
     * If the event is not registered, register it.
118
     *
119
     * @param string $name
120
     * @param callable $call
121
     * @param int $priority
122
     *
123
     * @return bool
124
     */
125
    public function hook(string $name, callable $call, int $priority = 0) : bool
126
    {
127
        if (!$this->isRegistered($name)) {
128
            $this->register($name);
129
        }
130
131
        $this->events[$name][] = [
132
            'call' => $call,
133
            'priority' => $priority
134
        ];
135
136
        return true;
137
    }
138
139
    /**
140
     * Fire an event and call all the hooked callables.
141
     *
142
     * @param string $name
143
     * @param array $params
144
     *
145
     * @return bool
146
     */
147
    public function fire(string $name, array $params = []) : bool
148
    {
149
        if (!is_array($params) || !$this->isRegistered($name)) {
150
            return false;
151
        }
152
153
        $this->inProgress = $name;
154
155
        usort($this->events[$name], function ($a, $b) {
156
            return $a['priority'] <=> $b['priority'];
157
        });
158
159
        foreach ($this->events[$name] as $call) {
160
            call_user_func($call['call'], $name, $params);
161
        }
162
163
        $this->inProgress = null;
164
165
        return true;
166
    }
167
168
    /**
169
     * Returns the name of the event being fired, null otherwise.
170
     *
171
     * @return string|null
172
     */
173
    public function getInProgress() : ?string
174
    {
175
        return $this->inProgress;
176
    }
177
178
    /**
179
     * Returns true if an event is being fired.
180
     *
181
     * @return bool
182
     */
183
    public function isInProgress() : bool
184
    {
185
        return $this->inProgress !== null;
186
    }
187
}
188