Completed
Push — 3.0 ( 9dd29c...237018 )
by Jeroen
53:05
created

engine/lib/admin.php (1 issue)

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
use Elgg\Menu\MenuItems;
24
use Elgg\Database\QueryBuilder;
25
26
/**
27
 * Get the admin users
28
 *
29
 * @param array $options Options array, @see elgg_get_entities() for parameters
30
 *
31
 * @return mixed Array of admin users or false on failure. If a count, returns int.
32
 * @since 1.8.0
33
 */
34
function elgg_get_admins(array $options = []) {
35 337
	$options['type'] = 'user';
36 337
	$options['metadata_name_value_pairs'] = elgg_extract('metadata_name_value_pairs', $options, []);
37
	
38 337
	$options['metadata_name_value_pairs']['admin'] = 'yes';
39
40 337
	return elgg_get_entities($options);
41
}
42
43
/**
44
 * Write a persistent message to the admin view.
45
 * Useful to alert the admin to take a certain action.
46
 * The id is a unique ID that can be cleared once the admin
47
 * completes the action.
48
 *
49
 * eg: add_admin_notice('twitter_services_no_api',
50
 * 	'Before your users can use Twitter services on this site, you must set up
51
 * 	the Twitter API key in the <a href="link">Twitter Services Settings</a>');
52
 *
53
 * @param string $id      A unique ID that your plugin can remember
54
 * @param string $message Body of the message
55
 *
56
 * @return ElggObject|bool
57
 * @since 1.8.0
58
 */
59
function elgg_add_admin_notice($id, $message) {
60 4
	return _elgg_services()->adminNotices->add($id, $message);
61
}
62
63
/**
64
 * Remove an admin notice by ID.
65
 *
66
 * @param string $id The unique ID assigned in add_admin_notice()
67
 *
68
 * @return bool
69
 * @since 1.8.0
70
 */
71
function elgg_delete_admin_notice($id) {
72 18
	return _elgg_services()->adminNotices->delete($id);
73
}
74
75
/**
76
 * Get admin notices. An admin must be logged in since the notices are private.
77
 *
78
 * @param array $options Query options
79
 *
80
 * @return ElggObject[] Admin notices
81
 * @since 1.8.0
82
 */
83
function elgg_get_admin_notices(array $options = []) {
84 1
	return _elgg_services()->adminNotices->find($options);
85
}
86
87
/**
88
 * Check if an admin notice is currently active. (Ignores access)
89
 *
90
 * @param string $id The unique ID used to register the notice.
91
 *
92
 * @return bool
93
 * @since 1.8.0
94
 */
95
function elgg_admin_notice_exists($id) {
96 4
	return _elgg_services()->adminNotices->exists($id);
97
}
98
99
/**
100
 * Add an admin notice when a new \ElggUpgrade object is created.
101
 *
102
 * @param string      $event  'create'
103
 * @param string      $type   'object'
104
 * @param \ElggObject $object the created object
105
 *
106
 * @return void
107
 *
108
 * @access private
109
 */
110
function _elgg_create_notice_of_pending_upgrade($event, $type, $object) {
111 235
	if (!$object instanceof \ElggUpgrade) {
112 235
		return;
113
	}
114
	
115
	// Link to the Upgrades section
116 1
	$link = elgg_view('output/url', [
117 1
		'href' => 'admin/upgrades',
118 1
		'text' => elgg_echo('admin:view_upgrades'),
119
	]);
120
121 1
	$message = elgg_echo('admin:pending_upgrades');
122
123 1
	elgg_add_admin_notice('pending_upgrades', "$message $link");
124 1
}
125
126
/**
127
 * Initialize the admin backend.
128
 * @return void
129
 * @access private
130
 */
131
function _elgg_admin_init() {
132
133 75
	elgg_register_css('elgg.admin', elgg_get_simplecache_url('admin.css'));
134 75
	elgg_register_css('admin/users/unvalidated', elgg_get_simplecache_url('admin/users/unvalidated.css'));
135
136 75
	elgg_define_js('admin/users/unvalidated', [
137 75
		'src' => elgg_get_simplecache_url('admin/users/unvalidated.js'),
138
	]);
139
	
140 75
	elgg_extend_view('admin.css', 'lightbox/elgg-colorbox-theme/colorbox.css');
141
		
142 75
	elgg_register_plugin_hook_handler('register', 'menu:admin_header', '_elgg_admin_header_menu');
143 75
	elgg_register_plugin_hook_handler('register', 'menu:admin_footer', '_elgg_admin_footer_menu');
144 75
	elgg_register_plugin_hook_handler('register', 'menu:filter:admin/upgrades', '_elgg_admin_upgrades_menu');
145 75
	elgg_register_plugin_hook_handler('register', 'menu:page', '_elgg_admin_page_menu');
146 75
	elgg_register_plugin_hook_handler('register', 'menu:page', '_elgg_admin_page_menu_plugin_settings');
147 75
	elgg_register_plugin_hook_handler('register', 'menu:user:unvalidated:bulk', '_elgg_admin_user_unvalidated_bulk_menu');
148
149
	// maintenance mode
150 75
	if (elgg_get_config('elgg_maintenance_mode', null)) {
151
		elgg_register_plugin_hook_handler('route', 'all', '_elgg_admin_maintenance_handler', 600);
152
		elgg_register_plugin_hook_handler('action', 'all', '_elgg_admin_maintenance_action_check', 600);
153
		elgg_register_css('maintenance', elgg_get_simplecache_url('maintenance.css'));
154
155
		elgg_register_menu_item('topbar', [
156
			'name' => 'maintenance_mode',
157
			'href' => 'admin/configure_utilities/maintenance',
158
			'text' => elgg_echo('admin:maintenance_mode:indicator_menu_item'),
159
			'icon' => 'wrench',
160
			'priority' => 900,
161
		]);
162
	}
163
164 75
	elgg_register_simplecache_view('admin.css');
165
	
166
	// widgets
167 75
	$widgets = ['online_users', 'new_users', 'content_stats', 'banned_users', 'admin_welcome', 'control_panel', 'cron_status'];
168 75
	foreach ($widgets as $widget) {
169 75
		elgg_register_widget_type(
170 75
				$widget,
171 75
				elgg_echo("admin:widget:$widget"),
172 75
				elgg_echo("admin:widget:$widget:help"),
173 75
				['admin']
174
		);
175
	}
176
177
	// automatic adding of widgets for admin
178 75
	elgg_register_event_handler('make_admin', 'user', '_elgg_add_admin_widgets');
179
	
180 75
	elgg_register_notification_event('user', 'user', ['make_admin', 'remove_admin']);
181 75
	elgg_register_plugin_hook_handler('get', 'subscriptions', '_elgg_admin_get_admin_subscribers_admin_action');
182 75
	elgg_register_plugin_hook_handler('get', 'subscriptions', '_elgg_admin_get_user_subscriber_admin_action');
183 75
	elgg_register_plugin_hook_handler('prepare', 'notification:make_admin:user:user', '_elgg_admin_prepare_admin_notification_make_admin');
184 75
	elgg_register_plugin_hook_handler('prepare', 'notification:make_admin:user:user', '_elgg_admin_prepare_user_notification_make_admin');
185 75
	elgg_register_plugin_hook_handler('prepare', 'notification:remove_admin:user:user', '_elgg_admin_prepare_admin_notification_remove_admin');
186 75
	elgg_register_plugin_hook_handler('prepare', 'notification:remove_admin:user:user', '_elgg_admin_prepare_user_notification_remove_admin');
187
	
188
	// Add notice about pending upgrades
189 75
	elgg_register_event_handler('create', 'object', '_elgg_create_notice_of_pending_upgrade');
190 75
}
191
192
/**
193
 * Returns plugin listing and admin menu to the client (used after plugin (de)activation)
194
 *
195
 * @access private
196
 * @return Elgg\Http\OkResponse
197
 */
198
function _elgg_ajax_plugins_update() {
199
	elgg_admin_gatekeeper();
200
	elgg_set_context('admin');
201
202
	return elgg_ok_response([
203
		'list' => elgg_view('admin/plugins', ['list_only' => true]),
204
		'sidebar' => elgg_view('admin/sidebar'),
205
	]);
206
}
207
208
/**
209
 * Register menu items for the admin_header menu
210
 *
211
 * @param string          $hook   'register'
212
 * @param string          $type   'menu:admin_header'
213
 * @param \ElggMenuItem[] $return current return value
214
 * @param array           $params supplied params
215
 *
216
 * @return void|\ElggMenuItem
217
 *
218
 * @access private
219
 * @since 3.0
220
 */
221
function _elgg_admin_header_menu($hook, $type, $return, $params) {
222
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
223
		return;
224
	}
225
226
	$admin = elgg_get_logged_in_user_entity();
227
228
	$return[] = \ElggMenuItem::factory([
229
		'name' => 'account',
230
		'text' => $admin->getDisplayName(),
231
		'href' => $admin->getURL(),
232
		'icon' => elgg_view('output/img', [
233
			'src' => $admin->getIconURL('small'),
234
			'alt' => $admin->getDisplayName(),
235
		]),
236
		'link_class' => 'elgg-avatar-small',
237
		'priority' => 1000,
238
	]);
239
240
	$return[] = \ElggMenuItem::factory([
241
		'name' => 'admin_logout',
242
		'href' => 'action/logout',
243
		'text' => elgg_echo('logout'),
244
		'priority' => 900,
245
	]);
246
247
	$return[] = \ElggMenuItem::factory([
248
		'name' => 'view_site',
249
		'href' => elgg_get_site_url(),
250
		'text' => elgg_echo('admin:view_site'),
251
		'priority' => 800,
252
	]);
253
254
	if (elgg_get_config('elgg_maintenance_mode')) {
255
		$return[] = \ElggMenuItem::factory([
256
			'name' => 'maintenance',
257
			'href' => 'admin/configure_utilities/maintenance',
258
			'text' => elgg_echo('admin:configure_utilities:maintenance'),
259
			'link_class' => 'elgg-maintenance-mode-warning',
260
			'priority' => 700,
261
		]);
262
	}
263
	
264
	return $return;
265
}
266
267
/**
268
 * Register menu items for the admin_footer menu
269
 *
270
 * @param string          $hook   'register'
271
 * @param string          $type   'menu:admin_footer'
272
 * @param \ElggMenuItem[] $return current return value
273
 * @param array           $params supplied params
274
 *
275
 * @return void|\ElggMenuItem[]
276
 *
277
 * @access private
278
 * @since 3.0
279
 */
280
function _elgg_admin_footer_menu($hook, $type, $return, $params) {
281
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
282
		return;
283
	}
284
285
	$return[] = \ElggMenuItem::factory([
286
		'name' => 'faq',
287
		'text' => elgg_echo('admin:footer:faq'),
288
		'href' => 'http://learn.elgg.org/en/stable/appendix/faqs.html',
289
	]);
290
291
	$return[] = \ElggMenuItem::factory([
292
		'name' => 'manual',
293
		'text' => elgg_echo('admin:footer:manual'),
294
		'href' => 'http://learn.elgg.org/en/stable/admin/index.html',
295
	]);
296
297
	$return[] = \ElggMenuItem::factory([
298
		'name' => 'community_forums',
299
		'text' => elgg_echo('admin:footer:community_forums'),
300
		'href' => 'http://elgg.org/groups/all/',
301
	]);
302
303
	$return[] = \ElggMenuItem::factory([
304
		'name' => 'blog',
305
		'text' => elgg_echo('admin:footer:blog'),
306
		'href' => 'https://elgg.org/blog/all',
307
	]);
308
	
309
	return $return;
310
}
311
312
/**
313
 * Register menu items for the page menu
314
 *
315
 * @param \Elgg\Hook $hook 'register' 'menu:page'
316
 * @return array
317
 *
318
 * @access private
319
 * @see _elgg_default_widgets_init() for default widgets menu items setup
320
 * @since 3.0
321
 */
322
function _elgg_admin_page_menu(\Elgg\Hook $hook) {
323 2
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
324 2
		return;
325
	}
326
	
327
	$return = $hook->getValue();
328
329
	// administer
330
	$return[] = \ElggMenuItem::factory([
331
		'name' => 'dashboard',
332
		'href' => 'admin',
333
		'text' => elgg_echo('admin:dashboard'),
334
		'priority' => 10,
335
		'section' => 'administer',
336
	]);
337
	
338
	$return[] = \ElggMenuItem::factory([
339
		'name' => 'plugins',
340
		'href' => 'admin/plugins',
341
		'text' => elgg_echo('admin:plugins'),
342
		'priority' => 30,
343
		'section' => 'administer',
344
	]);
345
346
	$return[] = \ElggMenuItem::factory([
347
		'name' => 'users',
348
		'text' => elgg_echo('admin:users'),
349
		'priority' => 40,
350
		'section' => 'administer',
351
	]);
352
	$return[] = \ElggMenuItem::factory([
353
		'name' => 'users:online',
354
		'text' => elgg_echo('admin:users:online'),
355
		'href' => 'admin/users/online',
356
		'priority' => 10,
357
		'section' => 'administer',
358
		'parent_name' => 'users',
359
	]);
360
	$return[] = \ElggMenuItem::factory([
361
		'name' => 'users:admins',
362
		'text' => elgg_echo('admin:users:admins'),
363
		'href' => 'admin/users/admins',
364
		'priority' => 20,
365
		'section' => 'administer',
366
		'parent_name' => 'users',
367
	]);
368
	$return[] = \ElggMenuItem::factory([
369
		'name' => 'users:newest',
370
		'text' => elgg_echo('admin:users:newest'),
371
		'href' => 'admin/users/newest',
372
		'priority' => 30,
373
		'section' => 'administer',
374
		'parent_name' => 'users',
375
	]);
376
	$return[] = \ElggMenuItem::factory([
377
		'name' => 'users:add',
378
		'text' => elgg_echo('admin:users:add'),
379
		'href' => 'admin/users/add',
380
		'priority' => 40,
381
		'section' => 'administer',
382
		'parent_name' => 'users',
383
	]);
384
	
385
	$return[] = \ElggMenuItem::factory([
386
		'name' => 'users:unvalidated',
387
		'text' => elgg_echo('admin:users:unvalidated'),
388
		'href' => 'admin/users/unvalidated',
389
		'priority' => 50,
390
		'section' => 'administer',
391
		'parent_name' => 'users',
392
	]);
393
	$return[] = \ElggMenuItem::factory([
394
		'name' => 'upgrades',
395
		'href' => 'admin/upgrades',
396
		'text' => elgg_echo('admin:upgrades'),
397
		'priority' => 600,
398
		'section' => 'administer',
399
	]);
400
	
401
	$return[] = \ElggMenuItem::factory([
402
		'name' => 'administer_utilities',
403
		'text' => elgg_echo('admin:administer_utilities'),
404
		'priority' => 50,
405
		'section' => 'administer',
406
	]);
407
	
408
	// configure
409
	$return[] = \ElggMenuItem::factory([
410
		'name' => 'settings:basic',
411
		'href' => 'admin/settings/basic',
412
		'text' => elgg_echo('admin:settings:basic'),
413
		'priority' => 10,
414
		'section' => 'configure',
415
	]);
416
	$return[] = \ElggMenuItem::factory([
417
		'name' => 'settings:advanced',
418
		'href' => 'admin/settings/advanced',
419
		'text' => elgg_echo('admin:settings:advanced'),
420
		'priority' => 20,
421
		'section' => 'configure',
422
	]);
423
	$return[] = \ElggMenuItem::factory([
424
		'name' => 'security',
425
		'href' => 'admin/security',
426
		'text' => elgg_echo('admin:security'),
427
		'priority' => 30,
428
		'section' => 'configure',
429
	]);
430
431
	$return[] = \ElggMenuItem::factory([
432
		'name' => 'configure_utilities',
433
		'text' => elgg_echo('admin:configure_utilities'),
434
		'priority' => 600,
435
		'section' => 'configure',
436
	]);
437
	$return[] = \ElggMenuItem::factory([
438
		'name' => 'configure_utilities:maintenance',
439
		'text' => elgg_echo('admin:configure_utilities:maintenance'),
440
		'href' => 'admin/configure_utilities/maintenance',
441
		'section' => 'configure',
442
		'parent_name' => 'configure_utilities',
443
	]);
444
	$return[] = \ElggMenuItem::factory([
445
		'name' => 'configure_utilities:menu_items',
446
		'text' => elgg_echo('admin:configure_utilities:menu_items'),
447
		'href' => 'admin/configure_utilities/menu_items',
448
		'section' => 'configure',
449
		'parent_name' => 'configure_utilities',
450
	]);
451
	$return[] = \ElggMenuItem::factory([
452
		'name' => 'configure_utilities:robots',
453
		'text' => elgg_echo('admin:configure_utilities:robots'),
454
		'href' => 'admin/configure_utilities/robots',
455
		'section' => 'configure',
456
		'parent_name' => 'configure_utilities',
457
	]);
458
	
459
	// information
460
	$return[] = \ElggMenuItem::factory([
461
		'name' => 'statistics',
462
		'href' => 'admin/statistics',
463
		'text' => elgg_echo('admin:statistics'),
464
		'section' => 'information',
465
	]);
466
	$return[] = \ElggMenuItem::factory([
467
		'name' => 'server',
468
		'href' => 'admin/server',
469
		'text' => elgg_echo('admin:server'),
470
		'section' => 'information',
471
	]);
472
		
473
	return $return;
474
}
475
476
/**
477
 * Register plugin settings menu items for the admin page menu
478
 *
479
 * @note Plugin settings are alphabetically sorted in the submenu
480
 *
481
 * @param \Elgg\Hook $hook 'register' 'menu:page'
482
 * @return array
483
 *
484
 * @access private
485
 * @since 3.0
486
 */
487
function _elgg_admin_page_menu_plugin_settings(\Elgg\Hook $hook) {
488 2
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
489 2
		return;
490
	}
491
	
492
	// plugin settings
493
	$active_plugins = elgg_get_plugins('active');
494
	if (!$active_plugins) {
495
		// nothing added because no items
496
		return;
497
	}
498
	
499
	$plugins_with_settings = [];
500
	
501
	foreach ($active_plugins as $plugin) {
502
		$plugin_id = $plugin->getID();
503
		
504
		if (!elgg_view_exists("plugins/{$plugin_id}/settings") ) {
505
			continue;
506
		}
507
		$plugin_name = $plugin->getDisplayName();
508
		$plugins_with_settings[$plugin_name] = [
509
			'name' => $plugin_id,
510
			'href' => "admin/plugin_settings/$plugin_id",
511
			'text' => $plugin_name,
512
			'parent_name' => 'plugin_settings',
513
			'section' => 'configure',
514
		];
515
	}
516
	
517
	if (empty($plugins_with_settings)) {
518
		return;
519
	}
520
521
	$return = $hook->getValue();
522
	
523
	$return[] = \ElggMenuItem::factory([
524
		'name' => 'plugin_settings',
525
		'text' => elgg_echo('admin:plugin_settings'),
526
		'section' => 'configure',
527
	]);
528
	
529
	ksort($plugins_with_settings);
530
	$priority = 0;
531
	foreach ($plugins_with_settings as $plugin_item) {
532
		$priority += 10;
533
		$plugin_item['priority'] = $priority;
534
		$return[] = \ElggMenuItem::factory($plugin_item);
535
	}
536
	
537
	return $return;
538
}
539
540
/**
541
 * Register menu items to the bulk actions for unvalidated users
542
 *
543
 * @elgg_plugin_hook register menu:user:unvalidated:bulk
544
 *
545
 * @param \Elgg\Hook $hook 'register' 'menu:user:unvalidated:bulk'
546
 *
547
 * @return void|ElggMenuItem[]
548
 *
549
 * @since 3.0
550
 * @internal
551
 */
552
function _elgg_admin_user_unvalidated_bulk_menu(\Elgg\Hook $hook) {
553
	
554
	if (!elgg_is_admin_logged_in()) {
555
		return;
556
	}
557
	
558
	$return = $hook->getValue();
559
	
560
	$return[] = ElggMenuItem::factory([
561
		'name' => 'select_all',
562
		'text' => elgg_view('input/checkbox', [
563
			'name' => 'select_all',
564
			'label' => elgg_echo('all'),
565
			'id' => 'admin-users-unvalidated-bulk-select',
566
		]),
567
		'href' => false,
568
		'priority' => 100,
569
		'deps' => 'admin/users/unvalidated',
570
	]);
571
	
572
	$return[] = ElggMenuItem::factory([
573
		'id' => 'admin-users-unvalidated-bulk-validate',
574
		'name' => 'bulk_validate',
575
		'text' => elgg_echo('validate'),
576
		'href' => 'action/admin/user/bulk/validate',
577
		'confirm' => true,
578
		'priority' => 400,
579
		'section' => 'right',
580
		'deps' => 'admin/users/unvalidated',
581
	]);
582
	
583
	$return[] = ElggMenuItem::factory([
584
		'id' => 'admin-users-unvalidated-bulk-delete',
585
		'name' => 'bulk_delete',
586
		'text' => elgg_echo('delete'),
587
		'href' => 'action/admin/user/bulk/delete',
588
		'confirm' => elgg_echo('deleteconfirm:plural'),
589
		'priority' => 500,
590
		'section' => 'right',
591
		'deps' => 'admin/users/unvalidated',
592
	]);
593
	
594
	return $return;
595
}
596
597
/**
598
 * Handle admin pages.  Expects corresponding views as admin/section/subsection
599
 *
600
 * @param array $page Array of pages
601
 *
602
 * @return bool
603
 * @access private
604
 */
605
function _elgg_admin_page_handler($page) {
606
	elgg_admin_gatekeeper();
607
	elgg_set_context('admin');
608
609
	elgg_unregister_css('elgg');
610
	elgg_require_js('elgg/admin');
611
612
	// default to dashboard
613
	if (!isset($page[0]) || empty($page[0])) {
614
		$page = ['dashboard'];
615
	}
616
617
	// was going to fix this in the page_handler() function but
618
	// it's commented to explicitly return a string if there's a trailing /
619
	if (empty($page[count($page) - 1])) {
620
		array_pop($page);
621
	}
622
623
	$vars = ['page' => $page];
624
625
	// special page for plugin settings since we create the form for them
626
	if ($page[0] == 'plugin_settings') {
627
		if (isset($page[1]) && (elgg_view_exists("plugins/{$page[1]}/settings"))) {
628
			$view = 'admin/plugin_settings';
629
			$plugin = elgg_get_plugin_from_id($page[1]);
630
			$vars['plugin'] = $plugin; // required for plugin settings backward compatibility
631
			$vars['entity'] = $plugin;
632
633
			$title = elgg_echo("admin:{$page[0]}") . ': ' . $plugin->getDisplayName();
634
		} else {
635
			forward('', '404');
636
		}
637
	} else {
638
		$view = 'admin/' . implode('/', $page);
639
		$title = elgg_echo("admin:{$page[0]}");
640
		if (count($page) > 1) {
641
			$title .= ' : ' . elgg_echo('admin:' .  implode(':', $page));
642
		}
643
	}
644
645
	// gets content and prevents direct access to 'components' views
646
	if ($page[0] == 'components' || !($content = elgg_view($view, $vars))) {
647
		$title = elgg_echo('admin:unknown_section');
648
		$content = elgg_echo('admin:unknown_section');
649
	}
650
651
	$body = elgg_view_layout('admin', ['content' => $content, 'title' => $title]);
652
	echo elgg_view_page($title, $body, 'admin');
653
	return true;
654
}
655
656
/**
657
 * When in maintenance mode, should the given URL be handled normally?
658
 *
659
 * @param string $current_url Current page URL
660
 * @return bool
661
 *
662
 * @access private
663
 */
664
function _elgg_admin_maintenance_allow_url($current_url) {
665
	$site_path = preg_replace('~^https?~', '', elgg_get_site_url());
666
	$current_path = preg_replace('~^https?~', '', $current_url);
667
	if (0 === strpos($current_path, $site_path)) {
668
		$current_path = ($current_path === $site_path) ? '' : substr($current_path, strlen($site_path));
669
	} else {
670
		$current_path = false;
671
	}
672
673
	// allow plugins to control access for specific URLs/paths
674
	$params = [
675
		'current_path' => $current_path,
676
		'current_url' => $current_url,
677
	];
678
	return (bool) elgg_trigger_plugin_hook('maintenance:allow', 'url', $params, false);
679
}
680
681
/**
682
 * Handle requests when in maintenance mode
683
 *
684
 * @param string $hook 'route'
685
 * @param string $type 'all'
686
 * @param array  $info current return value
687
 *
688
 * @return void|false
689
 *
690
 * @access private
691
 */
692
function _elgg_admin_maintenance_handler($hook, $type, $info) {
693
	if (elgg_is_admin_logged_in()) {
694
		return;
695
	}
696
697
	if ($info['identifier'] == 'action' && $info['segments'][0] == 'login') {
698
		return;
699
	}
700
701
	if (_elgg_admin_maintenance_allow_url(current_page_url())) {
702
		return;
703
	}
704
705
	elgg_unregister_plugin_hook_handler('register', 'menu:login', '_elgg_login_menu_setup');
706
707
	echo elgg_view_resource('maintenance');
708
709
	return false;
710
}
711
712
/**
713
 * Prevent non-admins from using actions
714
 *
715
 * @access private
716
 *
717
 * @param string $hook Hook name
718
 * @param string $type Action name
719
 * @return bool
720
 */
721
function _elgg_admin_maintenance_action_check($hook, $type) {
722
	if (elgg_is_admin_logged_in()) {
723
		return true;
724
	}
725
726
	if ($type == 'login') {
727
		$username = get_input('username');
728
729
		$user = get_user_by_username($username);
730
731
		if (!$user) {
732
			$users = get_user_by_email($username);
733
			if ($users) {
734
				$user = $users[0];
735
			}
736
		}
737
738
		if ($user && $user->isAdmin()) {
739
			return true;
740
		}
741
	}
742
743
	if (_elgg_admin_maintenance_allow_url(current_page_url())) {
744
		return true;
745
	}
746
747
	register_error(elgg_echo('actionunauthorized'));
748
749
	return false;
750
}
751
752
/**
753
 * Adds default admin widgets to the admin dashboard.
754
 *
755
 * @param string    $event 'make_admin'
756
 * @param string    $type  'user'
757
 * @param \ElggUser $user  affected user
758
 *
759
 * @return void
760
 * @access private
761
 */
762
function _elgg_add_admin_widgets($event, $type, $user) {
763 6
	$ia = elgg_set_ignore_access(true);
764
765
	// check if the user already has widgets
766 6
	if (elgg_get_widgets($user->getGUID(), 'admin')) {
767
		elgg_set_ignore_access($ia);
768
		return;
769
	}
770
771
	// In the form column => array of handlers in order, top to bottom
772
	$adminWidgets = [
773 6
		1 => ['control_panel', 'admin_welcome'],
774
		2 => ['online_users', 'new_users', 'content_stats'],
775
	];
776
777 6
	foreach ($adminWidgets as $column => $handlers) {
778 6
		foreach ($handlers as $position => $handler) {
779 6
			$guid = elgg_create_widget($user->getGUID(), $handler, 'admin');
780 6
			if ($guid) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $guid of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. 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 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...
781 6
				$widget = get_entity($guid);
782
				/* @var \ElggWidget $widget */
783 6
				$widget->move($column, $position);
784
			}
785
		}
786
	}
787
	
788 6
	elgg_set_ignore_access($ia);
789 6
}
790
791
/**
792
 * Add the current site admins to the subscribers when making/removing an admin user
793
 *
794
 * @param string $hook         'get'
795
 * @param string $type         'subscribers'
796
 * @param array  $return_value current subscribers
797
 * @param array  $params       supplied params
798
 *
799
 * @return void|array
800
 */
801
function _elgg_admin_get_admin_subscribers_admin_action($hook, $type, $return_value, $params) {
802
	
803 2
	if (!_elgg_config()->security_notify_admins) {
804
		return;
805
	}
806
	
807 2
	$event = elgg_extract('event', $params);
808 2
	if (!$event instanceof \Elgg\Notifications\SubscriptionNotificationEvent) {
809 2
		return;
810
	}
811
	
812
	if (!in_array($event->getAction(), ['make_admin', 'remove_admin'])) {
813
		return;
814
	}
815
	
816
	$user = $event->getObject();
817
	if (!$user instanceof \ElggUser) {
818
		return;
819
	}
820
	
821
	/* @var $admin_batch \Elgg\BatchResult */
822
	$admin_batch = elgg_get_admins([
823
		'limit' => false,
824
		'wheres' => [
825
			function (QueryBuilder $qb, $main_alias) use ($user) {
826
				return $qb->compare("{$main_alias}.guid", '!=', $user->guid, ELGG_VALUE_GUID);
827
			},
828
		],
829
		'batch' => true,
830
	]);
831
	
832
	/* @var $admin \ElggUser */
833
	foreach ($admin_batch as $admin) {
834
		$return_value[$admin->guid] = ['email'];
835
	}
836
	
837
	return $return_value;
838
}
839
840
/**
841
 * Prepare the notification content for site admins about making a site admin
842
 *
843
 * @param string                           $hook         'prepare'
844
 * @param string                           $type         'notification:make_admin:user:'
845
 * @param \Elgg\Notifications\Notification $return_value current notification content
846
 * @param array                            $params       supplied params
847
 *
848
 * @return void|\Elgg\Notifications\Notification
849
 */
850
function _elgg_admin_prepare_admin_notification_make_admin($hook, $type, $return_value, $params) {
851
	
852
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
853
		return;
854
	}
855
	
856
	$recipient = elgg_extract('recipient', $params);
857
	$object = elgg_extract('object', $params);
858
	$actor = elgg_extract('sender', $params);
859
	$language = elgg_extract('language', $params);
860
	
861
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
862
		return;
863
	}
864
	
865
	if ($recipient->getGUID() === $object->getGUID()) {
866
		// recipient is the user being acted on, this is handled elsewhere
867
		return;
868
	}
869
	
870
	$site = elgg_get_site_entity();
871
	
872
	$return_value->subject = elgg_echo('admin:notification:make_admin:admin:subject', [$site->getDisplayName()], $language);
873
	$return_value->body = elgg_echo('admin:notification:make_admin:admin:body', [
874
		$recipient->getDisplayName(),
875
		$actor->getDisplayName(),
876
		$object->getDisplayName(),
877
		$site->getDisplayName(),
878
		$object->getURL(),
879
		$site->getURL(),
880
	], $language);
881
882
	$return_value->url = elgg_normalize_url('admin/users/admins');
883
	
884
	return $return_value;
885
}
886
887
/**
888
 * Prepare the notification content for site admins about removing a site admin
889
 *
890
 * @param string                           $hook         'prepare'
891
 * @param string                           $type         'notification:remove_admin:user:'
892
 * @param \Elgg\Notifications\Notification $return_value current notification content
893
 * @param array                            $params       supplied params
894
 *
895
 * @return void|\Elgg\Notifications\Notification
896
 */
897
function _elgg_admin_prepare_admin_notification_remove_admin($hook, $type, $return_value, $params) {
898
	
899
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
900
		return;
901
	}
902
	
903
	$recipient = elgg_extract('recipient', $params);
904
	$object = elgg_extract('object', $params);
905
	$actor = elgg_extract('sender', $params);
906
	$language = elgg_extract('language', $params);
907
	
908
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
909
		return;
910
	}
911
	
912
	if ($recipient->getGUID() === $object->getGUID()) {
913
		// recipient is the user being acted on, this is handled elsewhere
914
		return;
915
	}
916
	
917
	$site = elgg_get_site_entity();
918
	
919
	$return_value->subject = elgg_echo('admin:notification:remove_admin:admin:subject', [$site->getDisplayName()], $language);
920
	$return_value->body = elgg_echo('admin:notification:remove_admin:admin:body', [
921
		$recipient->getDisplayName(),
922
		$actor->getDisplayName(),
923
		$object->getDisplayName(),
924
		$site->getDisplayName(),
925
		$object->getURL(),
926
		$site->getURL(),
927
	], $language);
928
929
	$return_value->url = elgg_normalize_url('admin/users/admins');
930
	
931
	return $return_value;
932
}
933
934
/**
935
 * Add the user to the subscribers when making/removing the admin role
936
 *
937
 * @param string $hook         'get'
938
 * @param string $type         'subscribers'
939
 * @param array  $return_value current subscribers
940
 * @param array  $params       supplied params
941
 *
942
 * @return void|array
943
 */
944
function _elgg_admin_get_user_subscriber_admin_action($hook, $type, $return_value, $params) {
945
	
946 2
	if (!_elgg_config()->security_notify_user_admin) {
947 2
		return;
948
	}
949
	
950
	$event = elgg_extract('event', $params);
951
	if (!$event instanceof \Elgg\Notifications\SubscriptionNotificationEvent) {
952
		return;
953
	}
954
	
955
	if (!in_array($event->getAction(), ['make_admin', 'remove_admin'])) {
956
		return;
957
	}
958
	
959
	$user = $event->getObject();
960
	if (!$user instanceof \ElggUser) {
961
		return;
962
	}
963
	
964
	$return_value[$user->guid] = ['email'];
965
	
966
	return $return_value;
967
}
968
969
/**
970
 * Prepare the notification content for the user being made as a site admins
971
 *
972
 * @param string                           $hook         'prepare'
973
 * @param string                           $type         'notification:make_admin:user:'
974
 * @param \Elgg\Notifications\Notification $return_value current notification content
975
 * @param array                            $params       supplied params
976
 *
977
 * @return void|\Elgg\Notifications\Notification
978
 */
979
function _elgg_admin_prepare_user_notification_make_admin($hook, $type, $return_value, $params) {
980
	
981
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
982
		return;
983
	}
984
	
985
	$recipient = elgg_extract('recipient', $params);
986
	$object = elgg_extract('object', $params);
987
	$actor = elgg_extract('sender', $params);
988
	$language = elgg_extract('language', $params);
989
	
990
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
991
		return;
992
	}
993
	
994
	if ($recipient->getGUID() !== $object->getGUID()) {
995
		// recipient is some other user, this is handled elsewhere
996
		return;
997
	}
998
	
999
	$site = elgg_get_site_entity();
1000
	
1001
	$return_value->subject = elgg_echo('admin:notification:make_admin:user:subject', [$site->getDisplayName()], $language);
1002
	$return_value->body = elgg_echo('admin:notification:make_admin:user:body', [
1003
		$recipient->getDisplayName(),
1004
		$actor->getDisplayName(),
1005
		$site->getDisplayName(),
1006
		$site->getURL(),
1007
	], $language);
1008
1009
	$return_value->url = elgg_normalize_url('admin');
1010
	
1011
	return $return_value;
1012
}
1013
1014
/**
1015
 * Prepare the notification content for the user being removed as a site admins
1016
 *
1017
 * @param string                           $hook         'prepare'
1018
 * @param string                           $type         'notification:remove_admin:user:'
1019
 * @param \Elgg\Notifications\Notification $return_value current notification content
1020
 * @param array                            $params       supplied params
1021
 *
1022
 * @return void|\Elgg\Notifications\Notification
1023
 */
1024
function _elgg_admin_prepare_user_notification_remove_admin($hook, $type, $return_value, $params) {
1025
	
1026
	if (!($return_value instanceof \Elgg\Notifications\Notification)) {
1027
		return;
1028
	}
1029
	
1030
	$recipient = elgg_extract('recipient', $params);
1031
	$object = elgg_extract('object', $params);
1032
	$actor = elgg_extract('sender', $params);
1033
	$language = elgg_extract('language', $params);
1034
	
1035
	if (!($recipient instanceof ElggUser) || !($object instanceof ElggUser) || !($actor instanceof ElggUser)) {
1036
		return;
1037
	}
1038
	
1039
	if ($recipient->getGUID() !== $object->getGUID()) {
1040
		// recipient is some other user, this is handled elsewhere
1041
		return;
1042
	}
1043
	
1044
	$site = elgg_get_site_entity();
1045
	
1046
	$return_value->subject = elgg_echo('admin:notification:remove_admin:user:subject', [$site->getDisplayName()], $language);
1047
	$return_value->body = elgg_echo('admin:notification:remove_admin:user:body', [
1048
		$recipient->getDisplayName(),
1049
		$actor->getDisplayName(),
1050
		$site->getDisplayName(),
1051
		$site->getURL(),
1052
	], $language);
1053
1054
	$return_value->url = '';
1055
	
1056
	return $return_value;
1057
}
1058
1059
/**
1060
 * Add menu items to the filter menu on the admin upgrades page
1061
 *
1062
 * @param \Elgg\Hook $hook 'register', 'menu:filter:admin/upgrades'
1063
 *
1064
 * @return MenuItems
1065
 * @access private
1066
 */
1067
function _elgg_admin_upgrades_menu(\Elgg\Hook $hook) {
1068
	
1069
	$result = $hook->getValue();
1070
	
1071
	$selected = $hook->getParam('filter_value');
1072
	
1073
	$result[] = ElggMenuItem::factory([
1074
		'name' => 'pending',
1075
		'text' => elgg_echo('admin:upgrades:menu:pending'),
1076
		'href' => 'admin/upgrades',
1077
		'priority' => 100,
1078
		'selected' => $selected === 'pending',
1079
	]);
1080
	
1081
	$result[] = ElggMenuItem::factory([
1082
		'name' => 'completed',
1083
		'text' => elgg_echo('admin:upgrades:menu:completed'),
1084
		'href' => 'admin/upgrades/finished',
1085
		'priority' => 200,
1086
		'selected' => $selected === 'completed',
1087
	]);
1088
	
1089
	$result[] = ElggMenuItem::factory([
1090
		'name' => 'db',
1091
		'text' => elgg_echo('admin:upgrades:menu:db'),
1092
		'href' => 'admin/upgrades/db',
1093
		'priority' => 300,
1094
		'selected' => $selected === 'db',
1095
	]);
1096
	
1097
	return $result;
1098
}
1099
1100
/**
1101
 * @see \Elgg\Application::loadCore Do not do work here. Just register for events.
1102
 */
1103
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
1104 64
	$events->registerHandler('init', 'system', '_elgg_admin_init');
1105
};
1106