Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

_elgg_admin_header_menu()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 43
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 29
nc 3
nop 4
dl 0
loc 43
ccs 0
cts 29
cp 0
crap 20
rs 8.5806
c 0
b 0
f 0
1
<?php
2
/**
3
 * Elgg admin functions.
4
 *
5
 * Admin pages
6
 * Plugins no not need to provide their own page handler to add a page to the
7
 * admin area. A view placed at admin/<section>/<subsection> can be access
8
 * at http://example.org/admin/<section>/<subsection>. The title of the page
9
 * will be elgg_echo('admin:<section>:<subsection>'). For an example of how to
10
 * add a page to the admin area, see the diagnostics plugin.
11
 *
12
 * Admin notices
13
 * System messages (success and error messages) are used in both the main site
14
 * and the admin area. There is a special presistent message for the admin area
15
 * called an admin notice. It should be used when a plugin requires an
16
 * administrator to take an action. @see elgg_add_admin_notice()
17
 *
18
 *
19
 * @package Elgg.Core
20
 * @subpackage Admin
21
 */
22
23
/**
24
 * Get the admin users
25
 *
26
 * @param array $options Options array, @see elgg_get_entities() for parameters
27
 *
28
 * @return mixed Array of admin users or false on failure. If a count, returns int.
29
 * @since 1.8.0
30
 */
31
function elgg_get_admins(array $options = []) {
32 311
	$options['type'] = 'user';
33 311
	$options['metadata_name_value_pairs'] = elgg_extract('metadata_name_value_pairs', $options, []);
34
	
35 311
	$options['metadata_name_value_pairs']['admin'] = 'yes';
36
37 311
	return elgg_get_entities($options);
38
}
39
40
/**
41
 * Write a persistent message to the admin view.
42
 * Useful to alert the admin to take a certain action.
43
 * The id is a unique ID that can be cleared once the admin
44
 * completes the action.
45
 *
46
 * eg: add_admin_notice('twitter_services_no_api',
47
 * 	'Before your users can use Twitter services on this site, you must set up
48
 * 	the Twitter API key in the <a href="link">Twitter Services Settings</a>');
49
 *
50
 * @param string $id      A unique ID that your plugin can remember
51
 * @param string $message Body of the message
52
 *
53
 * @return ElggObject|bool
54
 * @since 1.8.0
55
 */
56
function elgg_add_admin_notice($id, $message) {
57 2
	return _elgg_services()->adminNotices->add($id, $message);
58
}
59
60
/**
61
 * Remove an admin notice by ID.
62
 *
63
 * @param string $id The unique ID assigned in add_admin_notice()
64
 *
65
 * @return bool
66
 * @since 1.8.0
67
 */
68
function elgg_delete_admin_notice($id) {
69 1
	return _elgg_services()->adminNotices->delete($id);
70
}
71
72
/**
73
 * Get admin notices. An admin must be logged in since the notices are private.
74
 *
75
 * @param array $options Query options
76
 *
77
 * @return ElggObject[] Admin notices
78
 * @since 1.8.0
79
 */
80
function elgg_get_admin_notices(array $options = []) {
81 1
	return _elgg_services()->adminNotices->find($options);
82
}
83
84
/**
85
 * Check if an admin notice is currently active. (Ignores access)
86
 *
87
 * @param string $id The unique ID used to register the notice.
88
 *
89
 * @return bool
90
 * @since 1.8.0
91
 */
92
function elgg_admin_notice_exists($id) {
93 2
	return _elgg_services()->adminNotices->exists($id);
94
}
95
96
/**
97
 * Add an admin notice when a new \ElggUpgrade object is created.
98
 *
99
 * @param string      $event  'create'
100
 * @param string      $type   'object'
101
 * @param \ElggObject $object the created object
102
 *
103
 * @return void
104
 *
105
 * @access private
106
 */
107
function _elgg_create_notice_of_pending_upgrade($event, $type, $object) {
108 199
	if (!$object instanceof \ElggUpgrade) {
109 199
		return;
110
	}
111
	
112
	// Link to the Upgrades section
113
	$link = elgg_view('output/url', [
114
		'href' => 'admin/upgrades',
115
		'text' => elgg_echo('admin:view_upgrades'),
116
	]);
117
118
	$message = elgg_echo('admin:pending_upgrades');
119
120
	elgg_add_admin_notice('pending_upgrades', "$message $link");
121
}
122
123
/**
124
 * Initialize the admin backend.
125
 * @return void
126
 * @access private
127
 */
128
function _elgg_admin_init() {
129
130 31
	elgg_register_css('elgg.admin', elgg_get_simplecache_url('admin.css'));
131
132 31
	elgg_extend_view('admin.css', 'lightbox/elgg-colorbox-theme/colorbox.css');
133
		
134 31
	elgg_register_plugin_hook_handler('register', 'menu:admin_header', '_elgg_admin_header_menu');
135 31
	elgg_register_plugin_hook_handler('register', 'menu:admin_footer', '_elgg_admin_footer_menu');
136 31
	elgg_register_plugin_hook_handler('register', 'menu:page', '_elgg_admin_page_menu');
137 31
	elgg_register_plugin_hook_handler('register', 'menu:page', '_elgg_admin_page_menu_plugin_settings');
138
139
	// maintenance mode
140 31
	if (elgg_get_config('elgg_maintenance_mode', null)) {
141
		elgg_register_plugin_hook_handler('route', 'all', '_elgg_admin_maintenance_handler', 600);
142
		elgg_register_plugin_hook_handler('action', 'all', '_elgg_admin_maintenance_action_check', 600);
143
		elgg_register_css('maintenance', elgg_get_simplecache_url('maintenance.css'));
144
145
		elgg_register_menu_item('topbar', [
146
			'name' => 'maintenance_mode',
147
			'href' => 'admin/configure_utilities/maintenance',
148
			'text' => elgg_echo('admin:maintenance_mode:indicator_menu_item'),
149
			'icon' => 'wrench',
150
			'priority' => 900,
151
		]);
152
	}
153
154 31
	elgg_register_action('admin/user/ban', '', 'admin');
155 31
	elgg_register_action('admin/user/unban', '', 'admin');
156 31
	elgg_register_action('admin/user/delete', '', 'admin');
157 31
	elgg_register_action('admin/user/resetpassword', '', 'admin');
158 31
	elgg_register_action('admin/user/makeadmin', '', 'admin');
159 31
	elgg_register_action('admin/user/removeadmin', '', 'admin');
160
161 31
	elgg_register_action('admin/site/update_basic', '', 'admin');
162 31
	elgg_register_action('admin/site/update_advanced', '', 'admin');
163 31
	elgg_register_action('admin/site/flush_cache', '', 'admin');
164 31
	elgg_register_action('admin/site/unlock_upgrade', '', 'admin');
165 31
	elgg_register_action('admin/site/set_robots', '', 'admin');
166 31
	elgg_register_action('admin/site/set_maintenance_mode', '', 'admin');
167
168 31
	elgg_register_action('admin/upgrades/upgrade_database_guid_columns', '', 'admin');
169 31
	elgg_register_action('admin/upgrade', '', 'admin');
170
171 31
	elgg_register_action('admin/menu/save', '', 'admin');
172
173 31
	elgg_register_action('admin/delete_admin_notice', '', 'admin');
174 31
	elgg_register_action('admin/delete_admin_notices', '', 'admin');
175
	
176 31
	elgg_register_action('admin/security/settings', '', 'admin');
177 31
	elgg_register_action('admin/security/regenerate_site_secret', '', 'admin');
178
	
179 31
	elgg_register_simplecache_view('admin.css');
180
181
	// widgets
182 31
	$widgets = ['online_users', 'new_users', 'content_stats', 'banned_users', 'admin_welcome', 'control_panel', 'cron_status'];
183 31
	foreach ($widgets as $widget) {
184 31
		elgg_register_widget_type(
185 31
				$widget,
186 31
				elgg_echo("admin:widget:$widget"),
187 31
				elgg_echo("admin:widget:$widget:help"),
188 31
				['admin']
189
		);
190
	}
191
192
	// automatic adding of widgets for admin
193 31
	elgg_register_event_handler('make_admin', 'user', '_elgg_add_admin_widgets');
194
	
195 31
	elgg_register_notification_event('user', '', ['make_admin', 'remove_admin']);
196 31
	elgg_register_plugin_hook_handler('get', 'subscriptions', '_elgg_admin_get_admin_subscribers_admin_action');
197 31
	elgg_register_plugin_hook_handler('get', 'subscriptions', '_elgg_admin_get_user_subscriber_admin_action');
198 31
	elgg_register_plugin_hook_handler('prepare', 'notification:make_admin:user:', '_elgg_admin_prepare_admin_notification_make_admin');
199 31
	elgg_register_plugin_hook_handler('prepare', 'notification:make_admin:user:', '_elgg_admin_prepare_user_notification_make_admin');
200 31
	elgg_register_plugin_hook_handler('prepare', 'notification:remove_admin:user:', '_elgg_admin_prepare_admin_notification_remove_admin');
201 31
	elgg_register_plugin_hook_handler('prepare', 'notification:remove_admin:user:', '_elgg_admin_prepare_user_notification_remove_admin');
202
	
203
	// Add notice about pending upgrades
204 31
	elgg_register_event_handler('create', 'object', '_elgg_create_notice_of_pending_upgrade');
205
206 31
	elgg_register_page_handler('admin', '_elgg_admin_page_handler');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

206
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('admin', '_elgg_admin_page_handler');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
207 31
	elgg_register_page_handler('admin_plugin_text_file', '_elgg_admin_markdown_page_handler');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

207
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('admin_plugin_text_file', '_elgg_admin_markdown_page_handler');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
208 31
	elgg_register_page_handler('robots.txt', '_elgg_robots_page_handler');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

208
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('robots.txt', '_elgg_robots_page_handler');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
209 31
	elgg_register_page_handler('phpinfo', '_elgg_phpinfo_page_handler');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

209
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('phpinfo', '_elgg_phpinfo_page_handler');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
210 31
	elgg_register_page_handler('admin_plugins_refresh', '_elgg_ajax_plugins_update');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

210
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('admin_plugins_refresh', '_elgg_ajax_plugins_update');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
211 31
}
212
213
/**
214
 * Returns plugin listing and admin menu to the client (used after plugin (de)activation)
215
 *
216
 * @access private
217
 * @return Elgg\Http\OkResponse
218
 */
219
function _elgg_ajax_plugins_update() {
220
	elgg_admin_gatekeeper();
221
	elgg_set_context('admin');
222
223
	return elgg_ok_response([
224
		'list' => elgg_view('admin/plugins', ['list_only' => true]),
225
		'sidebar' => elgg_view('admin/sidebar'),
226
	]);
227
}
228
229
/**
230
 * Register menu items for the admin_header menu
231
 *
232
 * @param string          $hook   'register'
233
 * @param string          $type   'menu:admin_header'
234
 * @param \ElggMenuItem[] $return current return value
235
 * @param array           $params supplied params
236
 *
237
 * @return void|\ElggMenuItem
238
 *
239
 * @access private
240
 * @since 3.0
241
 */
242
function _elgg_admin_header_menu($hook, $type, $return, $params) {
243
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
244
		return;
245
	}
246
247
	$admin = elgg_get_logged_in_user_entity();
248
249
	$return[] = \ElggMenuItem::factory([
250
		'name' => 'account',
251
		'text' => $admin->getDisplayName(),
252
		'href' => $admin->getURL(),
253
		'icon' => elgg_view('output/img', [
254
			'src' => $admin->getIconURL('small'),
255
			'alt' => $admin->getDisplayName(),
256
		]),
257
		'priority' => 1000,
258
	]);
259
260
	$return[] = \ElggMenuItem::factory([
261
		'name' => 'admin_logout',
262
		'href' => 'action/logout',
263
		'text' => elgg_echo('logout'),
264
		'priority' => 900,
265
	]);
266
267
	$return[] = \ElggMenuItem::factory([
268
		'name' => 'view_site',
269
		'href' => elgg_get_site_url(),
270
		'text' => elgg_echo('admin:view_site'),
271
		'priority' => 800,
272
	]);
273
274
	if (elgg_get_config('elgg_maintenance_mode')) {
275
		$return[] = \ElggMenuItem::factory([
276
			'name' => 'maintenance',
277
			'href' => 'admin/configure_utilities/maintenance',
278
			'text' => elgg_echo('admin:configure_utilities:maintenance'),
279
			'link_class' => 'elgg-maintenance-mode-warning',
280
			'priority' => 700,
281
		]);
282
	}
283
	
284
	return $return;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return returns the type ElggMenuItem[] which is incompatible with the documented return type ElggMenuItem.
Loading history...
285
}
286
287
/**
288
 * Register menu items for the admin_footer menu
289
 *
290
 * @param string          $hook   'register'
291
 * @param string          $type   'menu:admin_footer'
292
 * @param \ElggMenuItem[] $return current return value
293
 * @param array           $params supplied params
294
 *
295
 * @return void|\ElggMenuItem[]
296
 *
297
 * @access private
298
 * @since 3.0
299
 */
300
function _elgg_admin_footer_menu($hook, $type, $return, $params) {
301
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
302
		return;
303
	}
304
305
	$return[] = \ElggMenuItem::factory([
306
		'name' => 'faq',
307
		'text' => elgg_echo('admin:footer:faq'),
308
		'href' => 'http://learn.elgg.org/en/stable/appendix/faqs.html',
309
	]);
310
311
	$return[] = \ElggMenuItem::factory([
312
		'name' => 'manual',
313
		'text' => elgg_echo('admin:footer:manual'),
314
		'href' => 'http://learn.elgg.org/en/stable/admin/index.html',
315
	]);
316
317
	$return[] = \ElggMenuItem::factory([
318
		'name' => 'community_forums',
319
		'text' => elgg_echo('admin:footer:community_forums'),
320
		'href' => 'http://elgg.org/groups/all/',
321
	]);
322
323
	$return[] = \ElggMenuItem::factory([
324
		'name' => 'blog',
325
		'text' => elgg_echo('admin:footer:blog'),
326
		'href' => 'https://elgg.org/blog/all',
327
	]);
328
	
329
	return $return;
330
}
331
332
/**
333
 * Register menu items for the page menu
334
 *
335
 * @param \Elgg\Hook $hook 'register' 'menu:page'
336
 * @return array
337
 *
338
 * @access private
339
 * @see _elgg_default_widgets_init() for default widgets menu items setup
340
 * @since 3.0
341
 */
342
function _elgg_admin_page_menu(\Elgg\Hook $hook) {
343 1
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
344 1
		return;
345
	}
346
	
347
	$return = $hook->getValue();
348
349
	// administer
350
	$return[] = \ElggMenuItem::factory([
351
		'name' => 'dashboard',
352
		'href' => 'admin',
353
		'text' => elgg_echo('admin:dashboard'),
354
		'priority' => 10,
355
		'section' => 'administer',
356
	]);
357
	
358
	$return[] = \ElggMenuItem::factory([
359
		'name' => 'plugins',
360
		'href' => 'admin/plugins',
361
		'text' => elgg_echo('admin:plugins'),
362
		'priority' => 30,
363
		'section' => 'administer',
364
	]);
365
366
	$return[] = \ElggMenuItem::factory([
367
		'name' => 'users',
368
		'text' => elgg_echo('admin:users'),
369
		'priority' => 40,
370
		'section' => 'administer',
371
	]);
372
	$return[] = \ElggMenuItem::factory([
373
		'name' => 'users:online',
374
		'text' => elgg_echo('admin:users:online'),
375
		'href' => 'admin/users/online',
376
		'priority' => 10,
377
		'section' => 'administer',
378
		'parent_name' => 'users',
379
	]);
380
	$return[] = \ElggMenuItem::factory([
381
		'name' => 'users:admins',
382
		'text' => elgg_echo('admin:users:admins'),
383
		'href' => 'admin/users/admins',
384
		'priority' => 20,
385
		'section' => 'administer',
386
		'parent_name' => 'users',
387
	]);
388
	$return[] = \ElggMenuItem::factory([
389
		'name' => 'users:newest',
390
		'text' => elgg_echo('admin:users:newest'),
391
		'href' => 'admin/users/newest',
392
		'priority' => 30,
393
		'section' => 'administer',
394
		'parent_name' => 'users',
395
	]);
396
	$return[] = \ElggMenuItem::factory([
397
		'name' => 'users:add',
398
		'text' => elgg_echo('admin:users:add'),
399
		'href' => 'admin/users/add',
400
		'priority' => 40,
401
		'section' => 'administer',
402
		'parent_name' => 'users',
403
	]);
404
	$return[] = \ElggMenuItem::factory([
405
		'name' => 'upgrades',
406
		'href' => 'admin/upgrades',
407
		'text' => elgg_echo('admin:upgrades'),
408
		'priority' => 600,
409
		'section' => 'administer',
410
	]);
411
	
412
	$return[] = \ElggMenuItem::factory([
413
		'name' => 'administer_utilities',
414
		'text' => elgg_echo('admin:administer_utilities'),
415
		'priority' => 50,
416
		'section' => 'administer',
417
	]);
418
	
419
	// configure
420
	$return[] = \ElggMenuItem::factory([
421
		'name' => 'settings:basic',
422
		'href' => 'admin/settings/basic',
423
		'text' => elgg_echo('admin:settings:basic'),
424
		'priority' => 10,
425
		'section' => 'configure',
426
	]);
427
	$return[] = \ElggMenuItem::factory([
428
		'name' => 'settings:advanced',
429
		'href' => 'admin/settings/advanced',
430
		'text' => elgg_echo('admin:settings:advanced'),
431
		'priority' => 20,
432
		'section' => 'configure',
433
	]);
434
	$return[] = \ElggMenuItem::factory([
435
		'name' => 'security',
436
		'href' => 'admin/security',
437
		'text' => elgg_echo('admin:security'),
438
		'priority' => 30,
439
		'section' => 'configure',
440
	]);
441
442
	$return[] = \ElggMenuItem::factory([
443
		'name' => 'configure_utilities',
444
		'text' => elgg_echo('admin:configure_utilities'),
445
		'priority' => 600,
446
		'section' => 'configure',
447
	]);
448
	$return[] = \ElggMenuItem::factory([
449
		'name' => 'configure_utilities:maintenance',
450
		'text' => elgg_echo('admin:configure_utilities:maintenance'),
451
		'href' => 'admin/configure_utilities/maintenance',
452
		'section' => 'configure',
453
		'parent_name' => 'configure_utilities',
454
	]);
455
	$return[] = \ElggMenuItem::factory([
456
		'name' => 'configure_utilities:menu_items',
457
		'text' => elgg_echo('admin:configure_utilities:menu_items'),
458
		'href' => 'admin/configure_utilities/menu_items',
459
		'section' => 'configure',
460
		'parent_name' => 'configure_utilities',
461
	]);
462
	$return[] = \ElggMenuItem::factory([
463
		'name' => 'configure_utilities:robots',
464
		'text' => elgg_echo('admin:configure_utilities:robots'),
465
		'href' => 'admin/configure_utilities/robots',
466
		'section' => 'configure',
467
		'parent_name' => 'configure_utilities',
468
	]);
469
	
470
	// information
471
	$return[] = \ElggMenuItem::factory([
472
		'name' => 'statistics',
473
		'href' => 'admin/statistics',
474
		'text' => elgg_echo('admin:statistics'),
475
		'section' => 'information',
476
	]);
477
	$return[] = \ElggMenuItem::factory([
478
		'name' => 'server',
479
		'href' => 'admin/server',
480
		'text' => elgg_echo('admin:server'),
481
		'section' => 'information',
482
	]);
483
		
484
	return $return;
485
}
486
487
/**
488
 * Register plugin settings menu items for the admin page menu
489
 *
490
 * @note Plugin settings are alphabetically sorted in the submenu
491
 *
492
 * @param \Elgg\Hook $hook 'register' 'menu:page'
493
 * @return array
494
 *
495
 * @access private
496
 * @since 3.0
497
 */
498
function _elgg_admin_page_menu_plugin_settings(\Elgg\Hook $hook) {
499 1
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
500 1
		return;
501
	}
502
	
503
	// plugin settings
504
	$active_plugins = elgg_get_plugins('active');
505
	if (!$active_plugins) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $active_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...
506
		// nothing added because no items
507
		return;
508
	}
509
	
510
	$plugins_with_settings = [];
511
	
512
	foreach ($active_plugins as $plugin) {
513
		$plugin_id = $plugin->getID();
514
		
515
		if (!elgg_view_exists("plugins/{$plugin_id}/settings") ) {
516
			continue;
517
		}
518
		$plugin_name = $plugin->getDisplayName();
519
		$plugins_with_settings[$plugin_name] = [
520
			'name' => $plugin_id,
521
			'href' => "admin/plugin_settings/$plugin_id",
522
			'text' => $plugin_name,
523
			'parent_name' => 'plugin_settings',
524
			'section' => 'configure',
525
		];
526
	}
527
	
528
	if (empty($plugins_with_settings)) {
529
		return;
530
	}
531
532
	$return = $hook->getValue();
533
	
534
	$return[] = \ElggMenuItem::factory([
535
		'name' => 'plugin_settings',
536
		'text' => elgg_echo('admin:plugin_settings'),
537
		'section' => 'configure',
538
	]);
539
	
540
	ksort($plugins_with_settings);
541
	$priority = 0;
542
	foreach ($plugins_with_settings as $plugin_item) {
543
		$priority += 10;
544
		$plugin_item['priority'] = $priority;
545
		$return[] = \ElggMenuItem::factory($plugin_item);
546
	}
547
	
548
	return $return;
549
}
550
551
/**
552
 * Handle admin pages.  Expects corresponding views as admin/section/subsection
553
 *
554
 * @param array $page Array of pages
555
 *
556
 * @return bool
557
 * @access private
558
 */
559
function _elgg_admin_page_handler($page) {
560
	elgg_admin_gatekeeper();
561
	elgg_set_context('admin');
562
563
	elgg_unregister_css('elgg');
564
	elgg_require_js('elgg/admin');
565
566
	// default to dashboard
567
	if (!isset($page[0]) || empty($page[0])) {
568
		$page = ['dashboard'];
569
	}
570
571
	// was going to fix this in the page_handler() function but
572
	// it's commented to explicitly return a string if there's a trailing /
573
	if (empty($page[count($page) - 1])) {
574
		array_pop($page);
575
	}
576
577
	$vars = ['page' => $page];
578
579
	// special page for plugin settings since we create the form for them
580
	if ($page[0] == 'plugin_settings') {
581
		if (isset($page[1]) && (elgg_view_exists("plugins/{$page[1]}/settings"))) {
582
			$view = 'admin/plugin_settings';
583
			$plugin = elgg_get_plugin_from_id($page[1]);
584
			$vars['plugin'] = $plugin;
585
586
			$title = elgg_echo("admin:{$page[0]}");
587
		} else {
588
			forward('', '404');
589
		}
590
	} else {
591
		$view = 'admin/' . implode('/', $page);
592
		$title = elgg_echo("admin:{$page[0]}");
593
		if (count($page) > 1) {
594
			$title .= ' : ' . elgg_echo('admin:' .  implode(':', $page));
595
		}
596
	}
597
598
	// gets content and prevents direct access to 'components' views
599
	if ($page[0] == 'components' || !($content = elgg_view($view, $vars))) {
1 ignored issue
show
Comprehensibility Best Practice introduced by
The variable $view does not seem to be defined for all execution paths leading up to this point.
Loading history...
600
		$title = elgg_echo('admin:unknown_section');
601
		$content = elgg_echo('admin:unknown_section');
602
	}
603
604
	$body = elgg_view_layout('admin', ['content' => $content, 'title' => $title]);
1 ignored issue
show
Comprehensibility Best Practice introduced by
The variable $title does not seem to be defined for all execution paths leading up to this point.
Loading history...
605
	echo elgg_view_page($title, $body, 'admin');
606
	return true;
607
}
608
609
/**
610
 * Formats and serves out markdown files from plugins.
611
 *
612
 * URLs in format like admin_plugin_text_file/<plugin_id>/filename.ext
613
 *
614
 * The only valid files are:
615
 *	* README.txt
616
 *	* CHANGES.txt
617
 *	* INSTALL.txt
618
 *	* COPYRIGHT.txt
619
 *	* LICENSE.txt
620
 *
621
 * @param array $pages URL segments
622
 * @return bool
623
 * @access private
624
 */
625
function _elgg_admin_markdown_page_handler($pages) {
626
	elgg_set_context('admin');
627
628
	echo elgg_view_resource('admin/plugin_text_file', [
629
		'plugin_id' => elgg_extract(0, $pages),
630
		'filename' => elgg_extract(1, $pages),
631
	]);
632
	return true;
633
}
634
635
/**
636
 * Handle request for robots.txt
637
 *
638
 * @return true
639
 *
640
 * @access private
641
 */
642
function _elgg_robots_page_handler() {
643
	echo elgg_view_resource('robots.txt');
644
	return true;
645
}
646
647
/**
648
 * Handle request for phpinfo
649
 *
650
 * @return true
651
 *
652
 * @access private
653
 */
654
function _elgg_phpinfo_page_handler() {
655
	echo elgg_view_resource('phpinfo');
656
	return true;
657
}
658
659
/**
660
 * When in maintenance mode, should the given URL be handled normally?
661
 *
662
 * @param string $current_url Current page URL
663
 * @return bool
664
 *
665
 * @access private
666
 */
667
function _elgg_admin_maintenance_allow_url($current_url) {
668
	$site_path = preg_replace('~^https?~', '', elgg_get_site_url());
669
	$current_path = preg_replace('~^https?~', '', $current_url);
670
	if (0 === strpos($current_path, $site_path)) {
671
		$current_path = ($current_path === $site_path) ? '' : substr($current_path, strlen($site_path));
672
	} else {
673
		$current_path = false;
674
	}
675
676
	// allow plugins to control access for specific URLs/paths
677
	$params = [
678
		'current_path' => $current_path,
679
		'current_url' => $current_url,
680
	];
681
	return (bool) elgg_trigger_plugin_hook('maintenance:allow', 'url', $params, false);
682
}
683
684
/**
685
 * Handle requests when in maintenance mode
686
 *
687
 * @param string $hook 'route'
688
 * @param string $type 'all'
689
 * @param array  $info current return value
690
 *
691
 * @return void|false
692
 *
693
 * @access private
694
 */
695
function _elgg_admin_maintenance_handler($hook, $type, $info) {
696
	if (elgg_is_admin_logged_in()) {
697
		return;
698
	}
699
700
	if ($info['identifier'] == 'action' && $info['segments'][0] == 'login') {
701
		return;
702
	}
703
704
	if (_elgg_admin_maintenance_allow_url(current_page_url())) {
705
		return;
706
	}
707
708
	elgg_unregister_plugin_hook_handler('register', 'menu:login', '_elgg_login_menu_setup');
709
710
	echo elgg_view_resource('maintenance');
711
712
	return false;
713
}
714
715
/**
716
 * Prevent non-admins from using actions
717
 *
718
 * @access private
719
 *
720
 * @param string $hook Hook name
721
 * @param string $type Action name
722
 * @return bool
723
 */
724
function _elgg_admin_maintenance_action_check($hook, $type) {
725
	if (elgg_is_admin_logged_in()) {
726
		return true;
727
	}
728
729
	if ($type == 'login') {
730
		$username = get_input('username');
731
732
		$user = get_user_by_username($username);
733
734
		if (!$user) {
735
			$users = get_user_by_email($username);
736
			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...
737
				$user = $users[0];
738
			}
739
		}
740
741
		if ($user && $user->isAdmin()) {
742
			return true;
743
		}
744
	}
745
746
	if (_elgg_admin_maintenance_allow_url(current_page_url())) {
747
		return true;
748
	}
749
750
	register_error(elgg_echo('actionunauthorized'));
751
752
	return false;
753
}
754
755
/**
756
 * Adds default admin widgets to the admin dashboard.
757
 *
758
 * @param string    $event 'make_admin'
759
 * @param string    $type  'user'
760
 * @param \ElggUser $user  affected user
761
 *
762
 * @return void
763
 * @access private
764
 */
765
function _elgg_add_admin_widgets($event, $type, $user) {
766 6
	$ia = elgg_set_ignore_access(true);
767
768
	// check if the user already has widgets
769 6
	if (elgg_get_widgets($user->getGUID(), 'admin')) {
770
		elgg_set_ignore_access($ia);
771
		return;
772
	}
773
774
	// In the form column => array of handlers in order, top to bottom
775
	$adminWidgets = [
776 6
		1 => ['control_panel', 'admin_welcome'],
777
		2 => ['online_users', 'new_users', 'content_stats'],
778
	];
779
780 6
	foreach ($adminWidgets as $column => $handlers) {
781 6
		foreach ($handlers as $position => $handler) {
782 6
			$guid = elgg_create_widget($user->getGUID(), $handler, 'admin');
783 6
			if ($guid) {
784 6
				$widget = get_entity($guid);
785
				/* @var \ElggWidget $widget */
786 6
				$widget->move($column, $position);
787
			}
788
		}
789
	}
790
	
791 6
	elgg_set_ignore_access($ia);
792 6
}
793
794
/**
795
 * Add the current site admins to the subscribers when making/removing an admin user
796
 *
797
 * @param string $hook         'get'
798
 * @param string $type         'subscribers'
799
 * @param array  $return_value current subscribers
800
 * @param array  $params       supplied params
801
 *
802
 * @return void|array
803
 */
804
function _elgg_admin_get_admin_subscribers_admin_action($hook, $type, $return_value, $params) {
805
	
806 2
	if (!_elgg_config()->security_notify_admins) {
807
		return;
808
	}
809
	
810 2
	$event = elgg_extract('event', $params);
811 2
	if (!($event instanceof \Elgg\Notifications\Event)) {
812 2
		return;
813
	}
814
	
815
	if (!in_array($event->getAction(), ['make_admin', 'remove_admin'])) {
816
		return;
817
	}
818
	
819
	$user = $event->getObject();
820
	if (!($user instanceof \ElggUser)) {
821
		return;
822
	}
823
	
824
	/* @var $admin_batch \Elgg\BatchResult */
825
	$admin_batch = elgg_get_admins([
826
		'limit' => false,
827
		'wheres' => [
828
			"e.guid <> {$user->getGUID()}",
829
		],
830
		'batch' => true,
831
	]);
832
	
833
	/* @var $admin \ElggUser */
834
	foreach ($admin_batch as $admin) {
835
		$return_value[$admin->getGUID()] = ['email'];
836
	}
837
	
838
	return $return_value;
839
}
840
841
/**
842
 * Prepare the notification content for site admins about making a site admin
843
 *
844
 * @param string                           $hook         'prepare'
845
 * @param string                           $type         'notification:make_admin:user:'
846
 * @param \Elgg\Notifications\Notification $return_value current notification content
847
 * @param array                            $params       supplied params
848
 *
849
 * @return void|\Elgg\Notifications\Notification
850
 */
851
function _elgg_admin_prepare_admin_notification_make_admin($hook, $type, $return_value, $params) {
852
	
853
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
854
		return;
855
	}
856
	
857
	$recipient = elgg_extract('recipient', $params);
858
	$object = elgg_extract('object', $params);
859
	$actor = elgg_extract('sender', $params);
860
	$language = elgg_extract('language', $params);
861
	
862
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
863
		return;
864
	}
865
	
866
	if ($recipient->getGUID() === $object->getGUID()) {
867
		// recipient is the user being acted on, this is handled elsewhere
868
		return;
869
	}
870
	
871
	$site = elgg_get_site_entity();
872
	
873
	$return_value->subject = elgg_echo('admin:notification:make_admin:admin:subject', [$site->name], $language);
874
	$return_value->body = elgg_echo('admin:notification:make_admin:admin:body', [
875
		$recipient->name,
876
		$actor->name,
877
		$object->name,
878
		$site->name,
879
		$object->getURL(),
880
		$site->getURL(),
881
	], $language);
882
883
	$return_value->url = elgg_normalize_url('admin/users/admins');
884
	
885
	return $return_value;
886
}
887
888
/**
889
 * Prepare the notification content for site admins about removing a site admin
890
 *
891
 * @param string                           $hook         'prepare'
892
 * @param string                           $type         'notification:remove_admin:user:'
893
 * @param \Elgg\Notifications\Notification $return_value current notification content
894
 * @param array                            $params       supplied params
895
 *
896
 * @return void|\Elgg\Notifications\Notification
897
 */
898
function _elgg_admin_prepare_admin_notification_remove_admin($hook, $type, $return_value, $params) {
899
	
900
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
901
		return;
902
	}
903
	
904
	$recipient = elgg_extract('recipient', $params);
905
	$object = elgg_extract('object', $params);
906
	$actor = elgg_extract('sender', $params);
907
	$language = elgg_extract('language', $params);
908
	
909
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
910
		return;
911
	}
912
	
913
	if ($recipient->getGUID() === $object->getGUID()) {
914
		// recipient is the user being acted on, this is handled elsewhere
915
		return;
916
	}
917
	
918
	$site = elgg_get_site_entity();
919
	
920
	$return_value->subject = elgg_echo('admin:notification:remove_admin:admin:subject', [$site->name], $language);
921
	$return_value->body = elgg_echo('admin:notification:remove_admin:admin:body', [
922
		$recipient->name,
923
		$actor->name,
924
		$object->name,
925
		$site->name,
926
		$object->getURL(),
927
		$site->getURL(),
928
	], $language);
929
930
	$return_value->url = elgg_normalize_url('admin/users/admins');
931
	
932
	return $return_value;
933
}
934
935
/**
936
 * Add the user to the subscribers when making/removing the admin role
937
 *
938
 * @param string $hook         'get'
939
 * @param string $type         'subscribers'
940
 * @param array  $return_value current subscribers
941
 * @param array  $params       supplied params
942
 *
943
 * @return void|array
944
 */
945
function _elgg_admin_get_user_subscriber_admin_action($hook, $type, $return_value, $params) {
946
	
947 2
	if (!_elgg_config()->security_notify_user_admin) {
948 2
		return;
949
	}
950
	
951
	$event = elgg_extract('event', $params);
952
	if (!($event instanceof \Elgg\Notifications\Event)) {
953
		return;
954
	}
955
	
956
	if (!in_array($event->getAction(), ['make_admin', 'remove_admin'])) {
957
		return;
958
	}
959
	
960
	$user = $event->getObject();
961
	if (!($user instanceof \ElggUser)) {
962
		return;
963
	}
964
	
965
	$return_value[$user->getGUID()] = ['email'];
966
	
967
	return $return_value;
968
}
969
970
/**
971
 * Prepare the notification content for the user being made as a site admins
972
 *
973
 * @param string                           $hook         'prepare'
974
 * @param string                           $type         'notification:make_admin:user:'
975
 * @param \Elgg\Notifications\Notification $return_value current notification content
976
 * @param array                            $params       supplied params
977
 *
978
 * @return void|\Elgg\Notifications\Notification
979
 */
980
function _elgg_admin_prepare_user_notification_make_admin($hook, $type, $return_value, $params) {
981
	
982
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
983
		return;
984
	}
985
	
986
	$recipient = elgg_extract('recipient', $params);
987
	$object = elgg_extract('object', $params);
988
	$actor = elgg_extract('sender', $params);
989
	$language = elgg_extract('language', $params);
990
	
991
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
992
		return;
993
	}
994
	
995
	if ($recipient->getGUID() !== $object->getGUID()) {
996
		// recipient is some other user, this is handled elsewhere
997
		return;
998
	}
999
	
1000
	$site = elgg_get_site_entity();
1001
	
1002
	$return_value->subject = elgg_echo('admin:notification:make_admin:user:subject', [$site->name], $language);
1003
	$return_value->body = elgg_echo('admin:notification:make_admin:user:body', [
1004
		$recipient->name,
1005
		$actor->name,
1006
		$site->name,
1007
		$site->getURL(),
1008
	], $language);
1009
1010
	$return_value->url = elgg_normalize_url('admin');
1011
	
1012
	return $return_value;
1013
}
1014
1015
/**
1016
 * Prepare the notification content for the user being removed as a site admins
1017
 *
1018
 * @param string                           $hook         'prepare'
1019
 * @param string                           $type         'notification:remove_admin:user:'
1020
 * @param \Elgg\Notifications\Notification $return_value current notification content
1021
 * @param array                            $params       supplied params
1022
 *
1023
 * @return void|\Elgg\Notifications\Notification
1024
 */
1025
function _elgg_admin_prepare_user_notification_remove_admin($hook, $type, $return_value, $params) {
1026
	
1027
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
1028
		return;
1029
	}
1030
	
1031
	$recipient = elgg_extract('recipient', $params);
1032
	$object = elgg_extract('object', $params);
1033
	$actor = elgg_extract('sender', $params);
1034
	$language = elgg_extract('language', $params);
1035
	
1036
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
1037
		return;
1038
	}
1039
	
1040
	if ($recipient->getGUID() !== $object->getGUID()) {
1041
		// recipient is some other user, this is handled elsewhere
1042
		return;
1043
	}
1044
	
1045
	$site = elgg_get_site_entity();
1046
	
1047
	$return_value->subject = elgg_echo('admin:notification:remove_admin:user:subject', [$site->name], $language);
1048
	$return_value->body = elgg_echo('admin:notification:remove_admin:user:body', [
1049
		$recipient->name,
1050
		$actor->name,
1051
		$site->name,
1052
		$site->getURL(),
1053
	], $language);
1054
1055
	$return_value->url = false;
0 ignored issues
show
Documentation Bug introduced by
The property $url was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1056
	
1057
	return $return_value;
1058
}
1059
1060
/**
1061
 * @see \Elgg\Application::loadCore Do not do work here. Just register for events.
1062
 */
1063
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
1064 18
	$events->registerHandler('init', 'system', '_elgg_admin_init');
1065
};
1066