plugins.php ➔ _elgg_reindex_plugin_priorities()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Elgg plugins library
4
 * Contains functions for managing plugins
5
 *
6
 * @package Elgg.Core
7
 * @subpackage Plugins
8
 */
9
10
/**
11
 * Tells \ElggPlugin::start() to include the start.php file.
12
 */
13
define('ELGG_PLUGIN_INCLUDE_START', 1);
14
15
/**
16
 * Tells \ElggPlugin::start() to automatically register the plugin's views.
17
 */
18
define('ELGG_PLUGIN_REGISTER_VIEWS', 2);
19
20
/**
21
 * Tells \ElggPlugin::start() to automatically register the plugin's languages.
22
 */
23
define('ELGG_PLUGIN_REGISTER_LANGUAGES', 4);
24
25
/**
26
 * Tells \ElggPlugin::start() to automatically register the plugin's classes.
27
 */
28
define('ELGG_PLUGIN_REGISTER_CLASSES', 8);
29
30
/**
31
 * Prefix for plugin setting names
32
 *
33
 * @todo Can't namespace these because many plugins directly call
34
 * private settings via $entity->$name.
35
 */
36
//define('ELGG_PLUGIN_SETTING_PREFIX', 'plugin:setting:');
37
38
/**
39
 * Prefix for plugin user setting names
40
 */
41
define('ELGG_PLUGIN_USER_SETTING_PREFIX', 'plugin:user_setting:');
42
43
/**
44
 * Internal settings prefix
45
 *
46
 * @todo This could be resolved by promoting \ElggPlugin to a 5th type.
47
 */
48
define('ELGG_PLUGIN_INTERNAL_PREFIX', 'elgg:internal:');
49
50
51
/**
52
 * Returns a list of plugin directory names from a base directory.
53
 *
54
 * @param string $dir A dir to scan for plugins. Defaults to config's plugins_path.
55
 *                    Must have a trailing slash.
56
 *
57
 * @return array Array of directory names (not full paths)
58
 * @since 1.8.0
59
 * @access private
60
 */
61
function _elgg_get_plugin_dirs_in_dir($dir = null) {
62
	return _elgg_services()->plugins->getDirsInDir($dir);
63
}
64
65
/**
66
 * Discovers plugins in the plugins_path setting and creates \ElggPlugin
67
 * entities for them if they don't exist.  If there are plugins with entities
68
 * but not actual files, will disable the \ElggPlugin entities and mark as inactive.
69
 * The \ElggPlugin object holds config data, so don't delete.
70
 *
71
 * @return bool
72
 * @since 1.8.0
73
 * @access private
74
 */
75
function _elgg_generate_plugin_entities() {
76
	return _elgg_services()->plugins->generateEntities();
77
}
78
79
/**
80
 * Cache a reference to this plugin by its ID
81
 * 
82
 * @param \ElggPlugin $plugin
83
 * 
84
 * @access private
85
 */
86
function _elgg_cache_plugin_by_id(\ElggPlugin $plugin) {
87
	return _elgg_services()->plugins->cache($plugin);
88
}
89
90
/**
91
 * Returns an \ElggPlugin object with the path $path.
92
 *
93
 * @param string $plugin_id The id (dir name) of the plugin. NOT the guid.
94
 * @return \ElggPlugin|null
95
 * @since 1.8.0
96
 */
97
function elgg_get_plugin_from_id($plugin_id) {
98
	return _elgg_services()->plugins->get($plugin_id);
99
}
100
101
/**
102
 * Returns if a plugin exists in the system.
103
 *
104
 * @warning This checks only plugins that are registered in the system!
105
 * If the plugin cache is outdated, be sure to regenerate it with
106
 * {@link _elgg_generate_plugin_objects()} first.
107
 *
108
 * @param string $id The plugin ID.
109
 * @since 1.8.0
110
 * @return bool
111
 */
112
function elgg_plugin_exists($id) {
113
	return _elgg_services()->plugins->exists($id);
114
}
115
116
/**
117
 * Returns the highest priority of the plugins
118
 *
119
 * @return int
120
 * @since 1.8.0
121
 * @access private
122
 */
123
function _elgg_get_max_plugin_priority() {
124
	return _elgg_services()->plugins->getMaxPriority();
125
}
126
127
/**
128
 * Returns if a plugin is active for a current site.
129
 *
130
 * @param string $plugin_id The plugin ID
131
 * @param int    $site_guid The site guid
132
 * @since 1.8.0
133
 * @return bool
134
 */
135
function elgg_is_active_plugin($plugin_id, $site_guid = null) {
136
	return _elgg_services()->plugins->isActive($plugin_id, $site_guid);
137
}
138
139
/**
140
 * Loads all active plugins in the order specified in the tool admin panel.
141
 *
142
 * @note This is called on every page load. If a plugin is active and problematic, it
143
 * will be disabled and a visible error emitted. This does not check the deps system because
144
 * that was too slow.
145
 *
146
 * @return bool
147
 * @since 1.8.0
148
 * @access private
149
 */
150
function _elgg_load_plugins() {
151
	return _elgg_services()->plugins->load();
152
}
153
154
/**
155
 * Returns an ordered list of plugins
156
 *
157
 * @param string $status    The status of the plugins. active, inactive, or all.
158
 * @param mixed  $site_guid Optional site guid
159
 * @return \ElggPlugin[]
160
 * @since 1.8.0
161
 */
162
function elgg_get_plugins($status = 'active', $site_guid = null) {
163
	return _elgg_services()->plugins->find($status, $site_guid);
164
}
165
166
/**
167
 * Reorder plugins to an order specified by the array.
168
 * Plugins not included in this array will be appended to the end.
169
 *
170
 * @note This doesn't use the \ElggPlugin->setPriority() method because
171
 *       all plugins are being changed and we don't want it to automatically
172
 *       reorder plugins.
173
 *
174
 * @param array $order An array of plugin ids in the order to set them
175
 * @return bool
176
 * @since 1.8.0
177
 * @access private
178
 */
179
function _elgg_set_plugin_priorities(array $order) {
180
	return _elgg_services()->plugins->setPriorities($order);
181
}
182
183
/**
184
 * Reindexes all plugin priorities starting at 1.
185
 *
186
 * @todo Can this be done in a single sql command?
187
 * @return bool
188
 * @since 1.8.0
189
 * @access private
190
 */
191
function _elgg_reindex_plugin_priorities() {
192
	return _elgg_services()->plugins->reindexPriorities();
193
}
194
195
/**
196
 * Namespaces a string to be used as a private setting name for a plugin.
197
 *
198
 * For user_settings, two namespaces are added: a user setting namespace and the
199
 * plugin id.
200
 *
201
 * For internal (plugin priority), there is a single internal namespace added.
202
 *
203
 * @param string $type The type of setting: user_setting or internal.
204
 * @param string $name The name to namespace.
205
 * @param string $id   The plugin's ID to namespace with.  Required for user_setting.
206
 * @return string
207
 * @since 1.8.0
208
 * @access private
209
 */
210
function _elgg_namespace_plugin_private_setting($type, $name, $id = null) {
211
	return _elgg_services()->plugins->namespacePrivateSetting($type, $name, $id);
212
}
213
214
/**
215
 * Returns an array of all provides from all active plugins.
216
 *
217
 * Array in the form array(
218
 * 	'provide_type' => array(
219
 * 		'provided_name' => array(
220
 * 			'version' => '1.8',
221
 * 			'provided_by' => 'provider_plugin_id'
222
 *  	)
223
 *  )
224
 * )
225
 *
226
 * @param string $type The type of provides to return
227
 * @param string $name A specific provided name to return. Requires $provide_type.
228
 *
229
 * @return array
230
 * @since 1.8.0
231
 * @access private
232
 */
233
function _elgg_get_plugins_provides($type = null, $name = null) {
234
	return _elgg_services()->plugins->getProvides($type, $name);
235
}
236
237
/**
238
 * Deletes all cached data on plugins being provided.
239
 * 
240
 * @return boolean
241
 * @since 1.9.0
242
 * @access private
243
 */
244
function _elgg_invalidate_plugins_provides_cache() {
245
	return _elgg_services()->plugins->invalidateProvidesCache();
246
}
247
248
/**
249
 * Checks if a plugin is currently providing $type and $name, and optionally
250
 * checking a version.
251
 *
252
 * @param string $type       The type of the provide
253
 * @param string $name       The name of the provide
254
 * @param string $version    A version to check against
255
 * @param string $comparison The comparison operator to use in version_compare()
256
 *
257
 * @return array An array in the form array(
258
 * 	'status' => bool Does the provide exist?,
259
 * 	'value' => string The version provided
260
 * )
261
 * @since 1.8.0
262
 * @access private
263
 */
264
function _elgg_check_plugins_provides($type, $name, $version = null, $comparison = 'ge') {
265
	return _elgg_services()->plugins->checkProvides($type, $name, $version, $comparison);
266
}
267
268
/**
269
 * Returns an array of parsed strings for a dependency in the
270
 * format: array(
271
 * 	'type'			=>	requires, conflicts, or provides.
272
 * 	'name'			=>	The name of the requirement / conflict
273
 * 	'value'			=>	A string representing the expected value: <1, >=3, !=enabled
274
 * 	'local_value'	=>	The current value, ("Not installed")
275
 * 	'comment'		=>	Free form text to help resovle the problem ("Enable / Search for plugin <link>")
276
 * )
277
 *
278
 * @param array $dep An \ElggPluginPackage dependency array
279
 * @return array
280
 * @since 1.8.0
281
 * @access private
282
 */
283
function _elgg_get_plugin_dependency_strings($dep) {
284
	return _elgg_services()->plugins->getDependencyStrings($dep);
285
}
286
287
/**
288
 * Returns an array of all plugin user settings for a user.
289
 *
290
 * @param int    $user_guid  The user GUID or 0 for the currently logged in user.
291
 * @param string $plugin_id  The plugin ID (Required)
292
 * @param bool   $return_obj Return settings as an object? This can be used to in reusable
293
 *                           views where the settings are passed as $vars['entity'].
294
 * @return array
295
 * @since 1.8.0
296
 * @see \ElggPlugin::getAllUserSettings()
297
 */
298
function elgg_get_all_plugin_user_settings($user_guid = 0, $plugin_id = null, $return_obj = false) {
299
	return _elgg_services()->plugins->getAllUserSettings($user_guid, $plugin_id, $return_obj);
300
}
301
302
/**
303
 * Set a user specific setting for a plugin.
304
 *
305
 * @param string $name      The name. Note: cannot be "title".
306
 * @param mixed  $value     The value.
307
 * @param int    $user_guid The user GUID or 0 for the currently logged in user.
308
 * @param string $plugin_id The plugin ID (Required)
309
 *
310
 * @return bool
311
 * @since 1.8.0
312
 * @see \ElggPlugin::setUserSetting()
313
 */
314
function elgg_set_plugin_user_setting($name, $value, $user_guid = 0, $plugin_id = null) {
315
	return _elgg_services()->plugins->setUserSetting($name, $value, $user_guid, $plugin_id);
316
}
317
318
/**
319
 * Unsets a user-specific plugin setting
320
 *
321
 * @param string $name      Name of the setting
322
 * @param int    $user_guid The user GUID or 0 for the currently logged in user.
323
 * @param string $plugin_id The plugin ID (Required)
324
 *
325
 * @return bool
326
 * @since 1.8.0
327
 * @see \ElggPlugin::unsetUserSetting()
328
 */
329
function elgg_unset_plugin_user_setting($name, $user_guid = 0, $plugin_id = null) {
330
	return _elgg_services()->plugins->unsetUserSetting($name, $user_guid, $plugin_id);
331
}
332
333
/**
334
 * Get a user specific setting for a plugin.
335
 *
336
 * @param string $name      The name of the setting.
337
 * @param int    $user_guid The user GUID or 0 for the currently logged in user.
338
 * @param string $plugin_id The plugin ID (Required)
339
 * @param mixed  $default   The default value to return if none is set
340
 *
341
 * @return mixed
342
 * @since 1.8.0
343
 * @see \ElggPlugin::getUserSetting()
344
 */
345
function elgg_get_plugin_user_setting($name, $user_guid = 0, $plugin_id = null, $default = null) {
346
	return _elgg_services()->plugins->getUserSetting($name, $user_guid, $plugin_id, $default);
347
}
348
349
/**
350
 * Set a setting for a plugin.
351
 *
352
 * @param string $name      The name of the setting - note, can't be "title".
353
 * @param mixed  $value     The value.
354
 * @param string $plugin_id The plugin ID (Required)
355
 *
356
 * @return bool
357
 * @since 1.8.0
358
 * @see \ElggPlugin::setSetting()
359
 */
360
function elgg_set_plugin_setting($name, $value, $plugin_id = null) {
361
	return _elgg_services()->plugins->setSetting($name, $value, $plugin_id);
362
}
363
364
/**
365
 * Get setting for a plugin.
366
 *
367
 * @param string $name      The name of the setting.
368
 * @param string $plugin_id The plugin ID (Required)
369
 * @param mixed  $default   The default value to return if none is set
370
 *
371
 * @return mixed
372
 * @since 1.8.0
373
 * @see \ElggPlugin::getSetting()
374
 */
375
function elgg_get_plugin_setting($name, $plugin_id = null, $default = null) {
376
	return _elgg_services()->plugins->getSetting($name, $plugin_id, $default);
377
}
378
379
/**
380
 * Unsets a plugin setting.
381
 *
382
 * @param string $name      The name of the setting.
383
 * @param string $plugin_id The plugin ID (Required)
384
 *
385
 * @return bool
386
 * @since 1.8.0
387
 * @see \ElggPlugin::unsetSetting()
388
 */
389
function elgg_unset_plugin_setting($name, $plugin_id = null) {
390
	return _elgg_services()->plugins->unsetSetting($name, $plugin_id);
391
}
392
393
/**
394
 * Unsets all plugin settings for a plugin.
395
 *
396
 * @param string $plugin_id The plugin ID (Required)
397
 *
398
 * @return bool
399
 * @since 1.8.0
400
 * @see \ElggPlugin::unsetAllSettings()
401
 */
402
function elgg_unset_all_plugin_settings($plugin_id = null) {
403
	return _elgg_services()->plugins->unsetAllSettings($plugin_id);
404
}
405
406
/**
407
 * Returns entities based upon plugin user settings.
408
 * Takes all the options for {@link elgg_get_entities_from_private_settings()}
409
 * in addition to the ones below.
410
 *
411
 * @param array $options Array in the format:
412
 *
413
 * 	plugin_id => STR The plugin id. Required.
414
 *
415
 * 	plugin_user_setting_names => null|ARR private setting names
416
 *
417
 * 	plugin_user_setting_values => null|ARR metadata values
418
 *
419
 * 	plugin_user_setting_name_value_pairs => null|ARR (
420
 *                                         name => 'name',
421
 *                                         value => 'value',
422
 *                                         'operand' => '=',
423
 *                                        )
424
 * 	                             Currently if multiple values are sent via
425
 *                               an array (value => array('value1', 'value2')
426
 *                               the pair's operand will be forced to "IN".
427
 *
428
 * 	plugin_user_setting_name_value_pairs_operator => null|STR The operator to use for combining
429
 *                                        (name = value) OPERATOR (name = value); default AND
430
 *
431
 * @return mixed int If count, int. If not count, array. false on errors.
432
 * @since 1.8.0
433
 */
434
function elgg_get_entities_from_plugin_user_settings(array $options = array()) {
435
	return _elgg_services()->plugins->getEntitiesFromUserSettings($options);
436
}
437
438
/**
439
 * Runs unit tests for plugin API.
440
 *
441
 * @param string $hook   unit_test
442
 * @param string $type   system
443
 * @param mixed  $value  Array of tests
444
 * @param mixed  $params Params
445
 *
446
 * @return array
447
 * @access private
448
 */
449
function _elgg_plugins_test($hook, $type, $value, $params) {
450
	global $CONFIG;
451
	$value[] = $CONFIG->path . 'engine/tests/ElggCorePluginsAPITest.php';
452
	return $value;
453
}
454
455
/**
456
 * Checks on deactivate plugin event if disabling it won't create unmet dependencies and blocks disable in such case.
457
 *
458
 * @param string $event  deactivate
459
 * @param string $type   plugin
460
 * @param array  $params Parameters array containing entry with ELggPlugin instance under 'plugin_entity' key
461
 * @return bool  false to block plugin deactivation action
462
 *
463
 * @access private
464
 */
465
function _plugins_deactivate_dependency_check($event, $type, $params) {
466
	$plugin_id = $params['plugin_entity']->getManifest()->getPluginID();
467
	$plugin_name = $params['plugin_entity']->getManifest()->getName();
468
469
	$active_plugins = elgg_get_plugins();
470
471
	$dependents = array();
472
	foreach ($active_plugins as $plugin) {
473
		$manifest = $plugin->getManifest();
474
		$requires = $manifest->getRequires();
475
476
		foreach ($requires as $required) {
477
			if ($required['type'] == 'plugin' && $required['name'] == $plugin_id) {
478
				// there are active dependents
479
				$dependents[$manifest->getPluginID()] = $plugin;
480
			}
481
		}
482
	}
483
484
	if ($dependents) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dependents of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
485
		$list = '<ul>';
486
		// construct error message and prevent disabling
487
		foreach ($dependents as $dependent) {
488
			$list .= '<li>' . $dependent->getManifest()->getName() . '</li>';
489
		}
490
		$list .= '</ul>';
491
492
		register_error(elgg_echo('ElggPlugin:Dependencies:ActiveDependent', array($plugin_name, $list)));
493
494
		return false;
495
	}
496
}
497
498
/**
499
 * Initialize the plugin system
500
 *
501
 * @return void
502
 * @access private
503
 */
504
function _elgg_plugins_init() {
505
506
	if (elgg_is_admin_logged_in()) {
507
		elgg_register_ajax_view('object/plugin/full');
508
	}
509
510
	elgg_register_plugin_hook_handler('unit_test', 'system', '_elgg_plugins_test');
511
512
	// note - plugins are booted by the time this handler is registered
513
	// deactivation due to error may have already occurred
514
	elgg_register_event_handler('deactivate', 'plugin', '_plugins_deactivate_dependency_check');
515
516
	/**
517
	 * @see \Elgg\Database\Plugins::invalidateIsActiveCache
518
	 */
519
	$svc = _elgg_services()->plugins;
520
	elgg_register_event_handler('deactivate', 'plugin', array($svc, 'invalidateIsActiveCache'));
0 ignored issues
show
Documentation introduced by
array($svc, 'invalidateIsActiveCache') is of type array<integer,object<Elg...lugins>","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
521
	elgg_register_event_handler('activate', 'plugin', array($svc, 'invalidateIsActiveCache'));
0 ignored issues
show
Documentation introduced by
array($svc, 'invalidateIsActiveCache') is of type array<integer,object<Elg...lugins>","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
522
523
	elgg_register_action("plugins/settings/save", '', 'admin');
524
	elgg_register_action("plugins/usersettings/save");
525
526
	elgg_register_action('admin/plugins/activate', '', 'admin');
527
	elgg_register_action('admin/plugins/deactivate', '', 'admin');
528
	elgg_register_action('admin/plugins/activate_all', '', 'admin');
529
	elgg_register_action('admin/plugins/deactivate_all', '', 'admin');
530
531
	elgg_register_action('admin/plugins/set_priority', '', 'admin');
532
533
	elgg_register_library('elgg:markdown', elgg_get_root_path() . 'vendors/markdown/markdown.php');
534
}
535
536
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
537
	$events->registerHandler('init', 'system', '_elgg_plugins_init');
538
};
539