Issues (2473)

Branch: master

Security Analysis    no vulnerabilities found

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

engine/lib/admin.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Elgg admin functions.
4
 *
5
 * Admin menu items
6
 * Elgg has a convenience function for adding menu items to the sidebar of the
7
 * admin area. @see elgg_register_admin_menu_item()
8
 *
9
 * Admin pages
10
 * Plugins no not need to provide their own page handler to add a page to the
11
 * admin area. A view placed at admin/<section>/<subsection> can be access
12
 * at http://example.org/admin/<section>/<subsection>. The title of the page
13
 * will be elgg_echo('admin:<section>:<subsection>'). For an example of how to
14
 * add a page to the admin area, see the diagnostics plugin.
15
 *
16
 * Admin notices
17
 * System messages (success and error messages) are used in both the main site
18
 * and the admin area. There is a special presistent message for the admin area
19
 * called an admin notice. It should be used when a plugin requires an
20
 * administrator to take an action. An example is the categories plugin
21
 * requesting that the administrator set site categories after the plugin has
22
 * been activated. @see elgg_add_admin_notice()
23
 *
24
 *
25
 * @package Elgg.Core
26
 * @subpackage Admin
27
 */
28
29
/**
30
 * Get the admin users
31
 *
32
 * @param array $options Options array, @see elgg_get_entities() for parameters
33
 *
34
 * @return mixed Array of admin users or false on failure. If a count, returns int.
35
 * @since 1.8.0
36
 */
37
function elgg_get_admins(array $options = array()) {
38
	global $CONFIG;
39
40
	if (isset($options['joins'])) {
41
		if (!is_array($options['joins'])) {
42
			$options['joins'] = array($options['joins']);
43
		}
44
		$options['joins'][] = "join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid";
45
	} else {
46
		$options['joins'] = array("join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid");
47
	}
48
49 View Code Duplication
	if (isset($options['wheres'])) {
50
		if (!is_array($options['wheres'])) {
51
			$options['wheres'] = array($options['wheres']);
52
		}
53
		$options['wheres'][] = "u.admin = 'yes'";
54
	} else {
55
		$options['wheres'][] = "u.admin = 'yes'";
56
	}
57
58
	return elgg_get_entities($options);
59
}
60
61
/**
62
 * Write a persistent message to the admin view.
63
 * Useful to alert the admin to take a certain action.
64
 * The id is a unique ID that can be cleared once the admin
65
 * completes the action.
66
 *
67
 * eg: add_admin_notice('twitter_services_no_api',
68
 * 	'Before your users can use Twitter services on this site, you must set up
69
 * 	the Twitter API key in the <a href="link">Twitter Services Settings</a>');
70
 *
71
 * @param string $id      A unique ID that your plugin can remember
72
 * @param string $message Body of the message
73
 *
74
 * @return bool
75
 * @since 1.8.0
76
 */
77
function elgg_add_admin_notice($id, $message) {
78
	return _elgg_services()->adminNotices->add($id, $message);
79
}
80
81
/**
82
 * Remove an admin notice by ID.
83
 *
84
 * eg In actions/twitter_service/save_settings:
85
 * 	if (is_valid_twitter_api_key()) {
86
 * 		delete_admin_notice('twitter_services_no_api');
87
 * 	}
88
 *
89
 * @param string $id The unique ID assigned in add_admin_notice()
90
 *
91
 * @return bool
92
 * @since 1.8.0
93
 */
94
function elgg_delete_admin_notice($id) {
95
	return _elgg_services()->adminNotices->delete($id);
96
}
97
98
/**
99
 * Get admin notices. An admin must be logged in since the notices are private.
100
 *
101
 * @param int $limit Limit
102
 *
103
 * @return array Array of admin notices
104
 * @since 1.8.0
105
 */
106
function elgg_get_admin_notices($limit = 10) {
107
	return _elgg_services()->adminNotices->find($limit);
108
}
109
110
/**
111
 * Check if an admin notice is currently active.
112
 *
113
 * @param string $id The unique ID used to register the notice.
114
 *
115
 * @return bool
116
 * @since 1.8.0
117
 */
118
function elgg_admin_notice_exists($id) {
119
	return _elgg_services()->adminNotices->exists($id);
120
}
121
122
/**
123
 * Add an admin area section or child section.
124
 * This is a wrapper for elgg_register_menu_item().
125
 *
126
 * Used in conjuction with http://elgg.org/admin/section_id/child_section style
127
 * page handler. See the documentation at the top of this file for more details
128
 * on that.
129
 *
130
 * The text of the menu item is obtained from elgg_echo(admin:$parent_id:$menu_id)
131
 *
132
 * This function handles registering the parent if it has not been registered.
133
 *
134
 * @param string $section   The menu section to add to
135
 * @param string $menu_id   The unique ID of section
136
 * @param string $parent_id If a child section, the parent section id
137
 * @param int    $priority  The menu item priority
138
 *
139
 * @return bool
140
 * @since 1.8.0
141
 */
142
function elgg_register_admin_menu_item($section, $menu_id, $parent_id = null, $priority = 100) {
143
144
	// make sure parent is registered
145
	if ($parent_id && !elgg_is_menu_item_registered('page', $parent_id)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parent_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...
146
		elgg_register_admin_menu_item($section, $parent_id);
147
	}
148
149
	// in the admin section parents never have links
150
	if ($parent_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parent_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...
151
		$href = "admin/$parent_id/$menu_id";
152
	} else {
153
		$href = null;
154
	}
155
156
	$name = $menu_id;
157
	if ($parent_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parent_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...
158
		$name = "$parent_id:$name";
159
	}
160
161
	return elgg_register_menu_item('page', array(
162
		'name' => $name,
163
		'href' => $href,
164
		'text' => elgg_echo("admin:$name"),
165
		'context' => 'admin',
166
		'parent_name' => $parent_id,
167
		'priority' => $priority,
168
		'section' => $section
169
	));
170
}
171
172
/**
173
 * Add an admin notice when a new \ElggUpgrade object is created.
174
 *
175
 * @param string     $event
176
 * @param string     $type
177
 * @param \ElggObject $object
178
 * @access private
179
 */
180
function _elgg_create_notice_of_pending_upgrade($event, $type, $object) {
181
	if ($object instanceof \ElggUpgrade) {
182
		// Link to the Upgrades section
183
		$link = elgg_view('output/url', array(
184
			'href' => 'admin/upgrades',
185
			'text' => elgg_echo('admin:view_upgrades'),
186
		));
187
188
		$message = elgg_echo('admin:pending_upgrades');
189
190
		elgg_add_admin_notice('pending_upgrades', "$message $link");
191
	}
192
}
193
194
/**
195
 * Initialize the admin backend.
196
 * @return void
197
 * @access private
198
 */
199
function _elgg_admin_init() {
200
201
	elgg_register_event_handler('pagesetup', 'system', '_elgg_admin_pagesetup', 1000);
202
203
	// maintenance mode
204
	if (elgg_get_config('elgg_maintenance_mode', null)) {
205
		elgg_register_plugin_hook_handler('route', 'all', '_elgg_admin_maintenance_handler');
206
		elgg_register_plugin_hook_handler('action', 'all', '_elgg_admin_maintenance_action_check');
207
		elgg_register_css('maintenance', elgg_get_simplecache_url('css', 'maintenance'));
208
209
		elgg_register_menu_item('topbar', array(
210
			'name' => 'maintenance_mode',
211
			'href' => 'admin/administer_utilities/maintenance',
212
			'text' => elgg_echo('admin:maintenance_mode:indicator_menu_item'),
213
			'priority' => 900,
214
		));
215
	}
216
217
	elgg_register_action('admin/user/ban', '', 'admin');
218
	elgg_register_action('admin/user/unban', '', 'admin');
219
	elgg_register_action('admin/user/delete', '', 'admin');
220
	elgg_register_action('admin/user/resetpassword', '', 'admin');
221
	elgg_register_action('admin/user/makeadmin', '', 'admin');
222
	elgg_register_action('admin/user/removeadmin', '', 'admin');
223
224
	elgg_register_action('admin/site/update_basic', '', 'admin');
225
	elgg_register_action('admin/site/update_advanced', '', 'admin');
226
	elgg_register_action('admin/site/flush_cache', '', 'admin');
227
	elgg_register_action('admin/site/unlock_upgrade', '', 'admin');
228
	elgg_register_action('admin/site/set_robots', '', 'admin');
229
	elgg_register_action('admin/site/set_maintenance_mode', '', 'admin');
230
231
	elgg_register_action('admin/upgrades/upgrade_comments', '', 'admin');
232
	elgg_register_action('admin/upgrades/upgrade_datadirs', '', 'admin');
233
	elgg_register_action('admin/upgrades/upgrade_discussion_replies', '', 'admin');
234
	elgg_register_action('admin/upgrades/upgrade_comments_access', '', 'admin');
235
	elgg_register_action('admin/site/regenerate_secret', '', 'admin');
236
237
	elgg_register_action('admin/menu/save', '', 'admin');
238
239
	elgg_register_action('admin/delete_admin_notice', '', 'admin');
240
241
	elgg_register_action('profile/fields/reset', '', 'admin');
242
	elgg_register_action('profile/fields/add', '', 'admin');
243
	elgg_register_action('profile/fields/edit', '', 'admin');
244
	elgg_register_action('profile/fields/delete', '', 'admin');
245
	elgg_register_action('profile/fields/reorder', '', 'admin');
246
247
	elgg_register_simplecache_view('css/admin');
248
	$url = elgg_get_simplecache_url('js', 'admin');
249
	elgg_register_js('elgg.admin', $url);
250
	elgg_register_js('elgg.upgrades', 'js/lib/upgrades.js');
251
	elgg_register_js('jquery.jeditable', 'vendors/jquery/jquery.jeditable.mini.js');
252
253
	// administer
254
	// dashboard
255
	elgg_register_menu_item('page', array(
256
		'name' => 'dashboard',
257
		'href' => 'admin/dashboard',
258
		'text' => elgg_echo('admin:dashboard'),
259
		'context' => 'admin',
260
		'priority' => 10,
261
		'section' => 'administer'
262
	));
263
	// statistics
264
	elgg_register_admin_menu_item('administer', 'statistics', null, 20);
265
	elgg_register_admin_menu_item('administer', 'overview', 'statistics');
266
	elgg_register_admin_menu_item('administer', 'server', 'statistics');
267
	//utilities
268
	elgg_register_admin_menu_item('administer', 'maintenance', 'administer_utilities');
269
270
	// users
271
	elgg_register_admin_menu_item('administer', 'users', null, 20);
272
	elgg_register_admin_menu_item('administer', 'online', 'users', 10);
273
	elgg_register_admin_menu_item('administer', 'admins', 'users', 20);
274
	elgg_register_admin_menu_item('administer', 'newest', 'users', 30);
275
	elgg_register_admin_menu_item('administer', 'add', 'users', 40);
276
277
	// configure
278
	// upgrades
279
	elgg_register_menu_item('page', array(
280
		'name' => 'upgrades',
281
		'href' => 'admin/upgrades',
282
		'text' => elgg_echo('admin:upgrades'),
283
		'context' => 'admin',
284
		'priority' => 10,
285
		'section' => 'configure'
286
	));
287
288
	// plugins
289
	elgg_register_menu_item('page', array(
290
		'name' => 'plugins',
291
		'href' => 'admin/plugins',
292
		'text' => elgg_echo('admin:plugins'),
293
		'context' => 'admin',
294
		'priority' => 75,
295
		'section' => 'configure'
296
	));
297
298
	// settings
299
	elgg_register_admin_menu_item('configure', 'appearance', null, 50);
300
	elgg_register_admin_menu_item('configure', 'settings', null, 100);
301
	elgg_register_admin_menu_item('configure', 'basic', 'settings', 10);
302
	elgg_register_admin_menu_item('configure', 'advanced', 'settings', 20);
303
	// plugin settings are added in _elgg_admin_add_plugin_settings_menu() via the admin page handler
304
	// for performance reasons.
305
306
	// appearance
307
	elgg_register_admin_menu_item('configure', 'menu_items', 'appearance', 30);
308
	elgg_register_admin_menu_item('configure', 'profile_fields', 'appearance', 40);
309
	// default widgets is added via an event handler elgg_default_widgets_init() in widgets.php
310
	// because it requires additional setup.
311
312
	// configure utilities
313
	elgg_register_admin_menu_item('configure', 'robots', 'configure_utilities');
314
315
	// we want plugin settings menu items to be sorted alphabetical
316
	if (elgg_in_context('admin')) {
317
		elgg_register_plugin_hook_handler('prepare', 'menu:page', '_elgg_admin_sort_page_menu');
318
	}
319
320 View Code Duplication
	if (elgg_is_admin_logged_in()) {
321
		elgg_register_menu_item('topbar', array(
322
			'name' => 'administration',
323
			'href' => 'admin',
324
			'text' => elgg_view_icon('settings') . elgg_echo('admin'),
325
			'priority' => 100,
326
			'section' => 'alt',
327
		));
328
	}
329
330
	// widgets
331
	$widgets = array('online_users', 'new_users', 'content_stats', 'banned_users', 'admin_welcome', 'control_panel', 'cron_status');
332
	foreach ($widgets as $widget) {
333
		elgg_register_widget_type(
334
				$widget,
335
				elgg_echo("admin:widget:$widget"),
336
				elgg_echo("admin:widget:$widget:help"),
337
				array('admin')
338
		);
339
	}
340
341
	// automatic adding of widgets for admin
342
	elgg_register_event_handler('make_admin', 'user', '_elgg_add_admin_widgets');
343
344
	// Add notice about pending upgrades
345
	elgg_register_event_handler('create', 'object', '_elgg_create_notice_of_pending_upgrade');
346
347
	elgg_register_page_handler('admin', '_elgg_admin_page_handler');
348
	elgg_register_page_handler('admin_plugin_screenshot', '_elgg_admin_plugin_screenshot_page_handler');
349
	elgg_register_page_handler('admin_plugin_text_file', '_elgg_admin_markdown_page_handler');
350
	elgg_register_page_handler('robots.txt', '_elgg_robots_page_handler');
351
}
352
353
/**
354
 * Handles any set up required for administration pages
355
 *
356
 * @return void
357
 * @access private
358
 */
359
function _elgg_admin_pagesetup() {
360
	if (elgg_in_context('admin')) {
361
		$url = elgg_get_simplecache_url('css', 'admin');
362
		elgg_register_css('elgg.admin', $url);
363
		elgg_load_css('elgg.admin');
364
		elgg_unregister_css('elgg');
365
366
		$admin = elgg_get_logged_in_user_entity();
367
368
		// setup header menu
369
		elgg_register_menu_item('admin_header', array(
370
			'name' => 'admin_logout',
371
			'href' => 'action/logout',
372
			'text' => elgg_echo('logout'),
373
			'is_trusted' => true,
374
			'priority' => 1000,
375
		));
376
377
		elgg_register_menu_item('admin_header', array(
378
			'name' => 'view_site',
379
			'href' => elgg_get_site_url(),
380
			'text' => elgg_echo('admin:view_site'),
381
			'is_trusted' => true,
382
			'priority' => 900,
383
		));
384
385
		elgg_register_menu_item('admin_header', array(
386
			'name' => 'admin_profile',
387
			'href' => false,
388
			'text' => elgg_echo('admin:loggedin', array($admin->name)),
389
			'priority' => 800,
390
		));
391
392
		if (elgg_get_config('elgg_maintenance_mode', null)) {
393
			elgg_register_menu_item('admin_header', array(
394
				'name' => 'maintenance',
395
				'href' => 'admin/administer_utilities/maintenance',
396
				'text' => elgg_echo('admin:administer_utilities:maintenance'),
397
				'link_class' => 'elgg-maintenance-mode-warning',
398
				'priority' => 700,
399
			));
400
		}
401
402
		// setup footer menu
403
		elgg_register_menu_item('admin_footer', array(
404
			'name' => 'faq',
405
			'text' => elgg_echo('admin:footer:faq'),
406
			'href' => 'http://learn.elgg.org/en/stable/appendix/faqs.html',
407
		));
408
409
		elgg_register_menu_item('admin_footer', array(
410
			'name' => 'manual',
411
			'text' => elgg_echo('admin:footer:manual'),
412
			'href' => 'http://learn.elgg.org/en/stable/admin/index.html',
413
		));
414
415
		elgg_register_menu_item('admin_footer', array(
416
			'name' => 'community_forums',
417
			'text' => elgg_echo('admin:footer:community_forums'),
418
			'href' => 'http://community.elgg.org/groups/all/',
419
		));
420
421
		elgg_register_menu_item('admin_footer', array(
422
			'name' => 'blog',
423
			'text' => elgg_echo('admin:footer:blog'),
424
			'href' => 'https://community.elgg.org/blog/all',
425
		));
426
	}
427
}
428
429
/**
430
 * Create the plugin settings page menu.
431
 *
432
 * This is done in a separate function called from the admin
433
 * page handler because of performance concerns.
434
 *
435
 * @return void
436
 * @access private
437
 * @since 1.8.0
438
 */
439
function _elgg_admin_add_plugin_settings_menu() {
440
441
	$active_plugins = elgg_get_plugins('active');
442
	if (!$active_plugins) {
443
		// nothing added because no items
444
		return;
445
	}
446
447
	foreach ($active_plugins as $plugin) {
448
		$plugin_id = $plugin->getID();
449
		$settings_view_old = 'settings/' . $plugin_id . '/edit';
450
		$settings_view_new = 'plugins/' . $plugin_id . '/settings';
451
		if (elgg_view_exists($settings_view_new) || elgg_view_exists($settings_view_old)) {
452
			elgg_register_menu_item('page', array(
453
				'name' => $plugin_id,
454
				'href' => "admin/plugin_settings/$plugin_id",
455
				'text' => $plugin->getManifest()->getName(),
456
				'parent_name' => 'settings',
457
				'context' => 'admin',
458
				'section' => 'configure',
459
			));
460
		}
461
	}
462
}
463
464
/**
465
 * Sort the plugin settings menu items
466
 *
467
 * @param string $hook
468
 * @param string $type
469
 * @param array  $return
470
 * @param array  $params
471
 *
472
 * @return void
473
 * @since 1.8.0
474
 * @access private
475
 */
476
function _elgg_admin_sort_page_menu($hook, $type, $return, $params) {
477
	$configure_items = $return['configure'];
478
	if (is_array($configure_items)) {
479
		/* @var \ElggMenuItem[] $configure_items */
480
		foreach ($configure_items as $menu_item) {
481
			if ($menu_item->getName() == 'settings') {
482
				$settings = $menu_item;
483
			}
484
		}
485
486
		if (!empty($settings) && $settings instanceof \ElggMenuItem) {
487
			// keep the basic and advanced settings at the top
488
			/* @var \ElggMenuItem $settings */
489
			$children = $settings->getChildren();
490
			$site_settings = array_splice($children, 0, 2);
491
			usort($children, array('\ElggMenuBuilder', 'compareByText'));
492
			array_splice($children, 0, 0, $site_settings);
493
			$settings->setChildren($children);
494
		}
495
	}
496
}
497
498
/**
499
 * Handle admin pages.  Expects corresponding views as admin/section/subsection
500
 *
501
 * @param array $page Array of pages
502
 *
503
 * @return bool
504
 * @access private
505
 */
506
function _elgg_admin_page_handler($page) {
507
508
	elgg_admin_gatekeeper();
509
	_elgg_admin_add_plugin_settings_menu();
510
	elgg_set_context('admin');
511
512
	elgg_unregister_css('elgg');
513
	elgg_load_js('elgg.admin');
514
	elgg_load_js('jquery.jeditable');
515
516
	// default to dashboard
517
	if (!isset($page[0]) || empty($page[0])) {
518
		$page = array('dashboard');
519
	}
520
521
	// was going to fix this in the page_handler() function but
522
	// it's commented to explicitly return a string if there's a trailing /
523
	if (empty($page[count($page) - 1])) {
524
		array_pop($page);
525
	}
526
527
	$vars = array('page' => $page);
528
529
	// special page for plugin settings since we create the form for them
530
	if ($page[0] == 'plugin_settings') {
531
		if (isset($page[1]) && (elgg_view_exists("settings/{$page[1]}/edit") ||
532
			elgg_view_exists("plugins/{$page[1]}/settings"))) {
533
534
			$view = 'admin/plugin_settings';
535
			$plugin = elgg_get_plugin_from_id($page[1]);
536
			$vars['plugin'] = $plugin;
537
538
			$title = elgg_echo("admin:{$page[0]}");
539
		} else {
540
			forward('', '404');
541
		}
542
	} else {
543
		$view = 'admin/' . implode('/', $page);
544
		$title = elgg_echo("admin:{$page[0]}");
545
		if (count($page) > 1) {
546
			$title .= ' : ' . elgg_echo('admin:' .  implode(':', $page));
547
		}
548
	}
549
550
	// gets content and prevents direct access to 'components' views
551
	if ($page[0] == 'components' || !($content = elgg_view($view, $vars))) {
0 ignored issues
show
The variable $view does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
552
		$title = elgg_echo('admin:unknown_section');
553
		$content = elgg_echo('admin:unknown_section');
554
	}
555
556
	$body = elgg_view_layout('admin', array('content' => $content, 'title' => $title));
0 ignored issues
show
The variable $title does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
557
	echo elgg_view_page($title, $body, 'admin');
558
	return true;
559
}
560
561
/**
562
 * Serves up screenshots for plugins from
563
 * admin_plugin_screenshot/<plugin_id>/<size>/<ss_name>.<ext>
564
 *
565
 * @param array $pages The pages array
566
 * @return bool
567
 * @access private
568
 */
569
function _elgg_admin_plugin_screenshot_page_handler($pages) {
570
	// only admins can use this for security
571
	elgg_admin_gatekeeper();
572
573
	$plugin_id = elgg_extract(0, $pages);
574
	// only thumbnail or full.
575
	$size = elgg_extract(1, $pages, 'thumbnail');
576
577
	// the rest of the string is the filename
578
	$filename_parts = array_slice($pages, 2);
579
	$filename = implode('/', $filename_parts);
580
	$filename = sanitise_filepath($filename, false);
581
582
	$plugin = elgg_get_plugin_from_id($plugin_id);
583
	if (!$plugin) {
584
		$file = elgg_get_root_path() . '_graphics/icons/default/medium.png';
585
	} else {
586
		$file = $plugin->getPath() . $filename;
587
		if (!file_exists($file)) {
588
			$file = elgg_get_root_path() . '_graphics/icons/default/medium.png';
589
		}
590
	}
591
592
	header("Content-type: image/jpeg");
593
594
	// resize to 100x100 for thumbnails
595
	switch ($size) {
596
		case 'thumbnail':
597
			echo get_resized_image_from_existing_file($file, 100, 100, true);
598
			break;
599
600
		case 'full':
601
		default:
602
			echo file_get_contents($file);
603
			break;
604
	}
605
	return true;
606
}
607
608
/**
609
 * Formats and serves out markdown files from plugins.
610
 *
611
 * URLs in format like admin_plugin_text_file/<plugin_id>/filename.ext
612
 *
613
 * The only valid files are:
614
 *	* README.txt
615
 *	* CHANGES.txt
616
 *	* INSTALL.txt
617
 *	* COPYRIGHT.txt
618
 *	* LICENSE.txt
619
 *
620
 * @param array $pages
621
 * @return bool
622
 * @access private
623
 */
624
function _elgg_admin_markdown_page_handler($pages) {
625
	elgg_admin_gatekeeper();
626
	_elgg_admin_add_plugin_settings_menu();
627
	elgg_set_context('admin');
628
629
	elgg_unregister_css('elgg');
630
	elgg_load_js('elgg.admin');
631
	elgg_load_js('jquery.jeditable');
632
	elgg_load_library('elgg:markdown');
633
634
	$plugin_id = elgg_extract(0, $pages);
635
	$plugin = elgg_get_plugin_from_id($plugin_id);
636
	$filename = elgg_extract(1, $pages);
637
638
	$error = false;
639 View Code Duplication
	if (!$plugin) {
640
		$error = elgg_echo('admin:plugins:markdown:unknown_plugin');
641
		$body = elgg_view_layout('admin', array('content' => $error, 'title' => $error));
642
		echo elgg_view_page($error, $body, 'admin');
643
		return true;
644
	}
645
646
	$text_files = $plugin->getAvailableTextFiles();
647
648
	if (!array_key_exists($filename, $text_files)) {
649
		$error = elgg_echo('admin:plugins:markdown:unknown_file');
650
	}
651
652
	$file = $text_files[$filename];
653
	$file_contents = file_get_contents($file);
654
655
	if (!$file_contents) {
656
		$error = elgg_echo('admin:plugins:markdown:unknown_file');
657
	}
658
659 View Code Duplication
	if ($error) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $error of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
660
		$title = $error;
661
		$body = elgg_view_layout('admin', array('content' => $error, 'title' => $title));
662
		echo elgg_view_page($title, $body, 'admin');
663
		return true;
664
	}
665
666
	$title = $plugin->getManifest()->getName() . ": $filename";
667
	$text = Markdown($file_contents);
668
669
	$body = elgg_view_layout('admin', array(
670
		// setting classes here because there's no way to pass classes
671
		// to the layout
672
		'content' => '<div class="elgg-markdown">' . $text . '</div>',
673
		'title' => $title
674
	));
675
676
	echo elgg_view_page($title, $body, 'admin');
677
	return true;
678
}
679
680
/**
681
 * Handle request for robots.txt
682
 *
683
 * @access private
684
 */
685
function _elgg_robots_page_handler() {
686
	$site = elgg_get_site_entity();
687
	header("Content-type: text/plain;charset=utf-8");
688
	$content = $site->getPrivateSetting('robots.txt');
689
	$plugin_content = elgg_trigger_plugin_hook('robots.txt', 'site', array('site' => $site), '');
690
	if ($plugin_content) {
691
		$content = $content . "\n\n" . $plugin_content;
692
	}
693
	echo $content;
694
695
	return true;
696
}
697
698
/**
699
 * When in maintenance mode, should the given URL be handled normally?
700
 *
701
 * @param string $current_url Current page URL
702
 * @return bool
703
 *
704
 * @access private
705
 */
706
function _elgg_admin_maintenance_allow_url($current_url) {
707
	$site_path = preg_replace('~^https?~', '', elgg_get_site_url());
708
	$current_path = preg_replace('~^https?~', '', $current_url);
709
	if (0 === strpos($current_path, $site_path)) {
710
		$current_path = ($current_path === $site_path) ? '' : substr($current_path, strlen($site_path));
711
	} else {
712
		$current_path = false;
713
	}
714
715
	// allow plugins to control access for specific URLs/paths
716
	$params = array(
717
		'current_path' => $current_path,
718
		'current_url' => $current_url,
719
	);
720
	return (bool)elgg_trigger_plugin_hook('maintenance:allow', 'url', $params, false);
721
}
722
723
/**
724
 * Handle requests when in maintenance mode
725
 *
726
 * @access private
727
 */
728
function _elgg_admin_maintenance_handler($hook, $type, $info) {
729
	if (elgg_is_admin_logged_in()) {
730
		return;
731
	}
732
733
	if ($info['identifier'] == 'action' && $info['segments'][0] == 'login') {
734
		return;
735
	}
736
737
	if (_elgg_admin_maintenance_allow_url(current_page_url())) {
738
		return;
739
	}
740
741
	elgg_unregister_plugin_hook_handler('register', 'menu:login', '_elgg_login_menu_setup');
742
743
	$site = elgg_get_site_entity();
744
	$message = $site->getPrivateSetting('elgg_maintenance_message');
745
	if (!$message) {
746
		$message = elgg_echo('admin:maintenance_mode:default_message');
747
	}
748
749
	elgg_load_css('maintenance');
750
751
	header("HTTP/1.1 503 Service Unavailable");
752
753
	$body = elgg_view_layout('maintenance', array(
754
		'message' => $message,
755
		'site' => $site,
756
	));
757
	echo elgg_view_page($site->name, $body, 'maintenance');
758
759
	return false;
760
}
761
762
/**
763
 * Prevent non-admins from using actions
764
 *
765
 * @access private
766
 *
767
 * @param string $hook Hook name
768
 * @param string $type Action name
769
 * @return bool
770
 */
771
function _elgg_admin_maintenance_action_check($hook, $type) {
772
	if (elgg_is_admin_logged_in()) {
773
		return true;
774
	}
775
776
	if ($type == 'login') {
777
		$username = get_input('username');
778
779
		$user = get_user_by_username($username);
780
781
		if (!$user) {
782
			$users = get_user_by_email($username);
783
			if ($users) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $users 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...
784
				$user = $users[0];
785
			}
786
		}
787
788
		if ($user && $user->isAdmin()) {
789
			return true;
790
		}
791
	}
792
793
	if (_elgg_admin_maintenance_allow_url(current_page_url())) {
794
		return true;
795
	}
796
797
	register_error(elgg_echo('actionunauthorized'));
798
799
	return false;
800
}
801
802
/**
803
 * Adds default admin widgets to the admin dashboard.
804
 *
805
 * @param string $event
806
 * @param string $type
807
 * @param \ElggUser $user
808
 *
809
 * @return null|true
810
 * @access private
811
 */
812
function _elgg_add_admin_widgets($event, $type, $user) {
813
	elgg_set_ignore_access(true);
814
815
	// check if the user already has widgets
816
	if (elgg_get_widgets($user->getGUID(), 'admin')) {
817
		return true;
818
	}
819
820
	// In the form column => array of handlers in order, top to bottom
821
	$adminWidgets = array(
822
		1 => array('control_panel', 'admin_welcome'),
823
		2 => array('online_users', 'new_users', 'content_stats'),
824
	);
825
826 View Code Duplication
	foreach ($adminWidgets as $column => $handlers) {
827
		foreach ($handlers as $position => $handler) {
828
			$guid = elgg_create_widget($user->getGUID(), $handler, 'admin');
829
			if ($guid) {
830
				$widget = get_entity($guid);
831
				/* @var \ElggWidget $widget */
832
				$widget->move($column, $position);
833
			}
834
		}
835
	}
836
	elgg_set_ignore_access(false);
837
}
838
839
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
840
	$events->registerHandler('init', 'system', '_elgg_admin_init');
841
};
842