Elgg  Version master
Plugins.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Database;
4 
6 use Elgg\Config;
7 use Elgg\Context;
8 use Elgg\Database;
13 use Elgg\Invoker;
18 use Elgg\Traits\Loggable;
20 use Psr\Log\LogLevel;
21 
28 class Plugins {
29 
30  use Profilable;
31  use Loggable;
32 
33  const BUNDLED_PLUGINS = [
34  'activity',
35  'blog',
36  'bookmarks',
37  'ckeditor',
38  'custom_index',
39  'dashboard',
40  'developers',
41  'discussions',
42  'externalpages',
43  'file',
44  'friends',
45  'friends_collections',
46  'garbagecollector',
47  'groups',
48  'invitefriends',
49  'likes',
50  'members',
51  'messageboard',
52  'messages',
53  'notifications',
54  'pages',
55  'profile',
56  'reportedcontent',
57  'search',
58  'site_notifications',
59  'system_log',
60  'tagcloud',
61  'theme_sandbox',
62  'thewire',
63  'uservalidationbyemail',
64  'web_services',
65  ];
66 
70  protected ?array $boot_plugins;
71 
72  protected Context $context;
73 
88  public function __construct(
89  protected PluginsCache $cache,
90  protected Database $db,
91  protected SessionManagerService $session_manager,
92  protected EventsService $events,
93  protected Translator $translator,
94  protected ViewsService $views,
95  protected Config $config,
96  protected SystemMessagesService $system_messages,
97  protected Invoker $invoker,
99  ) {
100  $this->context = $request->getContextStack();
101  }
102 
108  public function getPath(): string {
109  return $this->config->plugins_path;
110  }
111 
120  public function setBootPlugins(?array $plugins = null, bool $order_plugins = true): void {
121  $this->cache->clear();
122  if (!is_array($plugins)) {
123  unset($this->boot_plugins);
124  return;
125  }
126 
127  // Always (re)set the boot_plugins. This makes sure that even if you have no plugins active this is known to the system.
128  $this->boot_plugins = [];
129 
130  if ($order_plugins) {
131  $plugins = $this->orderPluginsByPriority($plugins);
132  }
133 
134  foreach ($plugins as $plugin) {
135  if (!$plugin instanceof \ElggPlugin) {
136  continue;
137  }
138 
139  $plugin_id = $plugin->getID();
140  if (!$plugin_id) {
141  continue;
142  }
143 
144  $plugin->registerLanguages();
145 
146  $this->boot_plugins[$plugin_id] = $plugin;
147 
148  // make sure the plugin is in the entity and plugin cache
149  $plugin->cache();
150 
151  // can't use ElggEntity::cache() as it conflict with metadata preloading
152  $this->cache->save($plugin_id, $plugin);
153  }
154  }
155 
164  public function getDirsInDir(?string $dir = null): array {
165  if (!$dir) {
166  $dir = $this->getPath();
167  }
168 
169  if (!is_dir($dir)) {
170  return [];
171  }
172 
173  $handle = opendir($dir);
174  if ($handle === false) {
175  return [];
176  }
177 
178  $plugin_dirs = [];
179  while (($plugin_dir = readdir($handle)) !== false) {
180  // must be directory and not begin with a .
181  if (!str_starts_with($plugin_dir, '.') && is_dir($dir . $plugin_dir)) {
182  $plugin_dirs[] = $plugin_dir;
183  }
184  }
185 
186  sort($plugin_dirs);
187 
188  return $plugin_dirs;
189  }
190 
199  public function generateEntities(): bool {
200  // ignore access in case this is called with no admin logged in - needed for creating plugins perhaps?
201  // show hidden entities so that we can enable them if appropriate
202  return $this->invoker->call(ELGG_IGNORE_ACCESS | ELGG_SHOW_DISABLED_ENTITIES, function() {
203  $mod_dir = $this->getPath();
204 
205  $known_plugins = $this->find('all');
206 
207  // keeps track if reindexing is needed
208  $reindex = false;
209 
210  // map paths to indexes
211  $id_map = [];
212  $latest_priority = 0;
213  foreach ($known_plugins as $i => $plugin) {
214  // if the ID is wrong, delete the plugin because we can never load it.
215  $id = $plugin->getID() . $plugin->guid;
216  if (!$id) {
217  $plugin->delete();
218  unset($known_plugins[$i]);
219  continue;
220  }
221 
222  $id_map[$plugin->getID()] = $i;
223 
224  // disabled plugins should have no priority, so no need to check if the priority is incorrect
225  if (!$plugin->isEnabled()) {
226  continue;
227  }
228 
229  $current_priority = $plugin->getPriority();
230  if (($current_priority - $latest_priority) > 1) {
231  $reindex = true;
232  }
233 
234  $latest_priority = $current_priority;
235  }
236 
237  $physical_plugins = $this->getDirsInDir($mod_dir);
238  if (empty($physical_plugins)) {
239  return false;
240  }
241 
242  // check real plugins against known ones
243  foreach ($physical_plugins as $plugin_id) {
244  // is this already in the db?
245  if (array_key_exists($plugin_id, $id_map)) {
246  $index = $id_map[$plugin_id];
247  $plugin = $known_plugins[$index];
248  // was this plugin deleted and its entity disabled?
249  if (!$plugin->isEnabled()) {
250  $plugin->enable();
251  try {
252  $plugin->deactivate();
253  } catch (PluginException $e) {
254  // do nothing
255  }
256 
257  $plugin->setPriority('new');
258  }
259 
260  // remove from the list of plugins to disable
261  unset($known_plugins[$index]);
262  } else {
263  // create new plugin
264  // priority is forced to last in save() if not set.
266  }
267  }
268 
269  // everything remaining in $known_plugins needs to be disabled
270  // because they are entities, but their dirs were removed.
271  // don't delete the entities because they hold settings.
272  foreach ($known_plugins as $plugin) {
273  if (!$plugin->isEnabled()) {
274  continue;
275  }
276 
277  $reindex = true;
278 
279  if ($plugin->isActive()) {
280  try {
281  $plugin->deactivate();
282  } catch (PluginException $e) {
283  // do nothing
284  }
285  }
286 
287  // remove the priority.
288  $plugin->deleteMetadata(\ElggPlugin::PRIORITY_SETTING_NAME);
289 
290  $plugin->disable();
291  }
292 
293  if ($reindex) {
294  $this->reindexPriorities();
295  }
296 
297  return true;
298  });
299  }
300 
308  public function get(string $plugin_id): ?\ElggPlugin {
309  if (empty($plugin_id)) {
310  return null;
311  }
312 
313  $plugin = $this->cache->load($plugin_id);
314  if ($plugin instanceof \ElggPlugin) {
315  return $plugin;
316  }
317 
318  $plugins = elgg_get_entities([
319  'type' => 'object',
320  'subtype' => 'plugin',
321  'metadata_name_value_pairs' => [
322  'name' => 'title',
323  'value' => $plugin_id,
324  ],
325  'limit' => 1,
326  'distinct' => false,
327  ]);
328 
329  if (empty($plugins)) {
330  return null;
331  }
332 
333  $plugin = $plugins[0];
334 
335  $this->cache->save($plugin_id, $plugin);
336 
337  return $plugin;
338  }
339 
345  public function getMaxPriority(): int {
346  $qb = Select::fromTable(EntityTable::TABLE_NAME, EntityTable::DEFAULT_JOIN_ALIAS);
347  $qb->select('MAX(CAST(md.value AS unsigned)) as max')
348  ->join($qb->getTableAlias(), MetadataTable::TABLE_NAME, 'md', "{$qb->getTableAlias()}.guid = md.entity_guid")
349  ->where($qb->compare('md.name', '=', \ElggPlugin::PRIORITY_SETTING_NAME, ELGG_VALUE_STRING))
350  ->andWhere($qb->compare("{$qb->getTableAlias()}.type", '=', 'object', ELGG_VALUE_STRING))
351  ->andWhere($qb->compare("{$qb->getTableAlias()}.subtype", '=', 'plugin', ELGG_VALUE_STRING));
352 
353  $data = $this->db->getDataRow($qb);
354  if (empty($data)) {
355  return 1;
356  }
357 
358  return max(1, (int) $data->max);
359  }
360 
368  public function isActive(string $plugin_id): bool {
369  if (isset($this->boot_plugins) && is_array($this->boot_plugins)) {
370  return array_key_exists($plugin_id, $this->boot_plugins);
371  }
372 
373  $plugin = $this->get($plugin_id);
374  if (!$plugin instanceof \ElggPlugin) {
375  return false;
376  }
377 
378  return $plugin->hasRelationship(1, 'active_plugin');
379  }
380 
390  public function build(): bool {
391  $plugins_path = $this->getPath();
392 
393  // temporary disable all plugins if there is a file called 'disabled' in the plugin dir
394  if (file_exists("{$plugins_path}/disabled")) {
395  if ($this->session_manager->isAdminLoggedIn() && $this->context->contains('admin')) {
396  $this->system_messages->addSuccessMessage($this->translator->translate('plugins:disabled'));
397  }
398 
399  return false;
400  }
401 
402  $this->events->registerHandler('plugins_load', 'system', [$this, 'register']);
403  $this->events->registerHandler('plugins_boot:before', 'system', [$this, 'boot']);
404  $this->events->registerHandler('init', 'system', [$this, 'init']);
405  $this->events->registerHandler('ready', 'system', [$this, 'ready']);
406  $this->events->registerHandler('upgrade', 'system', [$this, 'upgrade']);
407  $this->events->registerHandler('shutdown', 'system', [$this, 'shutdown']);
408 
409  return true;
410  }
411 
418  public function register(): void {
419  $plugins = $this->find('active');
420  if (empty($plugins)) {
421  return;
422  }
423 
424  $this->beginTimer([__METHOD__]);
425 
426  foreach ($plugins as $plugin) {
427  try {
428  $plugin->register();
429  } catch (\Exception $ex) {
430  $this->disable($plugin, $ex);
431  }
432  }
433 
434  $this->endTimer([__METHOD__]);
435  }
436 
442  public function boot(): void {
443  $plugins = $this->find('active');
444  if (empty($plugins)) {
445  return;
446  }
447 
448  $this->beginTimer([__METHOD__]);
449 
450  foreach ($plugins as $plugin) {
451  try {
452  $plugin->boot();
453  } catch (\Exception $ex) {
454  $this->disable($plugin, $ex);
455  }
456  }
457 
458  $this->endTimer([__METHOD__]);
459  }
460 
466  public function init(): void {
467  $plugins = $this->find('active');
468  if (empty($plugins)) {
469  return;
470  }
471 
472  $this->beginTimer([__METHOD__]);
473 
474  foreach ($plugins as $plugin) {
475  try {
476  $plugin->init();
477  } catch (\Exception $ex) {
478  $this->disable($plugin, $ex);
479  }
480  }
481 
482  $this->endTimer([__METHOD__]);
483  }
484 
490  public function ready(): void {
491  $plugins = $this->find('active');
492  if (empty($plugins)) {
493  return;
494  }
495 
496  $this->beginTimer([__METHOD__]);
497 
498  foreach ($plugins as $plugin) {
499  try {
500  $plugin->getBootstrap()->ready();
501  } catch (\Exception $ex) {
502  $this->disable($plugin, $ex);
503  }
504  }
505 
506  $this->endTimer([__METHOD__]);
507  }
508 
514  public function upgrade(): void {
515  $plugins = $this->find('active');
516  if (empty($plugins)) {
517  return;
518  }
519 
520  $this->beginTimer([__METHOD__]);
521 
522  foreach ($plugins as $plugin) {
523  try {
524  $plugin->getBootstrap()->upgrade();
525  } catch (\Exception $ex) {
526  $this->disable($plugin, $ex);
527  }
528  }
529 
530  $this->endTimer([__METHOD__]);
531  }
532 
538  public function shutdown(): void {
539  $plugins = $this->find('active');
540  if (empty($plugins)) {
541  return;
542  }
543 
544  $this->beginTimer([__METHOD__]);
545 
546  foreach ($plugins as $plugin) {
547  try {
548  $plugin->getBootstrap()->shutdown();
549  } catch (\Exception $ex) {
550  $this->disable($plugin, $ex);
551  }
552  }
553 
554  $this->endTimer([__METHOD__]);
555  }
556 
565  protected function disable(\ElggPlugin $plugin, \Exception $previous): void {
566  $this->getLogger()->log(LogLevel::ERROR, $previous, [
567  'context' => [
568  'plugin' => $plugin,
569  ],
570  ]);
571 
572  if (!$this->config->auto_disable_plugins) {
573  return;
574  }
575 
576  try {
577  $id = $plugin->getID();
578  $plugin->deactivate();
579 
580  $msg = $this->translator->translate(
581  'PluginException:CannotStart',
582  [$id, $plugin->guid, $previous->getMessage()]
583  );
584 
585  elgg_add_admin_notice("cannot_start {$id}", $msg);
586  } catch (PluginException $ex) {
587  $this->getLogger()->log(LogLevel::ERROR, $ex, [
588  'context' => [
589  'plugin' => $plugin,
590  ],
591  ]);
592  }
593  }
594 
602  public function find(string $status = 'active'): array {
603  if (!$this->db || !$this->config->installed) {
604  return [];
605  }
606 
607  if ($status === 'active' && isset($this->boot_plugins)) {
608  // boot_plugins is an already ordered list of plugins
609  return array_values($this->boot_plugins);
610  }
611 
612  $volatile_data_name = null;
613  $site_guid = 1;
614 
615  // grab plugins
616  $options = [
617  'type' => 'object',
618  'subtype' => 'plugin',
619  'limit' => false,
620  'order_by' => false,
621  ];
622 
623  switch ($status) {
624  case 'active':
625  $options['relationship'] = 'active_plugin';
626  $options['relationship_guid'] = $site_guid;
627  $options['inverse_relationship'] = true;
628 
629  // shorten callstack
630  $volatile_data_name = 'select:value';
631  $options['select'] = [MetadataTable::DEFAULT_JOIN_ALIAS . '.value'];
632  $options['metadata_names'] = [
634  ];
635  break;
636 
637  case 'inactive':
638  $options['wheres'][] = function (QueryBuilder $qb, $main_alias) use ($site_guid) {
639  $subquery = $qb->subquery('entity_relationships', 'active_er');
640  $subquery->select('active_er.guid_one')
641  ->where($qb->compare('active_er.relationship', '=', 'active_plugin', ELGG_VALUE_STRING))
642  ->andWhere($qb->compare('active_er.guid_two', '=', $site_guid, ELGG_VALUE_GUID));
643 
644  return $qb->compare("{$main_alias}.guid", 'NOT IN', $subquery->getSQL());
645  };
646  break;
647 
648  case 'all':
649  default:
650  break;
651  }
652 
653  $plugins = $this->invoker->call(ELGG_IGNORE_ACCESS, function () use ($options) {
654  return elgg_get_entities($options) ?: [];
655  });
656 
657  $result = $this->orderPluginsByPriority($plugins, $volatile_data_name);
658 
659  if ($status === 'active' && !isset($this->boot_plugins)) {
660  // populate local cache if for some reason this is not set yet
661  $this->setBootPlugins($result, false);
662  }
663 
664  foreach ($plugins as $plugin) {
665  // can't use ElggEntity::cache() as it conflict with metadata preloading
666  $this->cache->save($plugin->getID(), $plugin);
667  }
668 
669  return $result;
670  }
671 
680  protected function orderPluginsByPriority(array $plugins = [], ?string $volatile_data_name = null): array {
681  $priorities = [];
682  $sorted_plugins = [];
683 
684  foreach ($plugins as $plugin) {
685  $priority = null;
686  if (!empty($volatile_data_name)) {
687  $priority = $plugin->getVolatileData($volatile_data_name);
688  }
689 
690  if (!isset($priority)) {
691  $priority = $plugin->getPriority();
692  }
693 
694  $priorities[$plugin->guid] = (int) $priority;
695  $sorted_plugins[$plugin->guid] = $plugin;
696  }
697 
698  asort($priorities);
699 
700  return array_values(array_replace($priorities, $sorted_plugins));
701  }
702 
715  public function setPriorities(array $order): bool {
716  $name = \ElggPlugin::PRIORITY_SETTING_NAME;
717 
718  $plugins = $this->find('all');
719  if (empty($plugins)) {
720  return false;
721  }
722 
723  // reindex to get standard counting. no need to increment by 10.
724  // though we do start with 1
725  $order = array_values($order);
726 
727  /* @var \ElggPlugin[] $missing_plugins */
728  $missing_plugins = [];
729 
730  $priority = 0;
731  foreach ($plugins as $plugin) {
732  if (!$plugin->isEnabled()) {
733  // disabled plugins should not have a priority
734  if ($plugin->getPriority() !== null) {
735  // remove the priority
736  unset($plugin->$name);
737  }
738 
739  continue;
740  }
741 
742  $plugin_id = $plugin->getID();
743 
744  if (!in_array($plugin_id, $order)) {
745  $missing_plugins[] = $plugin;
746  continue;
747  }
748 
749  $priority = array_search($plugin_id, $order) + 1;
750 
751  if (!$plugin->setMetadata($name, $priority)) {
752  return false;
753  }
754  }
755 
756  // set the missing plugins' priorities
757  if (empty($missing_plugins)) {
758  return true;
759  }
760 
761  foreach ($missing_plugins as $plugin) {
762  $priority++;
763  if (!$plugin->setMetadata($name, $priority)) {
764  return false;
765  }
766  }
767 
768  return true;
769  }
770 
776  public function reindexPriorities(): bool {
777  return $this->setPriorities([]);
778  }
779 
788  public function setPriority(\ElggPlugin $plugin, int $priority): int|false {
789  $old_priority = $plugin->getPriority() ?: 1;
790 
792 
793  if (!$plugin->setMetadata($name, $priority)) {
794  return false;
795  }
796 
797  if (!$plugin->guid) {
798  return false;
799  }
800 
801  $qb = Update::table(MetadataTable::TABLE_NAME);
802  $qb->where($qb->compare('name', '=', $name, ELGG_VALUE_STRING))
803  ->andWhere($qb->compare('entity_guid', '!=', $plugin->guid, ELGG_VALUE_INTEGER));
804 
805  if ($priority > $old_priority) {
806  $qb->set('value', 'CAST(value AS UNSIGNED) - 1');
807  $qb->andWhere($qb->between('CAST(value AS UNSIGNED)', $old_priority, $priority, ELGG_VALUE_INTEGER));
808  } else {
809  $qb->set('value', 'CAST(value AS UNSIGNED) + 1');
810  $qb->andWhere($qb->between('CAST(value AS UNSIGNED)', $priority, $old_priority, ELGG_VALUE_INTEGER));
811  }
812 
813  if (!$this->db->updateData($qb)) {
814  return false;
815  }
816 
817  return $priority;
818  }
819 }
if(! $user||! $user->canDelete()) $name
Definition: delete.php:22
$id
Generic annotation delete action.
Definition: delete.php:6
$plugin_id
Remove all user and plugin settings from the give plugin ID.
Definition: remove.php:8
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
if(! $entity instanceof \ElggUser) $data
Definition: attributes.php:13
Plugin class containing helper functions for plugin activation/deactivation, dependency checking capa...
Definition: ElggPlugin.php:17
const PRIORITY_SETTING_NAME
Definition: ElggPlugin.php:19
static fromId(string $plugin_id, ?string $path=null)
Load a plugin object from its ID Create a new plugin entity if it doesn't exist.
Definition: ElggPlugin.php:82
Manages a global stack of strings for sharing information about the current execution context.
Definition: Context.php:27
Entity table database service.
Definition: EntityTable.php:24
Persistent, installation-wide key-value storage.
Definition: Plugins.php:28
disable(\ElggPlugin $plugin, \Exception $previous)
Disable a plugin upon exception.
Definition: Plugins.php:565
find(string $status='active')
Returns an ordered list of plugins.
Definition: Plugins.php:602
reindexPriorities()
Reindexes all plugin priorities starting at 1.
Definition: Plugins.php:776
shutdown()
Run plugin shutdown handlers.
Definition: Plugins.php:538
ready()
Run plugin ready handlers.
Definition: Plugins.php:490
setPriorities(array $order)
Reorder plugins to an order specified by the array.
Definition: Plugins.php:715
getMaxPriority()
Returns the highest priority of the plugins.
Definition: Plugins.php:345
build()
Registers lifecycle events for all active plugins sorted by their priority.
Definition: Plugins.php:390
getDirsInDir(?string $dir=null)
Returns a list of plugin directory names from a base directory.
Definition: Plugins.php:164
boot()
Boot the plugins.
Definition: Plugins.php:442
setPriority(\ElggPlugin $plugin, int $priority)
Set plugin priority and adjust the priorities of other plugins.
Definition: Plugins.php:788
init()
Initialize plugins.
Definition: Plugins.php:466
__construct(protected PluginsCache $cache, protected Database $db, protected SessionManagerService $session_manager, protected EventsService $events, protected Translator $translator, protected ViewsService $views, protected Config $config, protected SystemMessagesService $system_messages, protected Invoker $invoker, Request $request)
Constructor.
Definition: Plugins.php:88
generateEntities()
Discovers plugins in the plugins_path setting and creates \ElggPlugin entities for them if they don't...
Definition: Plugins.php:199
orderPluginsByPriority(array $plugins=[], ?string $volatile_data_name=null)
Sorts plugins by priority.
Definition: Plugins.php:680
isActive(string $plugin_id)
Returns if a plugin is active for a current site.
Definition: Plugins.php:368
setBootPlugins(?array $plugins=null, bool $order_plugins=true)
Set the list of active plugins according to the boot data cache.
Definition: Plugins.php:120
getPath()
Get the plugin path for this installation, ending with slash.
Definition: Plugins.php:108
upgrade()
Run plugin upgrade handlers.
Definition: Plugins.php:514
Database abstraction query builder.
Query builder for fetching data from the database.
Definition: Select.php:8
The Elgg database.
Definition: Database.php:26
Events service.
Elgg HTTP request.
Definition: Request.php:17
Invocation service.
Definition: Invoker.php:10
Find Elgg and project paths.
Definition: Paths.php:8
System messages service.
Views service.
const ELGG_VALUE_STRING
Definition: constants.php:112
const ELGG_IGNORE_ACCESS
elgg_call() flags
Definition: constants.php:121
const ELGG_SHOW_DISABLED_ENTITIES
Definition: constants.php:123
const ELGG_VALUE_GUID
Definition: constants.php:113
const ELGG_VALUE_INTEGER
Value types.
Definition: constants.php:111
if($who_can_change_language==='nobody') elseif($who_can_change_language==='admin_only' &&!elgg_is_admin_logged_in()) $options
Definition: language.php:20
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
foreach($recommendedExtensions as $extension) if(empty(ini_get('session.gc_probability'))||empty(ini_get('session.gc_divisor'))) $db
$views
Definition: item.php:17
$index
Definition: gallery.php:40
elgg_add_admin_notice(string $id, string $message)
Write a persistent message to the admin view.
Definition: admin.php:51
elgg_get_entities(array $options=[])
Fetches/counts entities or performs a calculation on their properties.
Definition: entities.php:507
$request
Definition: livesearch.php:12
endTimer(array $keys)
Ends the timer (when enabled)
Definition: Profilable.php:59
trait Profilable
Make an object accept a timer.
Definition: Profilable.php:12
beginTimer(array $keys)
Start the timer (when enabled)
Definition: Profilable.php:43
$qb
Definition: queue.php:12
if(parse_url(elgg_get_site_url(), PHP_URL_PATH) !=='/') if(file_exists(elgg_get_root_path() . 'robots.txt'))
Set robots.txt.
Definition: robots.php:10
$priority
$plugin