Elgg  Version master
HandlersService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
6 
16 
17  use Loggable;
18 
19  protected const CLASS_NAME_PATTERN_53 = '/^(\\\\?[a-z_\x7f-\xff][a-z0-9_\x7f-\xff]*)+$/i';
20 
30  public function call($callable, $object, $args): array {
31  $original = $callable;
32 
33  $callable = $this->resolveCallable($callable);
34  if (!is_callable($callable)) {
35  $type = '';
36  switch (gettype($object)) {
37  case 'string':
38  $type = $object;
39  break;
40  case 'object':
41  $type = $object::class;
42  break;
43  }
44 
45  $description = ltrim($type . " [{$args[0]}, {$args[1]}]");
46 
47  $this->getLogger()->warning("Handler for {$description} is not callable: " . $this->describeCallable($original));
48 
49  return [false, null, $object];
50  }
51 
52  if (is_string($object)) {
53  switch ($object) {
54  case 'event':
55  $object = new Event(elgg(), $args[0], $args[1], $args[2], $args[3]);
56  break;
57 
58  case 'middleware':
59  case 'controller':
60  case 'action':
61  $object = new Request(elgg(), $args[0]);
62  break;
63  }
64  }
65 
66  $result = call_user_func($callable, $object);
67 
68  return [true, $result, $object];
69  }
70 
80  public function isCallable($callback) {
81  $callback = $this->resolveCallable($callback);
82  return $callback && is_callable($callback);
83  }
84 
92  public function resolveCallable($callable) {
93  if (is_callable($callable)) {
94  return $callable;
95  }
96 
97  if (is_string($callable)
98  && preg_match(self::CLASS_NAME_PATTERN_53, $callable)
99  && class_exists($callable)) {
100  $callable = new $callable;
101  }
102 
103  return is_callable($callable) ? $callable : null;
104  }
105 
115  public function describeCallable($callable, $file_root = '') {
116  if (is_string($callable)) {
117  return $callable;
118  }
119 
120  if (is_array($callable) && array_keys($callable) === [0, 1] && is_string($callable[1])) {
121  if (is_string($callable[0])) {
122  return "{$callable[0]}::{$callable[1]}";
123  }
124 
125  return '(' . get_class($callable[0]) . ")->{$callable[1]}";
126  }
127 
128  if ($callable instanceof \Closure) {
129  $ref = new \ReflectionFunction($callable);
130  $file = $ref->getFileName();
131  $line = $ref->getStartLine();
132 
133  if ($file_root && str_starts_with($file, $file_root)) {
134  $file = substr($file, strlen($file_root));
135  }
136 
137  return "(Closure {$file}:{$line})";
138  }
139 
140  if (is_object($callable)) {
141  return '(' . get_class($callable) . ')->__invoke()';
142  }
143 
144  return print_r($callable, true);
145  }
146 }
isCallable($callback)
Test is callback is callable Unlike is_callable(), this function also tests invokable classes...
Helpers for providing callable-based APIs.
$type
Definition: delete.php:22
$args
Some servers don&#39;t allow PHP to check the rewrite, so try via AJAX.
trait Loggable
Enables adding a logger.
Definition: Loggable.php:14
resolveCallable($callable)
Resolve a callable, possibly instantiating a class name.
$description
Definition: record.php:15
describeCallable($callable, $file_root= '')
Get a string description of a callback.
call($callable, $object, $args)
Call the handler with the event object.
getLogger()
Returns logger.
Definition: Loggable.php:37
if($email instanceof\Elgg\Email) $object
Definition: body.php:24
Request container.
Definition: Request.php:12
var elgg
Definition: elgglib.js:4
Models an event passed to event handlers.
Definition: Event.php:11