Elgg  Version master
Inspector.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg\Debug;
3 
5 use Elgg\Includer;
8 
15 class Inspector {
16 
22  public function getEvents() {
23  return $this->buildHandlerTree(_elgg_services()->events->getAllHandlers());
24  }
25 
31  public function getViewtypes() {
32  return array_keys($this->getViewsData()['locations']);
33  }
34 
42  public function getViews($viewtype = 'default') {
43  $view_data = $this->getViewsData();
44 
45  // maps view name to array of ViewComponent[] with priority as keys
46  $views = [];
47 
48  // add plugins and handle overrides
49  foreach ($view_data['locations'][$viewtype] as $view => $location) {
50  $component = new ViewComponent();
51  $component->view = $view;
52  $component->file = $location;
53 
54  $views[$view] = [500 => $component];
55  }
56 
57  // now extensions
58  foreach ($view_data['extensions'] as $view => $extensions) {
59  $view_list = [];
60  foreach ($extensions as $priority => $ext_view) {
61  if (isset($views[$ext_view])) {
62  $view_list[$priority] = $views[$ext_view][500];
63  }
64  }
65 
66  if (count($view_list) > 0) {
67  $views[$view] = $view_list;
68  }
69  }
70 
71  ksort($views);
72 
73  // now overrides
74  foreach ($views as $view => $view_list) {
75  if (!empty($view_data['overrides'][$viewtype][$view])) {
76  $overrides_list = [];
77  foreach ($view_data['overrides'][$viewtype][$view] as $i => $location) {
78  $component = new ViewComponent();
79  $component->overridden = true;
80  $component->view = $view;
81  $component->file = $location;
82 
83  $overrides_list["o:$i"] = $component;
84  }
85 
86  $views[$view] = $overrides_list + $view_list;
87  }
88  }
89 
90  // view handlers
91  $handlers = _elgg_services()->events->getAllHandlers();
92 
93  $input_filtered_views = [];
94  if (!empty($handlers['view_vars'])) {
95  $input_filtered_views = array_keys($handlers['view_vars']);
96  }
97 
98  $filtered_views = [];
99  if (!empty($handlers['view'])) {
100  $filtered_views = array_keys($handlers['view']);
101  }
102 
103  $global_events = [];
104  if (!empty($handlers['view_vars']['all'])) {
105  $global_events[] = 'view_vars, all';
106  }
107 
108  if (!empty($handlers['view']['all'])) {
109  $global_events[] = 'view, all';
110  }
111 
112  return [
113  'views' => $views,
114  'global_events' => $global_events,
115  'input_filtered_views' => $input_filtered_views,
116  'filtered_views' => $filtered_views,
117  ];
118  }
119 
125  public function getWidgets() {
126  $tree = [];
127  foreach (_elgg_services()->widgets->getAllTypes() as $handler => $handler_obj) {
128  $tree[$handler] = [$handler_obj->name, implode(',', array_values($handler_obj->context))];
129  }
130 
131  ksort($tree);
132 
133  return $tree;
134  }
135 
143  public function getActions() {
144  $tree = [];
145  $access = [
146  'public' => 'public',
147  'logged_in' => 'logged in only',
148  'logged_out' => 'logged out only',
149  'admin' => 'admin only',
150  ];
152  foreach (_elgg_services()->actions->getAllActions() as $action => $info) {
153  if (isset($info['file'])) {
154  $info['file'] = substr($info['file'], $start);
155  } else if ($info['controller']) {
156  $info['file'] = $this->describeCallable($info['controller']);
157  }
158 
159  $tree[$action] = [$info['file'], $access[$info['access']]];
160  }
161 
162  ksort($tree);
163  return $tree;
164  }
165 
171  public function getSimpleCache() {
172  $simplecache = elgg_extract('simplecache', $this->getViewsData(), []);
173  $locations = elgg_extract('locations', $this->getViewsData(), []);
174 
175  $tree = [];
176  foreach ($simplecache as $view => $foo) {
177  $tree[$view] = '';
178  }
179 
180  // add all static views
181  foreach ($locations as $viewtype) {
182  foreach ($viewtype as $view => $location) {
183  if (pathinfo($location, PATHINFO_EXTENSION) !== 'php') {
184  $tree[$view] = '';
185  }
186  }
187  }
188 
189  ksort($tree);
190 
191  return $tree;
192  }
193 
201  public function getRoutes() {
202  $tree = [];
203  foreach (_elgg_services()->routeCollection->all() as $name => $route) {
204  $handler = $route->getDefault('_handler') ?: '';
205  if ($handler) {
207  }
208 
209  $controller = $route->getDefault('_controller') ?: '';
210  if ($controller) {
211  $controller = $this->describeCallable($controller);
212  }
213 
214  $resource = $route->getDefault('_resource') ?: '';
215 
216  $file = $route->getDefault('_file') ?: '';
217 
218  $middleware = $route->getDefault('_middleware');
219  if (!is_array($middleware)) {
220  if (!empty($middleware)) {
221  $middleware = [$middleware];
222  } else {
223  $middleware = [];
224  }
225  }
226 
227  $middleware = array_map(function($e) {
228  return $this->describeCallable($e);
229  }, $middleware);
230 
231  $tree[$name] = [
232  $route->getPath(),
233  $resource,
234  $handler,
235  $controller,
236  $file,
237  $middleware,
238  ];
239  }
240 
241  uasort($tree, function($e1, $e2) {
242  return strcmp($e1[0], $e2[0]);
243  });
244 
245  return $tree;
246  }
247 
253  public function getMenus() {
254  $menus = _elgg_services()->menus->getAllMenus();
255 
256  // get JIT menu items
257  // note that 'river' is absent from this list - events attempt to get object/subject entities cause problems
258  $jit_menus = ['annotation', 'entity', 'login', 'longtext', 'owner_block', 'user_hover', 'widget'];
259 
260  // create generic ElggEntity, ElggAnnotation, ElggUser, ElggWidget
261  $annotation = new \ElggAnnotation();
262  $annotation->id = 999;
263  $annotation->name = 'generic_comment';
264  $annotation->value = 'testvalue';
265  $annotation->entity_guid = elgg_get_logged_in_user_guid();
266 
267  $entity = new \ElggObject();
268  $entity->guid = 999;
269  $entity->setSubtype('blog');
270  $entity->title = 'test entity';
271  $entity->access_id = ACCESS_PUBLIC;
272 
274  if (!$user instanceof \ElggUser) {
275  $user = new \ElggUser();
276  $user->guid = 999;
277  $user->name = 'Test User';
278  $user->username = 'test_user';
279  }
280 
281  $widget = new \ElggWidget();
282  $widget->guid = 999;
283  $widget->title = 'test widget';
284 
285  // call events
286  foreach ($jit_menus as $type) {
287  $params = ['entity' => $entity, 'annotation' => $annotation, 'user' => $user];
288  switch ($type) {
289  case 'owner_block':
290  case 'user_hover':
291  $params['entity'] = $user;
292  break;
293  case 'widget':
294  // this does not work because you cannot set a guid on an entity
295  $params['entity'] = $widget;
296  break;
297  case 'longtext':
298  $params['id'] = rand();
299  break;
300  default:
301  break;
302  }
303 
304  $menus[$type] = _elgg_services()->events->triggerResults('register', "menu:{$type}", $params, new MenuItems());
305  }
306 
307  // put the menus in tree form for inspection
308  $tree = [];
309 
310  foreach ($menus as $menu_name => $attributes) {
311  /* @var \ElggMenuItem $item */
312  foreach ($attributes as $item) {
313  $name = $item->getName();
314  $text = htmlspecialchars($item->getText() ?? '', ENT_QUOTES, 'UTF-8', false);
315  $href = $item->getHref();
316  if ($href === false) {
317  $href = 'not a link';
318  } elseif ($href === '') {
319  $href = 'not a direct link - possibly ajax';
320  }
321 
322  $section = $item->getSection();
323  $parent = $item->getParentName();
324  if (!$parent) {
325  $parent = 'none';
326  }
327 
328  $tree[$menu_name][$name] = [
329  "text: {$text}",
330  "href: {$href}",
331  "section: {$section}",
332  "parent: {$parent}",
333  ];
334  }
335  }
336 
337  ksort($tree);
338 
339  return $tree;
340  }
341 
351  public function describeCallable($callable, $file_root = '') {
352  return _elgg_services()->handlers->describeCallable($callable, $file_root);
353  }
354 
362  protected function buildHandlerTree($all_handlers) {
363  $tree = [];
364  $root = elgg_get_root_path();
365  $handlers_svc = _elgg_services()->handlers;
366 
367  foreach ($all_handlers as $event => $types) {
368  foreach ($types as $type => $priorities) {
369  ksort($priorities);
370 
371  foreach ($priorities as $priority => $handlers) {
372  foreach ($handlers as $callable) {
373  $description = $handlers_svc->describeCallable($callable, $root);
374  $callable = "{$priority}: {$description}";
375  $tree["{$event}, {$type}"][] = $callable;
376  }
377  }
378  }
379  }
380 
381  ksort($tree);
382 
383  return $tree;
384  }
385 
391  private function getViewsData() {
392  static $data;
393  if ($data === null) {
394  $data = _elgg_services()->views->getInspectorData();
395  }
396 
397  return $data;
398  }
399 
407  public function getServices() {
408  $sources = [
409  \Elgg\Project\Paths::elgg() . 'engine/public_services.php',
410  ];
411 
412  $plugins = _elgg_services()->plugins->find('active');
413  foreach ($plugins as $plugin) {
414  $plugin->autoload(); // make sure all classes are loaded
415  $sources[] = $plugin->getPath() . \ElggPlugin::PUBLIC_SERVICES_FILENAME;
416  }
417 
418  $tree = [];
419  foreach ($sources as $source) {
420  if (!is_file($source)) {
421  continue;
422  }
423 
424  $services = Includer::includeFile($source);
425 
426  foreach ($services as $name => $service) {
427  $tree[$name] = [get_class(elgg()->$name), Paths::sanitize($source, false)];
428  }
429  }
430 
431  ksort($tree);
432 
433  return $tree;
434  }
435 
441  public function getSeeders(): array {
442  return _elgg_services()->seeder->getSeederClasses();
443  }
444 }
if(!$items) $item
Definition: delete.php:13
elgg
Definition: install.js:27
static includeFile($file)
Include a file with as little context as possible.
Definition: Includer.php:18
$plugin
$source
static elgg()
Get the Elgg codebase path with "/".
Definition: Paths.php:44
$params
Saves global plugin settings.
Definition: save.php:13
getEvents()
Get Elgg event information.
Definition: Inspector.php:22
getWidgets()
Get Elgg widget information.
Definition: Inspector.php:125
if($id< 1) $annotation
Definition: delete.php:11
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
if(elgg_view_exists("widgets/{$widget->handler}/edit")) $access
Definition: save.php:19
getServices()
Returns public DI services.
Definition: Inspector.php:407
getMenus()
Get information about registered menus.
Definition: Inspector.php:253
$type
Definition: delete.php:21
$resource
getViews($viewtype= 'default')
Get Elgg view information.
Definition: Inspector.php:42
const PUBLIC_SERVICES_FILENAME
Definition: ElggPlugin.php:21
if($item instanceof\ElggEntity) elseif($item instanceof\ElggRiverItem) elseif($item instanceof\ElggRelationship) elseif(is_callable([$item, 'getType']))
Definition: item.php:48
elgg_extract($key, $array, $default=null, bool $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:254
foreach($notification_settings as $purpose=> $prefered_methods) if((bool) elgg_get_config('enable_delayed_email')) $start
if(!$entity instanceof\ElggUser) $data
Definition: attributes.php:13
$entity
Definition: reset.php:8
if(!empty($avatar)&&!$avatar->isValid()) elseif(empty($avatar)) if(!$owner->saveIconFromUploadedFile('avatar')) if(!elgg_trigger_event('profileiconupdate', $owner->type, $owner)) $view
Definition: upload.php:39
getActions()
Get Elgg actions information.
Definition: Inspector.php:143
$user
Definition: ban.php:7
buildHandlerTree($all_handlers)
Build a tree of event handlers.
Definition: Inspector.php:362
elgg_get_root_path()
Get the project path (where composer is installed), ending with slash.
$viewtype
Definition: default.php:11
getViewtypes()
Get all view types for known views.
Definition: Inspector.php:31
$description
Definition: record.php:15
getRoutes()
Get Elgg route information.
Definition: Inspector.php:201
if($guid===false) $widget
Definition: add.php:31
$extensions
getSimpleCache()
Get simplecache information.
Definition: Inspector.php:171
$action
Definition: subscribe.php:11
Debug inspector.
Definition: Inspector.php:15
$location
Definition: member.php:29
getSeeders()
Get the registered database CLI seeders.
Definition: Inspector.php:441
static sanitize($path, $append_slash=true)
Sanitize file paths ensuring that they begin and end with slashes etc.
Definition: Paths.php:76
_elgg_services()
Get the global service provider.
Definition: elgglib.php:351
const ACCESS_PUBLIC
Definition: constants.php:12
elgg_get_logged_in_user_entity()
Return the current logged in user, or null if no user is logged in.
Definition: sessions.php:24
$handler
Definition: add.php:7
describeCallable($callable, $file_root= '')
Get a string description of a callback.
Definition: Inspector.php:351
A collection of menu items.
Definition: MenuItems.php:10
$text
Definition: button.php:33
$attributes
Elgg AJAX loader.
Definition: ajax_loader.php:10
elgg_get_logged_in_user_guid()
Return the current logged in user by guid.
Definition: sessions.php:34
$priority
$views
Definition: item.php:17