Plugins   F
last analyzed

Complexity

Total Complexity 133

Size/Duplication

Total Lines 1035
Duplicated Lines 8.5 %

Coupling/Cohesion

Components 2
Dependencies 5

Test Coverage

Coverage 0.63%

Importance

Changes 0
Metric Value
dl 88
loc 1035
ccs 3
cts 478
cp 0.0063
rs 1.46
c 0
b 0
f 0
wmc 133
lcom 2
cbo 5

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B getDirsInDir() 0 21 6
C generateEntities() 0 90 11
A cache() 0 3 1
A get() 0 24 2
A exists() 0 5 2
A getMaxPriority() 0 21 3
B isActive() 0 26 7
B load() 0 50 10
B find() 0 50 5
B setPriorities() 0 49 10
A reindexPriorities() 0 3 1
A namespacePrivateSetting() 0 22 4
B getProvides() 0 42 11
A invalidateProvidesCache() 0 5 1
A invalidateIsActiveCache() 0 4 1
A checkProvides() 0 20 3
F getDependencyStrings() 32 113 21
B getAllUserSettings() 0 26 6
A setUserSetting() 14 14 3
A unsetUserSetting() 14 14 3
A getUserSetting() 14 14 3
A setSetting() 0 14 3
A getSetting() 14 14 3
A unsetSetting() 0 14 3
A unsetAllSettings() 0 14 3
B getEntitiesFromUserSettings() 0 40 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Plugins often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Plugins, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Elgg\Database;
3
4
use Exception;
5
6
/**
7
 * @var array cache used by elgg_get_plugins_provides function
8
 * @todo move it with all other functions to \Elgg\PluginsService
9
 */
10 1
global $ELGG_PLUGINS_PROVIDES_CACHE;
11
12
13
/**
14
 * Persistent, installation-wide key-value storage.
15
 * 
16
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
17
 *
18
 * @access private
19
 *
20
 * @package    Elgg.Core
21
 * @subpackage Database
22
 * @since      1.10.0
23
 */
24
class Plugins {
25
26
	/**
27
	 * @var string[] Active plugin IDs with IDs as the array keys. Missing keys imply inactive plugins.
28
	 */
29
	protected $active_ids = array();
30
31
	/**
32
	 * @var bool Has $active_ids been populated?
33
	 */
34
	protected $active_ids_known = false;
35
36
	/**
37
	 * @var \Elgg\Cache\MemoryPool
38
	 */
39
	protected $plugins_by_id;
40
41
	/**
42
	 * Constructor
43
	 *
44
	 * @param \Elgg\EventsService    $events Events service
45
	 * @param \Elgg\Cache\MemoryPool $pool   Cache for referencing plugins by ID
46
	 */
47 1
	public function __construct(\Elgg\EventsService $events, \Elgg\Cache\MemoryPool $pool) {
48 1
		$this->plugins_by_id = $pool;
49 1
	}
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
	 * @access private
59
	 */
60
	function getDirsInDir($dir = null) {
61
		if (!$dir) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dir of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
62
			$dir = elgg_get_plugins_path();
63
		}
64
	
65
		$plugin_dirs = array();
66
		$handle = opendir($dir);
67
	
68
		if ($handle) {
69
			while ($plugin_dir = readdir($handle)) {
70
				// must be directory and not begin with a .
71
				if (substr($plugin_dir, 0, 1) !== '.' && is_dir($dir . $plugin_dir)) {
72
					$plugin_dirs[] = $plugin_dir;
73
				}
74
			}
75
		}
76
	
77
		sort($plugin_dirs);
78
	
79
		return $plugin_dirs;
80
	}
81
	
82
	/**
83
	 * Discovers plugins in the plugins_path setting and creates \ElggPlugin
84
	 * entities for them if they don't exist.  If there are plugins with entities
85
	 * but not actual files, will disable the \ElggPlugin entities and mark as inactive.
86
	 * The \ElggPlugin object holds config data, so don't delete.
87
	 *
88
	 * @return bool
89
	 * @access private
90
	 */
91
	function generateEntities() {
92
	
93
		$mod_dir = elgg_get_plugins_path();
94
		$db_prefix = elgg_get_config('dbprefix');
95
	
96
		// ignore access in case this is called with no admin logged in - needed for creating plugins perhaps?
97
		$old_ia = elgg_set_ignore_access(true);
98
	
99
		// show hidden entities so that we can enable them if appropriate
100
		$old_access = access_get_show_hidden_status();
101
		access_show_hidden_entities(true);
102
	
103
		$options = array(
104
			'type' => 'object',
105
			'subtype' => 'plugin',
106
			'selects' => array('plugin_oe.*'),
107
			'joins' => array("JOIN {$db_prefix}objects_entity plugin_oe on plugin_oe.guid = e.guid"),
108
			'limit' => ELGG_ENTITIES_NO_VALUE,
109
		);
110
		$known_plugins = elgg_get_entities_from_relationship($options);
111
		/* @var \ElggPlugin[] $known_plugins */
112
	
113
		if (!$known_plugins) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $known_plugins of type ElggPlugin[] 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...
114
			$known_plugins = array();
115
		}
116
	
117
		// map paths to indexes
118
		$id_map = array();
119
		foreach ($known_plugins as $i => $plugin) {
120
			// if the ID is wrong, delete the plugin because we can never load it.
121
			$id = $plugin->getID();
122
			if (!$id) {
123
				$plugin->delete();
124
				unset($known_plugins[$i]);
125
				continue;
126
			}
127
			$id_map[$plugin->getID()] = $i;
128
		}
129
	
130
		$physical_plugins = _elgg_get_plugin_dirs_in_dir($mod_dir);
131
	
132
		if (!$physical_plugins) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $physical_plugins 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...
133
			return false;
134
		}
135
	
136
		// check real plugins against known ones
137
		foreach ($physical_plugins as $plugin_id) {
138
			// is this already in the db?
139
			if (array_key_exists($plugin_id, $id_map)) {
140
				$index = $id_map[$plugin_id];
141
				$plugin = $known_plugins[$index];
142
				// was this plugin deleted and its entity disabled?
143
				if (!$plugin->isEnabled()) {
144
					$plugin->enable();
145
					$plugin->deactivate();
146
					$plugin->setPriority('last');
147
				}
148
	
149
				// remove from the list of plugins to disable
150
				unset($known_plugins[$index]);
151
			} else {
152
				// create new plugin
153
				// priority is forced to last in save() if not set.
154
				$plugin = new \ElggPlugin($mod_dir . $plugin_id);
155
				$plugin->save();
156
			}
157
		}
158
	
159
		// everything remaining in $known_plugins needs to be disabled
160
		// because they are entities, but their dirs were removed.
161
		// don't delete the entities because they hold settings.
162
		foreach ($known_plugins as $plugin) {
163
			if ($plugin->isActive()) {
164
				$plugin->deactivate();
165
			}
166
			// remove the priority.
167
			$name = _elgg_namespace_plugin_private_setting('internal', 'priority');
168
			remove_private_setting($plugin->guid, $name);
169
			if ($plugin->isEnabled()) {
170
				$plugin->disable();
171
			}
172
		}
173
	
174
		access_show_hidden_entities($old_access);
175
		elgg_set_ignore_access($old_ia);
176
	
177
		_elgg_reindex_plugin_priorities();
178
	
179
		return true;
180
	}
181
	
182
	/**
183
	 * Cache a reference to this plugin by its ID
184
	 * 
185
	 * @param \ElggPlugin $plugin
186
	 * 
187
	 * @access private
188
	 */
189
	function cache(\ElggPlugin $plugin) {
190
		$this->plugins_by_id->put($plugin->getID(), $plugin);
191
	}
192
	
193
	/**
194
	 * Returns an \ElggPlugin object with the path $path.
195
	 *
196
	 * @param string $plugin_id The id (dir name) of the plugin. NOT the guid.
197
	 * @return \ElggPlugin|null
198
	 */
199
	function get($plugin_id) {
200
		return $this->plugins_by_id->get($plugin_id, function () use ($plugin_id) {
201
			$plugin_id = sanitize_string($plugin_id);
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $plugin_id, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
202
			$db_prefix = get_config('dbprefix');
203
204
			$options = array(
205
				'type' => 'object',
206
				'subtype' => 'plugin',
207
				'joins' => array("JOIN {$db_prefix}objects_entity oe on oe.guid = e.guid"),
208
				'selects' => array("oe.title", "oe.description"),
209
				'wheres' => array("oe.title = '$plugin_id'"),
210
				'limit' => 1,
211
				'distinct' => false,
212
			);
213
214
			$plugins = elgg_get_entities($options);
215
216
			if ($plugins) {
217
				return $plugins[0];
218
			}
219
220
			return null;
221
		});
222
	}
223
	
224
	/**
225
	 * Returns if a plugin exists in the system.
226
	 *
227
	 * @warning This checks only plugins that are registered in the system!
228
	 * If the plugin cache is outdated, be sure to regenerate it with
229
	 * {@link _elgg_generate_plugin_objects()} first.
230
	 *
231
	 * @param string $id The plugin ID.
232
	 * @return bool
233
	 */
234
	function exists($id) {
235
		$plugin = elgg_get_plugin_from_id($id);
236
	
237
		return ($plugin) ? true : false;
238
	}
239
	
240
	/**
241
	 * Returns the highest priority of the plugins
242
	 *
243
	 * @return int
244
	 * @access private
245
	 */
246
	function getMaxPriority() {
247
		$db_prefix = get_config('dbprefix');
248
		$priority = _elgg_namespace_plugin_private_setting('internal', 'priority');
249
		$plugin_subtype = get_subtype_id('object', 'plugin');
250
	
251
		$q = "SELECT MAX(CAST(ps.value AS unsigned)) as max
252
			FROM {$db_prefix}entities e, {$db_prefix}private_settings ps
253
			WHERE ps.name = '$priority'
254
			AND ps.entity_guid = e.guid
255
			AND e.type = 'object' and e.subtype = $plugin_subtype";
256
	
257
		$data = get_data($q);
258
		if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data 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...
259
			$max = $data[0]->max;
260
		} else {
261
			$max = 1;
262
		}
263
	
264
		// can't have a priority of 0.
265
		return ($max) ? $max : 1;
266
	}
267
	
268
	/**
269
	 * Returns if a plugin is active for a current site.
270
	 *
271
	 * @param string $plugin_id The plugin ID
272
	 * @param int    $site_guid The site guid
273
	 * @return bool
274
	 */
275
	function isActive($plugin_id, $site_guid = null) {
276
		$current_site_guid = elgg_get_site_entity()->guid;
277
278
		if ($this->active_ids_known
279
				&& ($site_guid === null || $site_guid == $current_site_guid)) {
280
			return isset($this->active_ids[$plugin_id]);
281
		}
282
283
		if ($site_guid) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $site_guid of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
284
			$site = get_entity($site_guid);
285
		} else {
286
			$site = elgg_get_site_entity();
287
		}
288
	
289
		if (!($site instanceof \ElggSite)) {
290
			return false;
291
		}
292
	
293
		$plugin = elgg_get_plugin_from_id($plugin_id);
294
	
295
		if (!$plugin) {
296
			return false;
297
		}
298
	
299
		return $plugin->isActive($site->guid);
300
	}
301
	
302
	/**
303
	 * Loads all active plugins in the order specified in the tool admin panel.
304
	 *
305
	 * @note This is called on every page load. If a plugin is active and problematic, it
306
	 * will be disabled and a visible error emitted. This does not check the deps system because
307
	 * that was too slow.
308
	 *
309
	 * @return bool
310
	 * @access private
311
	 */
312
	function load() {
313
		$plugins_path = elgg_get_plugins_path();
314
		$start_flags = ELGG_PLUGIN_INCLUDE_START |
315
						ELGG_PLUGIN_REGISTER_VIEWS |
316
						ELGG_PLUGIN_REGISTER_LANGUAGES |
317
						ELGG_PLUGIN_REGISTER_CLASSES;
318
	
319
		if (!$plugins_path) {
320
			return false;
321
		}
322
	
323
		// temporary disable all plugins if there is a file called 'disabled' in the plugin dir
324
		if (file_exists("$plugins_path/disabled")) {
325
			if (elgg_is_admin_logged_in() && elgg_in_context('admin')) {
326
				system_message(_elgg_services()->translator->translate('plugins:disabled'));
327
			}
328
			return false;
329
		}
330
	
331
		if (elgg_get_config('system_cache_loaded')) {
332
			$start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_VIEWS;
333
		}
334
	
335
		if (elgg_get_config('i18n_loaded_from_cache')) {
336
			$start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_LANGUAGES;
337
		}
338
	
339
		$return = true;
340
		$plugins = $this->find('active');
341
		if ($plugins) {
342
			foreach ($plugins as $plugin) {
343
				$id = $plugin->getID();
344
				try {
345
					$plugin->start($start_flags);
346
					$this->active_ids[$id] = true;
347
				} catch (Exception $e) {
348
					$plugin->deactivate();
349
					$msg = _elgg_services()->translator->translate('PluginException:CannotStart',
350
									array($id, $plugin->guid, $e->getMessage()));
351
					elgg_add_admin_notice("cannot_start $id", $msg);
352
					$return = false;
353
	
354
					continue;
355
				}
356
			}
357
		}
358
359
		$this->active_ids_known = true;
360
		return $return;
361
	}
362
	
363
	/**
364
	 * Returns an ordered list of plugins
365
	 *
366
	 * @param string $status    The status of the plugins. active, inactive, or all.
367
	 * @param mixed  $site_guid Optional site guid
368
	 * @return \ElggPlugin[]
369
	 */
370
	function find($status = 'active', $site_guid = null) {
371
		$db_prefix = get_config('dbprefix');
372
		$priority = _elgg_namespace_plugin_private_setting('internal', 'priority');
373
	
374
		if (!$site_guid) {
375
			$site = get_config('site');
376
			$site_guid = $site->guid;
377
		}
378
	
379
		// grab plugins
380
		$options = array(
381
			'type' => 'object',
382
			'subtype' => 'plugin',
383
			'limit' => ELGG_ENTITIES_NO_VALUE,
384
			'selects' => array('plugin_oe.*'),
385
			'joins' => array(
386
				"JOIN {$db_prefix}private_settings ps on ps.entity_guid = e.guid",
387
				"JOIN {$db_prefix}objects_entity plugin_oe on plugin_oe.guid = e.guid"
388
				),
389
			'wheres' => array("ps.name = '$priority'"),
390
			'order_by' => "CAST(ps.value as unsigned), e.guid",
391
			'distinct' => false,
392
		);
393
	
394
		switch ($status) {
395
			case 'active':
396
				$options['relationship'] = 'active_plugin';
397
				$options['relationship_guid'] = $site_guid;
398
				$options['inverse_relationship'] = true;
399
				break;
400
	
401
			case 'inactive':
402
				$options['wheres'][] = "NOT EXISTS (
403
						SELECT 1 FROM {$db_prefix}entity_relationships active_er
404
						WHERE active_er.guid_one = e.guid
405
							AND active_er.relationship = 'active_plugin'
406
							AND active_er.guid_two = $site_guid)";
407
				break;
408
	
409
			case 'all':
410
			default:
411
				break;
412
		}
413
	
414
		$old_ia = elgg_set_ignore_access(true);
415
		$plugins = elgg_get_entities_from_relationship($options);
416
		elgg_set_ignore_access($old_ia);
417
	
418
		return $plugins;
419
	}
420
	
421
	/**
422
	 * Reorder plugins to an order specified by the array.
423
	 * Plugins not included in this array will be appended to the end.
424
	 *
425
	 * @note This doesn't use the \ElggPlugin->setPriority() method because
426
	 *       all plugins are being changed and we don't want it to automatically
427
	 *       reorder plugins.
428
	 *
429
	 * @param array $order An array of plugin ids in the order to set them
430
	 * @return bool
431
	 * @access private
432
	 */
433
	function setPriorities(array $order) {
434
		$name = _elgg_namespace_plugin_private_setting('internal', 'priority');
435
	
436
		$plugins = elgg_get_plugins('any');
437
		if (!$plugins) {
438
			return false;
439
		}
440
	
441
		$return = true;
442
	
443
		// reindex to get standard counting. no need to increment by 10.
444
		// though we do start with 1
445
		$order = array_values($order);
446
	
447
		$missing_plugins = array();
448
		/* @var \ElggPlugin[] $missing_plugins */
449
	
450
		foreach ($plugins as $plugin) {
451
			$plugin_id = $plugin->getID();
452
	
453
			if (!in_array($plugin_id, $order)) {
454
				$missing_plugins[] = $plugin;
455
				continue;
456
			}
457
	
458
			$priority = array_search($plugin_id, $order) + 1;
459
	
460
			if (!$plugin->setPrivateSetting($name, $priority)) {
461
				$return = false;
462
				break;
463
			}
464
		}
465
	
466
		// set the missing plugins' priorities
467
		if ($return && $missing_plugins) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $missing_plugins of type ElggPlugin[] 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...
468
			if (!isset($priority)) {
469
				$priority = 0;
470
			}
471
			foreach ($missing_plugins as $plugin) {
472
				$priority++;
473
				if (!$plugin->setPrivateSetting($name, $priority)) {
474
					$return = false;
475
					break;
476
				}
477
			}
478
		}
479
	
480
		return $return;
481
	}
482
	
483
	/**
484
	 * Reindexes all plugin priorities starting at 1.
485
	 *
486
	 * @todo Can this be done in a single sql command?
487
	 * @return bool
488
	 * @access private
489
	 */
490
	function reindexPriorities() {
491
		return _elgg_set_plugin_priorities(array());
492
	}
493
	
494
	/**
495
	 * Namespaces a string to be used as a private setting name for a plugin.
496
	 *
497
	 * For user_settings, two namespaces are added: a user setting namespace and the
498
	 * plugin id.
499
	 *
500
	 * For internal (plugin priority), there is a single internal namespace added.
501
	 *
502
	 * @param string $type The type of setting: user_setting or internal.
503
	 * @param string $name The name to namespace.
504
	 * @param string $id   The plugin's ID to namespace with.  Required for user_setting.
505
	 * @return string
506
	 * @access private
507
	 */
508
	function namespacePrivateSetting($type, $name, $id = null) {
509
		switch ($type) {
510
			// commented out because it breaks $plugin->$name access to variables
511
			//case 'setting':
512
			//	$name = ELGG_PLUGIN_SETTING_PREFIX . $name;
513
			//	break;
514
	
515
			case 'user_setting':
516
				if (!$id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
517
					elgg_deprecated_notice("You must pass the plugin id to _elgg_namespace_plugin_private_setting() for user settings", 1.9);
518
					$id = elgg_get_calling_plugin_id();
519
				}
520
				$name = ELGG_PLUGIN_USER_SETTING_PREFIX . "$id:$name";
521
				break;
522
	
523
			case 'internal':
524
				$name = ELGG_PLUGIN_INTERNAL_PREFIX . $name;
525
				break;
526
		}
527
	
528
		return $name;
529
	}
530
	
531
	
532
	/**
533
	 * Returns an array of all provides from all active plugins.
534
	 *
535
	 * Array in the form array(
536
	 * 	'provide_type' => array(
537
	 * 		'provided_name' => array(
538
	 * 			'version' => '1.8',
539
	 * 			'provided_by' => 'provider_plugin_id'
540
	 *  	)
541
	 *  )
542
	 * )
543
	 *
544
	 * @param string $type The type of provides to return
545
	 * @param string $name A specific provided name to return. Requires $provide_type.
546
	 *
547
	 * @return array
548
	 * @access private
549
	 */
550
	function getProvides($type = null, $name = null) {
551
		global $ELGG_PLUGINS_PROVIDES_CACHE;
552
		if (!isset($ELGG_PLUGINS_PROVIDES_CACHE)) {
553
			$active_plugins = elgg_get_plugins('active');
554
		
555
			$provides = array();
556
	
557
			foreach ($active_plugins as $plugin) {
558
				$plugin_provides = array();
559
				$manifest = $plugin->getManifest();
560
				if ($manifest instanceof \ElggPluginManifest) {
561
					$plugin_provides = $plugin->getManifest()->getProvides();
562
				}
563
				if ($plugin_provides) {
564
					foreach ($plugin_provides as $provided) {
565
						$provides[$provided['type']][$provided['name']] = array(
566
							'version' => $provided['version'],
567
							'provided_by' => $plugin->getID()
568
						);
569
					}
570
				}
571
			}
572
			
573
			$ELGG_PLUGINS_PROVIDES_CACHE = $provides;
574
		}
575
		
576
		if ($type && $name) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $name of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
577
			if (isset($ELGG_PLUGINS_PROVIDES_CACHE[$type][$name])) {
578
				return $ELGG_PLUGINS_PROVIDES_CACHE[$type][$name];
579
			} else {
580
				return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by Elgg\Database\Plugins::getProvides of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
581
			}
582
		} elseif ($type) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
583
			if (isset($ELGG_PLUGINS_PROVIDES_CACHE[$type])) {
584
				return $ELGG_PLUGINS_PROVIDES_CACHE[$type];
585
			} else {
586
				return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by Elgg\Database\Plugins::getProvides of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
587
			}
588
		}
589
	
590
		return $ELGG_PLUGINS_PROVIDES_CACHE;
591
	}
592
	
593
	/**
594
	 * Deletes all cached data on plugins being provided.
595
	 * 
596
	 * @return boolean
597
	 * @access private
598
	 */
599
	function invalidateProvidesCache() {
600
		global $ELGG_PLUGINS_PROVIDES_CACHE;
601
		$ELGG_PLUGINS_PROVIDES_CACHE = null;
602
		return true;
603
	}
604
605
	/**
606
	 * Delete the cache holding whether plugins are active or not
607
	 *
608
	 * @return void
609
	 * @access private
610
	 */
611
	public function invalidateIsActiveCache() {
612
		$this->active_ids = array();
613
		$this->active_ids_known = false;
614
	}
615
	
616
	/**
617
	 * Checks if a plugin is currently providing $type and $name, and optionally
618
	 * checking a version.
619
	 *
620
	 * @param string $type       The type of the provide
621
	 * @param string $name       The name of the provide
622
	 * @param string $version    A version to check against
623
	 * @param string $comparison The comparison operator to use in version_compare()
624
	 *
625
	 * @return array An array in the form array(
626
	 * 	'status' => bool Does the provide exist?,
627
	 * 	'value' => string The version provided
628
	 * )
629
	 * @access private
630
	 */
631
	function checkProvides($type, $name, $version = null, $comparison = 'ge') {
632
		$provided = _elgg_get_plugins_provides($type, $name);
633
		if (!$provided) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $provided 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...
634
			return array(
635
				'status' => false,
636
				'value' => ''
637
			);
638
		}
639
	
640
		if ($version) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
641
			$status = version_compare($provided['version'], $version, $comparison);
642
		} else {
643
			$status = true;
644
		}
645
	
646
		return array(
647
			'status' => $status,
648
			'value' => $provided['version']
649
		);
650
	}
651
	
652
	/**
653
	 * Returns an array of parsed strings for a dependency in the
654
	 * format: array(
655
	 * 	'type'			=>	requires, conflicts, or provides.
656
	 * 	'name'			=>	The name of the requirement / conflict
657
	 * 	'value'			=>	A string representing the expected value: <1, >=3, !=enabled
658
	 * 	'local_value'	=>	The current value, ("Not installed")
659
	 * 	'comment'		=>	Free form text to help resovle the problem ("Enable / Search for plugin <link>")
660
	 * )
661
	 *
662
	 * @param array $dep An \ElggPluginPackage dependency array
663
	 * @return array
664
	 * @access private
665
	 */
666
	function getDependencyStrings($dep) {
667
		$translator = _elgg_services()->translator;
668
		$dep_system = elgg_extract('type', $dep);
669
		$info = elgg_extract('dep', $dep);
670
		$type = elgg_extract('type', $info);
671
	
672
		if (!$dep_system || !$info || !$type) {
673
			return false;
674
		}
675
	
676
		// rewrite some of these to be more readable
677
		$comparison = elgg_extract('comparison', $info);
678
		switch($comparison) {
679
			case 'lt':
680
				$comparison = '<';
681
				break;
682
			case 'gt':
683
				$comparison = '>';
684
				break;
685
			case 'ge':
686
				$comparison = '>=';
687
				break;
688
			case 'le':
689
				$comparison = '<=';
690
				break;
691
			default:
692
				//keep $comparison value intact
693
				break;
694
		}
695
	
696
		/*
697
		'requires'	'plugin oauth_lib'	<1.3	1.3		'downgrade'
698
		'requires'	'php setting bob'	>3		3		'change it'
699
		'conflicts'	'php setting'		>3		4		'change it'
700
		'conflicted''plugin profile'	any		1.8		'disable profile'
701
		'provides'	'plugin oauth_lib'	1.3		--		--
702
		'priority'	'before blog'		--		after	'move it'
703
		*/
704
		$strings = array();
705
		$strings['type'] = $translator->translate('ElggPlugin:Dependencies:' . ucwords($dep_system));
706
	
707
		switch ($type) {
708
			case 'elgg_version':
709 View Code Duplication
			case 'elgg_release':
710
				// 'Elgg Version'
711
				$strings['name'] = $translator->translate('ElggPlugin:Dependencies:Elgg');
712
				$strings['expected_value'] = "$comparison {$info['version']}";
713
				$strings['local_value'] = $dep['value'];
714
				$strings['comment'] = '';
715
				break;
716
	
717 View Code Duplication
			case 'php_version':
718
				// 'PHP version'
719
				$strings['name'] = $translator->translate('ElggPlugin:Dependencies:PhpVersion');
720
				$strings['expected_value'] = "$comparison {$info['version']}";
721
				$strings['local_value'] = $dep['value'];
722
				$strings['comment'] = '';
723
				break;
724
			
725
			case 'php_extension':
726
				// PHP Extension %s [version]
727
				$strings['name'] = $translator->translate('ElggPlugin:Dependencies:PhpExtension', array($info['name']));
728
				if ($info['version']) {
729
					$strings['expected_value'] = "$comparison {$info['version']}";
730
					$strings['local_value'] = $dep['value'];
731
				} else {
732
					$strings['expected_value'] = '';
733
					$strings['local_value'] = '';
734
				}
735
				$strings['comment'] = '';
736
				break;
737
	
738 View Code Duplication
			case 'php_ini':
739
				$strings['name'] = $translator->translate('ElggPlugin:Dependencies:PhpIni', array($info['name']));
740
				$strings['expected_value'] = "$comparison {$info['value']}";
741
				$strings['local_value'] = $dep['value'];
742
				$strings['comment'] = '';
743
				break;
744
	
745
			case 'plugin':
746
				$strings['name'] = $translator->translate('ElggPlugin:Dependencies:Plugin', array($info['name']));
747
				$expected = $info['version'] ? "$comparison {$info['version']}" : $translator->translate('any');
748
				$strings['expected_value'] = $expected;
749
				$strings['local_value'] = $dep['value'] ? $dep['value'] : '--';
750
				$strings['comment'] = '';
751
				break;
752
	
753
			case 'priority':
754
				$expected_priority = ucwords($info['priority']);
755
				$real_priority = ucwords($dep['value']);
756
				$strings['name'] = $translator->translate('ElggPlugin:Dependencies:Priority');
757
				$strings['expected_value'] = $translator->translate("ElggPlugin:Dependencies:Priority:$expected_priority", array($info['plugin']));
758
				$strings['local_value'] = $translator->translate("ElggPlugin:Dependencies:Priority:$real_priority", array($info['plugin']));
759
				$strings['comment'] = '';
760
				break;
761
		}
762
	
763
		if ($dep['type'] == 'suggests') {
764 View Code Duplication
			if ($dep['status']) {
765
				$strings['comment'] = $translator->translate('ok');
766
			} else {
767
				$strings['comment'] = $translator->translate('ElggPlugin:Dependencies:Suggests:Unsatisfied');
768
			}
769 View Code Duplication
		} else {
770
			if ($dep['status']) {
771
				$strings['comment'] = $translator->translate('ok');
772
			} else {
773
				$strings['comment'] = $translator->translate('error');
774
			}
775
		}
776
	
777
		return $strings;
778
	}
779
	
780
	/**
781
	 * Returns an array of all plugin user settings for a user.
782
	 *
783
	 * @param int    $user_guid  The user GUID or 0 for the currently logged in user.
784
	 * @param string $plugin_id  The plugin ID (Required)
785
	 * @param bool   $return_obj Return settings as an object? This can be used to in reusable
786
	 *                           views where the settings are passed as $vars['entity'].
787
	 * @return array
788
	 * @see \ElggPlugin::getAllUserSettings()
789
	 */
790
	function getAllUserSettings($user_guid = 0, $plugin_id = null, $return_obj = false) {
791
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
792
			$plugin = elgg_get_plugin_from_id($plugin_id);
793
		} else {
794
			elgg_deprecated_notice('elgg_get_all_plugin_user_settings() requires plugin_id to be set', 1.9);
795
			$plugin = elgg_get_calling_plugin_entity();
796
		}
797
	
798
		if (!$plugin instanceof \ElggPlugin) {
799
			return false;
800
		}
801
	
802
		$settings = $plugin->getAllUserSettings((int)$user_guid);
803
	
804
		if ($settings && $return_obj) {
805
			$return = new \stdClass;
806
	
807
			foreach ($settings as $k => $v) {
808
				$return->$k = $v;
809
			}
810
	
811
			return $return;
812
		} else {
813
			return $settings;
814
		}
815
	}
816
	
817
	/**
818
	 * Set a user specific setting for a plugin.
819
	 *
820
	 * @param string $name      The name. Note: cannot be "title".
821
	 * @param mixed  $value     The value.
822
	 * @param int    $user_guid The user GUID or 0 for the currently logged in user.
823
	 * @param string $plugin_id The plugin ID (Required)
824
	 *
825
	 * @return bool
826
	 * @see \ElggPlugin::setUserSetting()
827
	 */
828 View Code Duplication
	function setUserSetting($name, $value, $user_guid = 0, $plugin_id = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
829
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
830
			$plugin = elgg_get_plugin_from_id($plugin_id);
831
		} else {
832
			elgg_deprecated_notice('elgg_set_plugin_user_setting() requires plugin_id to be set', 1.9);
833
			$plugin = elgg_get_calling_plugin_entity();
834
		}
835
	
836
		if (!$plugin) {
837
			return false;
838
		}
839
	
840
		return $plugin->setUserSetting($name, $value, (int)$user_guid);
841
	}
842
	
843
	/**
844
	 * Unsets a user-specific plugin setting
845
	 *
846
	 * @param string $name      Name of the setting
847
	 * @param int    $user_guid The user GUID or 0 for the currently logged in user.
848
	 * @param string $plugin_id The plugin ID (Required)
849
	 *
850
	 * @return bool
851
	 * @see \ElggPlugin::unsetUserSetting()
852
	 */
853 View Code Duplication
	function unsetUserSetting($name, $user_guid = 0, $plugin_id = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
854
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
855
			$plugin = elgg_get_plugin_from_id($plugin_id);
856
		} else {
857
			elgg_deprecated_notice('elgg_unset_plugin_user_setting() requires plugin_id to be set', 1.9);
858
			$plugin = elgg_get_calling_plugin_entity();
859
		}
860
	
861
		if (!$plugin) {
862
			return false;
863
		}
864
	
865
		return $plugin->unsetUserSetting($name, (int)$user_guid);
866
	}
867
	
868
	/**
869
	 * Get a user specific setting for a plugin.
870
	 *
871
	 * @param string $name      The name of the setting.
872
	 * @param int    $user_guid The user GUID or 0 for the currently logged in user.
873
	 * @param string $plugin_id The plugin ID (Required)
874
	 * @param mixed  $default   The default value to return if none is set
875
	 *
876
	 * @return mixed
877
	 * @see \ElggPlugin::getUserSetting()
878
	 */
879 View Code Duplication
	function getUserSetting($name, $user_guid = 0, $plugin_id = null, $default = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
880
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
881
			$plugin = elgg_get_plugin_from_id($plugin_id);
882
		} else {
883
			elgg_deprecated_notice('elgg_get_plugin_user_setting() requires plugin_id to be set', 1.9);
884
			$plugin = elgg_get_calling_plugin_entity();
885
		}
886
	
887
		if (!$plugin) {
888
			return false;
889
		}
890
	
891
		return $plugin->getUserSetting($name, (int)$user_guid, $default);
892
	}
893
	
894
	/**
895
	 * Set a setting for a plugin.
896
	 *
897
	 * @param string $name      The name of the setting - note, can't be "title".
898
	 * @param mixed  $value     The value.
899
	 * @param string $plugin_id The plugin ID (Required)
900
	 *
901
	 * @return bool
902
	 * @see \ElggPlugin::setSetting()
903
	 */
904
	function setSetting($name, $value, $plugin_id = null) {
905
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
906
			$plugin = elgg_get_plugin_from_id($plugin_id);
907
		} else {
908
			elgg_deprecated_notice('elgg_set_plugin_setting() requires plugin_id to be set', 1.9);
909
			$plugin = elgg_get_calling_plugin_entity();
910
		}
911
	
912
		if (!$plugin) {
913
			return false;
914
		}
915
	
916
		return $plugin->setSetting($name, $value);
917
	}
918
	
919
	/**
920
	 * Get setting for a plugin.
921
	 *
922
	 * @param string $name      The name of the setting.
923
	 * @param string $plugin_id The plugin ID (Required)
924
	 * @param mixed  $default   The default value to return if none is set
925
	 *
926
	 * @return mixed
927
	 * @see \ElggPlugin::getSetting()
928
	 */
929 View Code Duplication
	function getSetting($name, $plugin_id = null, $default = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
930
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
931
			$plugin = elgg_get_plugin_from_id($plugin_id);
932
		} else {
933
			elgg_deprecated_notice('elgg_get_plugin_setting() requires plugin_id to be set', 1.9);
934
			$plugin = elgg_get_calling_plugin_entity();
935
		}
936
	
937
		if (!$plugin) {
938
			return false;
939
		}
940
	
941
		return $plugin->getSetting($name, $default);
942
	}
943
	
944
	/**
945
	 * Unsets a plugin setting.
946
	 *
947
	 * @param string $name      The name of the setting.
948
	 * @param string $plugin_id The plugin ID (Required)
949
	 *
950
	 * @return bool
951
	 * @see \ElggPlugin::unsetSetting()
952
	 */
953
	function unsetSetting($name, $plugin_id = null) {
954
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
955
			$plugin = elgg_get_plugin_from_id($plugin_id);
956
		} else {
957
			elgg_deprecated_notice('elgg_unset_plugin_setting() requires plugin_id to be set', 1.9);
958
			$plugin = elgg_get_calling_plugin_entity();
959
		}
960
	
961
		if (!$plugin) {
962
			return false;
963
		}
964
	
965
		return $plugin->unsetSetting($name);
966
	}
967
	
968
	/**
969
	 * Unsets all plugin settings for a plugin.
970
	 *
971
	 * @param string $plugin_id The plugin ID (Required)
972
	 *
973
	 * @return bool
974
	 * @see \ElggPlugin::unsetAllSettings()
975
	 */
976
	function unsetAllSettings($plugin_id = null) {
977
		if ($plugin_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $plugin_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
978
			$plugin = elgg_get_plugin_from_id($plugin_id);
979
		} else {
980
			elgg_deprecated_notice('elgg_unset_all_plugin_settings() requires plugin_id to be set', 1.9);
981
			$plugin = elgg_get_calling_plugin_entity();
982
		}
983
	
984
		if (!$plugin) {
985
			return false;
986
		}
987
	
988
		return $plugin->unsetAllSettings();
989
	}
990
	
991
	/**
992
	 * Returns entities based upon plugin user settings.
993
	 * Takes all the options for {@link elgg_get_entities_from_private_settings()}
994
	 * in addition to the ones below.
995
	 *
996
	 * @param array $options Array in the format:
997
	 *
998
	 * 	plugin_id => STR The plugin id. Required.
999
	 *
1000
	 * 	plugin_user_setting_names => null|ARR private setting names
1001
	 *
1002
	 * 	plugin_user_setting_values => null|ARR metadata values
1003
	 *
1004
	 * 	plugin_user_setting_name_value_pairs => null|ARR (
1005
	 *                                         name => 'name',
1006
	 *                                         value => 'value',
1007
	 *                                         'operand' => '=',
1008
	 *                                        )
1009
	 * 	                             Currently if multiple values are sent via
1010
	 *                               an array (value => array('value1', 'value2')
1011
	 *                               the pair's operand will be forced to "IN".
1012
	 *
1013
	 * 	plugin_user_setting_name_value_pairs_operator => null|STR The operator to use for combining
1014
	 *                                        (name = value) OPERATOR (name = value); default AND
1015
	 *
1016
	 * @return mixed int If count, int. If not count, array. false on errors.
1017
	 */
1018
	function getEntitiesFromUserSettings(array $options = array()) {
1019
		if (!isset($options['plugin_id'])) {
1020
			elgg_deprecated_notice("'plugin_id' is now required for elgg_get_entities_from_plugin_user_settings()", 1.9);
1021
			$options['plugin_id'] = elgg_get_calling_plugin_id();
1022
		}
1023
	
1024
		$singulars = array('plugin_user_setting_name', 'plugin_user_setting_value',
1025
			'plugin_user_setting_name_value_pair');
1026
	
1027
		$options = _elgg_normalize_plural_options_array($options, $singulars);
1028
	
1029
		// rewrite plugin_user_setting_name_* to the right PS ones.
1030
		$map = array(
1031
			'plugin_user_setting_names' => 'private_setting_names',
1032
			'plugin_user_setting_values' => 'private_setting_values',
1033
			'plugin_user_setting_name_value_pairs' => 'private_setting_name_value_pairs',
1034
			'plugin_user_setting_name_value_pairs_operator' => 'private_setting_name_value_pairs_operator',
1035
		);
1036
	
1037
		foreach ($map as $plugin => $private) {
1038
			if (!isset($options[$plugin])) {
1039
				continue;
1040
			}
1041
	
1042
			if (isset($options[$private])) {
1043
				if (!is_array($options[$private])) {
1044
					$options[$private] = array($options[$private]);
1045
				}
1046
	
1047
				$options[$private] = array_merge($options[$private], $options[$plugin]);
1048
			} else {
1049
				$options[$private] = $options[$plugin];
1050
			}
1051
		}
1052
	
1053
		$prefix = _elgg_namespace_plugin_private_setting('user_setting', '', $options['plugin_id']);
1054
		$options['private_setting_name_prefix'] = $prefix;
1055
	
1056
		return elgg_get_entities_from_private_settings($options);
1057
	}
1058
}
1059