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