-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathHooks.php
More file actions
164 lines (147 loc) · 4.65 KB
/
Hooks.php
File metadata and controls
164 lines (147 loc) · 4.65 KB
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?php
/**
* Copyright (C) 2015-2019 FeatherBB
* based on code by (C) 2008-2015 FluxBB
* and Rickard Andersson (C) 2002-2008 PunBB
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
*/
namespace FeatherBB\Core;
class Hooks
{
/**
* @var array
*/
protected $hooks = [
];
/**
* Assign hook
* @param string $name The hook name
* @param mixed $callable A callable object
* @param int $priority The hook priority; 0 = high, 10 = low
*/
public function bind($name, $callable, $priority = 10)
{
if (!isset($this->hooks[$name])) {
$this->hooks[$name] = [[]];
}
if (is_callable($callable)) {
$this->hooks[$name][(int) $priority][] = $callable;
}
}
/**
* Invoke hook
* @param string $name The hook name
* @param mixed ... (Optional) Argument(s) for hooked functions, can specify multiple arguments
* @return mixed data
*/
public function fire($name)
{
$args = func_get_args();
array_shift($args);
if (!isset($this->hooks[$name])) {
//$this->hooks[$name] = array(array());
if (isset($args[0])) {
return $args[0];
} else {
return;
}
}
if (!empty($this->hooks[$name])) {
// Sort by priority, low to high, if there's more than one priority
if (count($this->hooks[$name]) > 1) {
ksort($this->hooks[$name]);
}
$output = [];
$count = 0;
foreach ($this->hooks[$name] as $priority) {
if (!empty($priority)) {
foreach ($priority as $callable) {
$output[] = call_user_func_array($callable, $args);
++$count;
}
}
}
// If we only have one hook binded or the argument is not an array,
// let's return the first output
if ($count == 1 || !is_array($args[0])) {
return $output[0];
} else {
$data = [];
// Move all the keys to the same level
array_walk_recursive($output, function ($v, $k) use (&$data) {
$data[] = $v;
});
// Remove any duplicate key
$data = array_unique($data);
return $data;
}
}
}
/**
* Invoke hook for DB
* @param string $name The hook name
* @param mixed ... Argument(s) for hooked functions, can specify multiple arguments
* @return mixed
*/
public function fireDB($name)
{
$args = func_get_args();
array_shift($args);
if (!isset($this->hooks[$name])) {
return $args[0];
}
if (!empty($this->hooks[$name])) {
// Sort by priority, low to high, if there's more than one priority
if (count($this->hooks[$name]) > 1) {
ksort($this->hooks[$name]);
}
$output = [];
foreach ($this->hooks[$name] as $priority) {
if (!empty($priority)) {
foreach ($priority as $callable) {
$output[] = call_user_func_array($callable, $args);
}
}
}
return $output[0];
}
}
/**
* Get hook listeners
*
* Return an array of registered hooks. If `$name` is a valid
* hook name, only the listeners attached to that hook are returned.
* Else, all listeners are returned as an associative array whose
* keys are hook names and whose values are arrays of listeners.
*
* @param string $name A hook name (Optional)
* @return array|null
*/
public function getHooks($name = null)
{
if (!is_null($name)) {
return isset($this->hooks[(string) $name]) ? $this->hooks[(string) $name] : null;
} else {
return $this->hooks;
}
}
/**
* Clear hook listeners
*
* Clear all listeners for all hooks. If `$name` is
* a valid hook name, only the listeners attached
* to that hook will be cleared.
*
* @param string $name A hook name (Optional)
*/
public function clearHooks($name = null)
{
if (!is_null($name) && isset($this->hooks[(string) $name])) {
$this->hooks[(string) $name] = [[]];
} else {
foreach ($this->hooks as $key => $value) {
$this->hooks[$key] = [[]];
}
}
}
}