1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* webtrees-lib: MyArtJaub library for webtrees |
4
|
|
|
* |
5
|
|
|
* @package MyArtJaub\Webtrees |
6
|
|
|
* @subpackage Hook |
7
|
|
|
* @author Jonathan Jaubart <[email protected]> |
8
|
|
|
* @copyright Copyright (c) 2011-2016, Jonathan Jaubart |
9
|
|
|
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 |
10
|
|
|
*/ |
11
|
|
|
namespace MyArtJaub\Webtrees\Hook; |
12
|
|
|
|
13
|
|
|
use Fisharebest\Webtrees\Database; |
14
|
|
|
use Fisharebest\Webtrees\Module; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Class to manage Hooks (subscription and execution). |
18
|
|
|
* Accessing list of hooks should be done through a MyArtJaub\Webtrees\Hook\HookSubscriberInterface |
19
|
|
|
*/ |
20
|
|
|
class Hook { |
21
|
|
|
|
22
|
|
|
/** @var string Function executed by the hook */ |
23
|
|
|
protected $hook_function; |
24
|
|
|
|
25
|
|
|
/** @var string Context in which the hook is executed */ |
26
|
|
|
protected $hook_context; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Constructor for Hook class |
30
|
|
|
* |
31
|
|
|
* @param string $hook_function_in Hook function to be subscribed or executed |
32
|
|
|
* @param string $hook_context_in Hook context to be subscribed or executed |
33
|
|
|
*/ |
34
|
|
|
public function __construct($hook_function_in, $hook_context_in = 'all'){ |
35
|
|
|
$this->hook_function = $hook_function_in; |
36
|
|
|
$this->hook_context = $hook_context_in; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Methods for subscribing to Hooks |
41
|
|
|
*/ |
42
|
|
|
|
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Subscribe a class implementing HookSubscriberInterface to the Hook |
46
|
|
|
* The Hook is by default enabled. |
47
|
|
|
* |
48
|
|
|
* @param string $hsubscriber Name of the subscriber module |
49
|
|
|
*/ |
50
|
|
|
public function subscribe($hsubscriber){ |
51
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
52
|
|
|
Database::prepare( |
53
|
|
|
"INSERT IGNORE INTO `##maj_hooks` (majh_hook_function, majh_hook_context, majh_module_name)". |
54
|
|
|
" VALUES (?, ?, ?)" |
55
|
|
|
)->execute(array($this->hook_function, $this->hook_context, $hsubscriber)); |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Define the priority for execution of the Hook for the specific HookSubscriberInterface |
61
|
|
|
* |
62
|
|
|
* @param string $hsubscriber Name of the subscriber module |
63
|
|
|
* @param int $priority Priority of execution |
64
|
|
|
*/ |
65
|
|
View Code Duplication |
public function setPriority($hsubscriber, $priority){ |
|
|
|
|
66
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
67
|
|
|
Database::prepare( |
68
|
|
|
"UPDATE `##maj_hooks`". |
69
|
|
|
" SET majh_module_priority=?". |
70
|
|
|
" WHERE majh_hook_function=?". |
71
|
|
|
" AND majh_hook_context=?". |
72
|
|
|
" AND majh_module_name=?" |
73
|
|
|
)->execute(array($priority, $this->hook_function, $this->hook_context, $hsubscriber)); |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Enable the hook for a specific HookSubscriberInterface. |
79
|
|
|
* |
80
|
|
|
* @param string $hsubscriber Name of the subscriber module |
81
|
|
|
*/ |
82
|
|
View Code Duplication |
public function enable($hsubscriber){ |
|
|
|
|
83
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
84
|
|
|
Database::prepare( |
85
|
|
|
"UPDATE `##maj_hooks`". |
86
|
|
|
" SET majh_status='enabled'". |
87
|
|
|
" WHERE majh_hook_function=?". |
88
|
|
|
" AND majh_hook_context=?". |
89
|
|
|
" AND majh_module_name=?" |
90
|
|
|
)->execute(array($this->hook_function, $this->hook_context, $hsubscriber)); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Disable the hook for a specific HookSubscriberInterface. |
96
|
|
|
* |
97
|
|
|
* @param string $hsubscriber Name of the subscriber module |
98
|
|
|
*/ |
99
|
|
View Code Duplication |
public function disable($hsubscriber){ |
|
|
|
|
100
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
101
|
|
|
Database::prepare( |
102
|
|
|
"UPDATE `##maj_hooks`". |
103
|
|
|
" SET majh_status='disabled'". |
104
|
|
|
" WHERE majh_hook_function=?". |
105
|
|
|
" AND majh_hook_context=?". |
106
|
|
|
" AND majh_module_name=?" |
107
|
|
|
)->execute(array($this->hook_function, $this->hook_context, $hsubscriber)); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Remove the hook for a specific HookSubscriberInterface. |
113
|
|
|
* |
114
|
|
|
* @param string $hsubscriber Name of the subscriber module |
115
|
|
|
*/ |
116
|
|
View Code Duplication |
public function remove($hsubscriber){ |
|
|
|
|
117
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
118
|
|
|
Database::prepare( |
119
|
|
|
"DELETE FROM `##maj_hooks`". |
120
|
|
|
" WHERE majh_hook_function=?". |
121
|
|
|
" AND majh_hook_context=?". |
122
|
|
|
" AND majh_module_name=?" |
123
|
|
|
)->execute(array($this->hook_function, $this->hook_context, $hsubscriber)); |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Methods for execution of the Hook |
130
|
|
|
* |
131
|
|
|
*/ |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Return the resuls of the execution of the hook function for a defined list of modules, only for those enabled. |
135
|
|
|
* |
136
|
|
|
* @param string[] $module_names List of Modules to execute |
137
|
|
|
* @return array Results of the hook executions |
138
|
|
|
*/ |
139
|
|
|
public function executeOnlyFor(array $module_names) { |
140
|
|
|
$result = array(); |
141
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
142
|
|
|
$params = func_get_args(); |
143
|
|
|
array_shift($params); |
144
|
|
|
foreach ($module_names as $module_name) { |
145
|
|
|
if($module = Module::getModuleByName($module_name)) { |
146
|
|
|
$result[] = call_user_func_array(array($module, $this->hook_function), $params); |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
return $result; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Return the results of the execution of the hook function for all subscribed and enabled modules, in the order defined by their priority. |
155
|
|
|
* Parameters can be passed if the hook requires them. |
156
|
|
|
* |
157
|
|
|
* @return array Results of the hook executions |
158
|
|
|
*/ |
159
|
|
|
public function execute(){ |
160
|
|
|
$result = array(); |
161
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
162
|
|
|
$params = func_get_args(); |
163
|
|
|
$sqlquery = ''; |
164
|
|
|
$sqlparams = array($this->hook_function); |
165
|
|
View Code Duplication |
if($this->hook_context != 'all') { |
|
|
|
|
166
|
|
|
$sqlparams = array($this->hook_function, $this->hook_context); |
167
|
|
|
$sqlquery = " OR majh_hook_context=?"; |
168
|
|
|
} |
169
|
|
|
$module_names=Database::prepare( |
170
|
|
|
"SELECT majh_module_name AS module, majh_module_priority AS priority FROM `##maj_hooks`". |
171
|
|
|
" WHERE majh_hook_function = ? AND (majh_hook_context='all'".$sqlquery.") AND majh_status='enabled'". |
172
|
|
|
" ORDER BY majh_module_priority ASC, module ASC" |
173
|
|
|
)->execute($sqlparams)->fetchAssoc(); |
174
|
|
|
asort($module_names); |
175
|
|
|
array_unshift($params, array_keys($module_names)); |
176
|
|
|
$result = call_user_func_array(array(&$this, 'executeOnlyFor'), $params); |
177
|
|
|
} |
178
|
|
|
return $result; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Returns the number of active modules linked to a hook |
183
|
|
|
* |
184
|
|
|
* @return int Number of active modules |
185
|
|
|
*/ |
186
|
|
|
public function getNumberActiveModules(){ |
187
|
|
|
if(HookProvider::getInstance()->isModuleOperational()){ |
188
|
|
|
$sqlquery = ''; |
189
|
|
|
$sqlparams = array($this->hook_function); |
190
|
|
View Code Duplication |
if($this->hook_context != 'all') { |
|
|
|
|
191
|
|
|
$sqlparams = array($this->hook_function, $this->hook_context); |
192
|
|
|
$sqlquery = " OR majh_hook_context=?"; |
193
|
|
|
} |
194
|
|
|
$module_names=Database::prepare( |
195
|
|
|
"SELECT majh_module_name AS modules FROM `##maj_hooks`". |
196
|
|
|
" WHERE majh_hook_function = ? AND (majh_hook_context='all'".$sqlquery.") AND majh_status='enabled'" |
197
|
|
|
)->execute($sqlparams)->fetchOneColumn(); |
198
|
|
|
return count($module_names); |
199
|
|
|
} |
200
|
|
|
return 0; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Return whether any active module is linked to a hook |
205
|
|
|
* |
206
|
|
|
* @return bool True is active modules exist, false otherwise |
207
|
|
|
*/ |
208
|
|
|
public function hasAnyActiveModule(){ |
209
|
|
|
return ($this->getNumberActiveModules()>0); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
} |
213
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.