Completed
Push — master ( b746e6...94717f )
by Jonathan
06:37
created

Hook::executeOnlyFor()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 2
nop 1
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){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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