Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
HooksRegistrationService.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg;
3 
15 abstract class HooksRegistrationService {
16 
17  const REG_KEY_PRIORITY = 0;
18  const REG_KEY_INDEX = 1;
19  const REG_KEY_HANDLER = 2;
20 
24  private $next_index = 0;
25 
29  private $registrations = [];
30 
34  private $backups = [];
35 
39  protected $logger;
40 
47  public function setLogger(\Elgg\Logger $logger = null) {
48  $this->logger = $logger;
49  return $this;
50  }
51 
60  public function registerHandler($name, $type, $callback, $priority = 500) {
61  if (empty($name) || empty($type) || !is_callable($callback, true)) {
62  return false;
63  }
64 
65  if (($name == 'view' || $name == 'view_vars') && $type != 'all') {
66  $type = _elgg_services()->views->canonicalizeViewName($type);
67  }
68 
69  $this->registrations[$name][$type][] = [
70  self::REG_KEY_PRIORITY => $priority,
71  self::REG_KEY_INDEX => $this->next_index,
72  self::REG_KEY_HANDLER => $callback,
73  ];
74  $this->next_index++;
75 
76  return true;
77  }
78 
89  public function unregisterHandler($name, $type, $callback) {
90  if (($name == 'view' || $name == 'view_vars') && $type != 'all') {
91  $type = _elgg_services()->views->canonicalizeViewName($type);
92  }
93 
94  if (empty($this->registrations[$name][$type])) {
95  return false;
96  }
97 
98  $matcher = $this->getMatcher($callback);
99 
100  foreach ($this->registrations[$name][$type] as $i => $registration) {
101 
102  if ($matcher) {
103  if (!$matcher->matches($registration[self::REG_KEY_HANDLER])) {
104  continue;
105  }
106  } else {
107  if ($registration[self::REG_KEY_HANDLER] != $callback) {
108  continue;
109  }
110  }
111 
112  unset($this->registrations[$name][$type][$i]);
113  return true;
114  }
115 
116  return false;
117  }
118 
128  public function clearHandlers($name, $type) {
129  unset($this->registrations[$name][$type]);
130  }
131 
146  public function getAllHandlers() {
147  $ret = [];
148  foreach ($this->registrations as $name => $types) {
149  foreach ($types as $type => $registrations) {
150  foreach ($registrations as $registration) {
151  $priority = $registration[self::REG_KEY_PRIORITY];
152  $handler = $registration[self::REG_KEY_HANDLER];
153  $ret[$name][$type][$priority][] = $handler;
154  }
155  }
156  }
157 
158  return $ret;
159  }
160 
171  public function hasHandler($name, $type) {
172  return !empty($this->registrations[$name][$type]);
173  }
174 
185  public function getOrderedHandlers($name, $type) {
186  $registrations = [];
187 
188  if (!empty($this->registrations[$name][$type])) {
189  if ($name !== 'all' && $type !== 'all') {
190  array_splice($registrations, count($registrations), 0, $this->registrations[$name][$type]);
191  }
192  }
193  if (!empty($this->registrations['all'][$type])) {
194  if ($type !== 'all') {
195  array_splice($registrations, count($registrations), 0, $this->registrations['all'][$type]);
196  }
197  }
198  if (!empty($this->registrations[$name]['all'])) {
199  if ($name !== 'all') {
200  array_splice($registrations, count($registrations), 0, $this->registrations[$name]['all']);
201  }
202  }
203  if (!empty($this->registrations['all']['all'])) {
204  array_splice($registrations, count($registrations), 0, $this->registrations['all']['all']);
205  }
206 
207  usort($registrations, function ($a, $b) {
208  // priority first
209  if ($a[self::REG_KEY_PRIORITY] < $b[self::REG_KEY_PRIORITY]) {
210  return -1;
211  }
212  if ($a[self::REG_KEY_PRIORITY] > $b[self::REG_KEY_PRIORITY]) {
213  return 1;
214  }
215  // then insertion order
216  return ($a[self::REG_KEY_INDEX] < $b[self::REG_KEY_INDEX]) ? -1 : 1;
217  });
218 
219  $handlers = [];
220  foreach ($registrations as $registration) {
221  $handlers[] = $registration[self::REG_KEY_HANDLER];
222  }
223 
224  return $handlers;
225  }
226 
234  protected function getMatcher($spec) {
235  if (is_string($spec) && false !== strpos($spec, '::')) {
236  list ($type, $method) = explode('::', $spec, 2);
237  return new MethodMatcher($type, $method);
238  }
239 
240  if (!is_array($spec) || empty($spec[0]) || empty($spec[1]) || !is_string($spec[1])) {
241  return null;
242  }
243 
244  if (is_object($spec[0])) {
245  $spec[0] = get_class($spec[0]);
246  }
247 
248  if (!is_string($spec[0])) {
249  return null;
250  }
251 
252  return new MethodMatcher($spec[0], $spec[1]);
253  }
254 
267  public function backup() {
268  $this->backups[] = $this->registrations;
269  $this->registrations = [];
270  }
271 
280  public function restore() {
281  $backup = array_pop($this->backups);
282  if (is_array($backup)) {
283  $this->registrations = $backup;
284  }
285  }
286 }
clearHandlers($name, $type)
Clears all handlers for a specific hook.
hasHandler($name, $type)
Is a handler registered for this specific name and type? "all" handlers are not considered.
setLogger(\Elgg\Logger $logger=null)
Set a logger instance, e.g.
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
$method
Definition: form.php:25
registerHandler($name, $type, $callback, $priority=500)
Registers a handler.
backup()
Temporarily remove all event/hook registrations (before tests)
Identify a static/dynamic method callable, even if contains an object to which you don't have a refer...
getMatcher($spec)
Create a matcher for the given callable (if it's for a static or dynamic method)
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
getAllHandlers()
Returns all registered handlers as array( $name => array( $type => array( $priority => array( callbac...
$handler
Definition: add.php:10
unregisterHandler($name, $type, $callback)
Unregister a handler.
$priority
if(!$display_name) $type
Definition: delete.php:27
restore()
Restore backed up event/hook registrations (after tests)
getOrderedHandlers($name, $type)
Returns an ordered array of handlers registered for $name and $type.