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