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
|
|||
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 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
integer
values, zero is a special case, in particular the following results might be unexpected: