Elgg  Version 3.0
HooksRegistrationService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
10 abstract class HooksRegistrationService {
11 
12  const REG_KEY_PRIORITY = 0;
13  const REG_KEY_INDEX = 1;
14  const REG_KEY_HANDLER = 2;
15 
16  const OPTION_DEPRECATION_MESSAGE = 'deprecation_message';
17  const OPTION_DEPRECATION_VERSION = 'deprecation_version';
18 
22  private $next_index = 0;
23 
27  private $registrations = [];
28 
32  private $backups = [];
33 
48  public function registerHandler($name, $type, $callback, $priority = 500) {
49  if (empty($name) || empty($type) || !is_callable($callback, true)) {
50  return false;
51  }
52 
53  $this->registrations[$name][$type][] = [
54  self::REG_KEY_PRIORITY => $priority,
55  self::REG_KEY_INDEX => $this->next_index,
56  self::REG_KEY_HANDLER => $callback,
57  ];
58  $this->next_index++;
59 
60  return true;
61  }
62 
76  public function unregisterHandler($name, $type, $callback) {
77  if (empty($this->registrations[$name][$type])) {
78  return false;
79  }
80 
81  $matcher = $this->getMatcher($callback);
82 
83  foreach ($this->registrations[$name][$type] as $i => $registration) {
84  if ($matcher) {
85  if (!$matcher->matches($registration[self::REG_KEY_HANDLER])) {
86  continue;
87  }
88  } else {
89  if ($registration[self::REG_KEY_HANDLER] != $callback) {
90  continue;
91  }
92  }
93 
94  unset($this->registrations[$name][$type][$i]);
95  return true;
96  }
97 
98  return false;
99  }
100 
111  public function clearHandlers($name, $type) {
112  unset($this->registrations[$name][$type]);
113  }
114 
128  public function getAllHandlers() {
129  $ret = [];
130  foreach ($this->registrations as $name => $types) {
131  foreach ($types as $type => $registrations) {
132  foreach ($registrations as $registration) {
133  $priority = $registration[self::REG_KEY_PRIORITY];
134  $handler = $registration[self::REG_KEY_HANDLER];
135  $ret[$name][$type][$priority][] = $handler;
136  }
137  }
138  }
139 
140  return $ret;
141  }
142 
153  public function hasHandler($name, $type) {
154  return !empty($this->registrations[$name][$type]);
155  }
156 
165  public function getOrderedHandlers($name, $type) {
166  $registrations = [];
167 
168  if (!empty($this->registrations[$name][$type])) {
169  if ($name !== 'all' && $type !== 'all') {
170  array_splice($registrations, count($registrations), 0, $this->registrations[$name][$type]);
171  }
172  }
173  if (!empty($this->registrations['all'][$type])) {
174  if ($type !== 'all') {
175  array_splice($registrations, count($registrations), 0, $this->registrations['all'][$type]);
176  }
177  }
178  if (!empty($this->registrations[$name]['all'])) {
179  if ($name !== 'all') {
180  array_splice($registrations, count($registrations), 0, $this->registrations[$name]['all']);
181  }
182  }
183  if (!empty($this->registrations['all']['all'])) {
184  array_splice($registrations, count($registrations), 0, $this->registrations['all']['all']);
185  }
186 
187  usort($registrations, function ($a, $b) {
188  // priority first
189  if ($a[self::REG_KEY_PRIORITY] < $b[self::REG_KEY_PRIORITY]) {
190  return -1;
191  }
192  if ($a[self::REG_KEY_PRIORITY] > $b[self::REG_KEY_PRIORITY]) {
193  return 1;
194  }
195  // then insertion order
196  return ($a[self::REG_KEY_INDEX] < $b[self::REG_KEY_INDEX]) ? -1 : 1;
197  });
198 
199  $handlers = [];
200  foreach ($registrations as $registration) {
201  $handlers[] = $registration[self::REG_KEY_HANDLER];
202  }
203 
204  return $handlers;
205  }
206 
214  protected function getMatcher($spec) {
215  if (is_string($spec) && false !== strpos($spec, '::')) {
216  list ($type, $method) = explode('::', $spec, 2);
217  return new MethodMatcher($type, $method);
218  }
219 
220  if (!is_array($spec) || empty($spec[0]) || empty($spec[1]) || !is_string($spec[1])) {
221  return null;
222  }
223 
224  if (is_object($spec[0])) {
225  $spec[0] = get_class($spec[0]);
226  }
227 
228  if (!is_string($spec[0])) {
229  return null;
230  }
231 
232  return new MethodMatcher($spec[0], $spec[1]);
233  }
234 
245  public function backup() {
246  $this->backups[] = $this->registrations;
247  $this->registrations = [];
248  }
249 
256  public function restore() {
257  $backup = array_pop($this->backups);
258  if (is_array($backup)) {
259  $this->registrations = $backup;
260  }
261  }
262 
272  protected function checkDeprecation($name, $type, array $options = []) {
273  $options = array_merge([
274  self::OPTION_DEPRECATION_MESSAGE => '',
275  self::OPTION_DEPRECATION_VERSION => '',
276  ], $options);
277 
278  $handlers = $this->hasHandler($name, $type);
279  if (!$handlers || !$options[self::OPTION_DEPRECATION_MESSAGE]) {
280  return;
281  }
282 
283  _elgg_services()->deprecation->sendNotice(
284  $options[self::OPTION_DEPRECATION_MESSAGE],
285  $options[self::OPTION_DEPRECATION_VERSION],
286  4
287  );
288  }
289 }
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
clearHandlers($name, $type)
Clears all callback registrations for a plugin hook.
hasHandler($name, $type)
Is a handler registered for this specific name and type? "all" handlers are not considered.
registerHandler($name, $type, $callback, $priority=500)
Register a callback as a plugin hook handler.
$type
Definition: delete.php:21
$options
Elgg admin footer.
Definition: footer.php:6
backup()
Temporarily remove all event/hook registrations (before tests)
Configuration exception.
Base class for events and hooks.
Identify a static/dynamic method callable, even if contains an object to which you don&#39;t have a refer...
getMatcher($spec)
Create a matcher for the given callable (if it&#39;s for a static or dynamic method)
checkDeprecation($name, $type, array $options=[])
Check if handlers are registered on a deprecated hook/event.
_elgg_services()
Get the global service provider.
Definition: elgglib.php:1292
getAllHandlers()
Returns all registered handlers as array( $name => array( $type => array( $priority => array( callbac...
$handler
Definition: add.php:7
unregisterHandler($name, $type, $callback)
Unregister a callback as a plugin hook of event handler.
$priority
restore()
Restore backed up event/hook registrations (after tests)
getOrderedHandlers($name, $type)
Returns an ordered array of handlers registered for $name and $type.