Elgg  Version 2.3
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  $this->registrations[$name][$type][] = [
66  self::REG_KEY_PRIORITY => $priority,
67  self::REG_KEY_INDEX => $this->next_index,
68  self::REG_KEY_HANDLER => $callback,
69  ];
70  $this->next_index++;
71 
72  return true;
73  }
74 
85  public function unregisterHandler($name, $type, $callback) {
86  if (($name == 'view' || $name == 'view_vars') && $type != 'all') {
87  $type = _elgg_services()->views->canonicalizeViewName($type);
88  }
89 
90  if (empty($this->registrations[$name][$type])) {
91  return false;
92  }
93 
94  $matcher = $this->getMatcher($callback);
95 
96  foreach ($this->registrations[$name][$type] as $i => $registration) {
97 
98  if ($matcher) {
99  if (!$matcher->matches($registration[self::REG_KEY_HANDLER])) {
100  continue;
101  }
102  } else {
103  if ($registration[self::REG_KEY_HANDLER] != $callback) {
104  continue;
105  }
106  }
107 
108  unset($this->registrations[$name][$type][$i]);
109  return true;
110  }
111 
112  return false;
113  }
114 
124  public function clearHandlers($name, $type) {
125  unset($this->registrations[$name][$type]);
126  }
127 
142  public function getAllHandlers() {
143  $ret = [];
144  foreach ($this->registrations as $name => $types) {
145  foreach ($types as $type => $registrations) {
146  foreach ($registrations as $registration) {
147  $priority = $registration[self::REG_KEY_PRIORITY];
148  $handler = $registration[self::REG_KEY_HANDLER];
149  $ret[$name][$type][$priority][] = $handler;
150  }
151  }
152  }
153 
154  return $ret;
155  }
156 
167  public function hasHandler($name, $type) {
168  return !empty($this->registrations[$name][$type]);
169  }
170 
181  public function getOrderedHandlers($name, $type) {
182  $registrations = [];
183 
184  if (!empty($this->registrations[$name][$type])) {
185  if ($name !== 'all' && $type !== 'all') {
186  array_splice($registrations, count($registrations), 0, $this->registrations[$name][$type]);
187  }
188  }
189  if (!empty($this->registrations['all'][$type])) {
190  if ($type !== 'all') {
191  array_splice($registrations, count($registrations), 0, $this->registrations['all'][$type]);
192  }
193  }
194  if (!empty($this->registrations[$name]['all'])) {
195  if ($name !== 'all') {
196  array_splice($registrations, count($registrations), 0, $this->registrations[$name]['all']);
197  }
198  }
199  if (!empty($this->registrations['all']['all'])) {
200  array_splice($registrations, count($registrations), 0, $this->registrations['all']['all']);
201  }
202 
203  usort($registrations, function ($a, $b) {
204  // priority first
205  if ($a[self::REG_KEY_PRIORITY] < $b[self::REG_KEY_PRIORITY]) {
206  return -1;
207  }
208  if ($a[self::REG_KEY_PRIORITY] > $b[self::REG_KEY_PRIORITY]) {
209  return 1;
210  }
211  // then insertion order
212  return ($a[self::REG_KEY_INDEX] < $b[self::REG_KEY_INDEX]) ? -1 : 1;
213  });
214 
215  $handlers = [];
216  foreach ($registrations as $registration) {
217  $handlers[] = $registration[self::REG_KEY_HANDLER];
218  }
219 
220  return $handlers;
221  }
222 
230  protected function getMatcher($spec) {
231  if (is_string($spec) && false !== strpos($spec, '::')) {
232  list ($type, $method) = explode('::', $spec, 2);
233  return new MethodMatcher($type, $method);
234  }
235 
236  if (!is_array($spec) || empty($spec[0]) || empty($spec[1]) || !is_string($spec[1])) {
237  return null;
238  }
239 
240  if (is_object($spec[0])) {
241  $spec[0] = get_class($spec[0]);
242  }
243 
244  if (!is_string($spec[0])) {
245  return null;
246  }
247 
248  return new MethodMatcher($spec[0], $spec[1]);
249  }
250 
263  public function backup() {
264  $this->backups[] = $this->registrations;
265  $this->registrations = [];
266  }
267 
276  public function restore() {
277  $backup = array_pop($this->backups);
278  if (is_array($backup)) {
279  $this->registrations = $backup;
280  }
281  }
282 }
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)
Save menu items.
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)
_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.