PluginProbe ʕ •ᴥ•ʔ
PublishPress Capabilities – User Role Editor, Access Permissions, User Capabilities, Admin Menus / 2.19.0
PublishPress Capabilities – User Role Editor, Access Permissions, User Capabilities, Admin Menus v2.19.0
2.45.0 2.44.0 trunk 1.10 1.10.1 1.4.1 1.4.10 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5 1.5.1 1.5.10 1.5.11 1.5.2 1.5.3 1.5.4 1.5.5 1.5.7 1.5.8 1.5.9 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.8.1 1.9 1.9.10 1.9.12 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.9 2.0 2.0.2 2.0.3 2.1 2.1.1 2.10.0 2.10.1 2.10.2 2.10.3 2.11.1 2.12.1 2.12.2 2.13.0 2.14.0 2.15.0 2.16.0 2.17.0 2.18.0 2.18.2 2.19.0 2.19.1 2.19.2 2.2 2.2.1 2.20.0 2.21.0 2.22.0 2.23.0 2.3 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.30.0 2.31.0 2.32.0 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.41.0 2.42.0 2.43.0 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.7.0 2.7.1 2.8.0 2.8.1 2.9.0 2.9.1
capability-manager-enhanced / includes / manager.php
capability-manager-enhanced / includes Last commit date
admin-notices 1 year ago features 1 year ago plugin-capabilities 1 year ago redirects 1 year ago roles 1 year ago admin-load.php 1 year ago admin.php 1 year ago backup-handler.php 1 year ago backup.php 1 year ago cap-helper.php 1 year ago dashboard.php 1 year ago extractor-capabilities.php 1 year ago filters-admin.php 1 year ago filters-woocommerce.php 1 year ago filters-wp_rest_workarounds.php 1 year ago filters.php 1 year ago functions-admin.php 1 year ago functions.php 1 year ago handler.php 1 year ago inflect-cme.php 1 year ago manager.php 1 year ago network.php 1 year ago plugin-capabilities.php 1 year ago pp-handler.php 1 year ago pp-ui.php 1 year ago publishpress-roles.php 1 year ago settings-handler.php 1 year ago settings-ui.php 1 year ago settings.php 1 year ago test-user-ui.php 1 year ago test-user.php 1 year ago
manager.php
1470 lines
1 <?php
2 /**
3 * PublishPress Capabilities [Free]
4 *
5 * Plugin to create and manage roles and capabilities.
6 *
7 * This is the plugin's original controller module, which is due for some refactoring.
8 * It registers and handles menus, loads javascript, and processes or routes update operations from the Capabilities screen.
9 *
10 * Note: for lower overhead, this module is only loaded for Capabilities Pro URLs.
11 * For all other wp-admin URLs, menus are registered by a separate skeleton module.
12 *
13 * @author Jordi Canals, Kevin Behrens
14 * @copyright Copyright (C) 2009, 2010 Jordi Canals, (C) 2020 PublishPress
15 * @license GNU General Public License version 2
16 * @link https://publishpress.com/
17 *
18 *
19 * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
20 *
21 * Modifications Copyright 2020, PublishPress <help@publishpress.com>
22 *
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * version 2 as published by the Free Software Foundation.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program. If not, see <http://www.gnu.org/licenses/>.
34 */
35
36 add_action( 'init', 'cme_update_pp_usage' ); // update early so resulting post type cap changes are applied for this request's UI construction
37
38 function cme_update_pp_usage() {
39 if ( ! empty($_REQUEST['update_filtered_types']) || ! empty($_REQUEST['update_filtered_taxonomies']) || ! empty($_REQUEST['update_detailed_taxonomies']) || ! empty($_REQUEST['SaveRole']) ) {
40 check_admin_referer('capsman-general-manager');
41
42 require_once( dirname(__FILE__).'/pp-handler.php' );
43 return _cme_update_pp_usage();
44 }
45 }
46
47 // Core WP roles to apply safeguard preventing accidental lockout from dashboard
48 function _cme_core_roles() {
49 return apply_filters( 'pp_caps_core_roles', array( 'administrator', 'editor', 'revisor', 'author', 'contributor', 'subscriber' ) );
50 }
51
52 function _cme_core_caps() {
53 $core_caps = array_fill_keys( array( 'switch_themes', 'edit_themes', 'activate_plugins', 'edit_plugins', 'edit_users', 'edit_files', 'manage_options', 'moderate_comments',
54 'manage_links', 'upload_files', 'import', 'unfiltered_html', 'read', 'delete_users', 'create_users', 'unfiltered_upload', 'edit_dashboard',
55 'update_plugins', 'delete_plugins', 'install_plugins', 'update_themes', 'install_themes',
56 'update_core', 'list_users', 'remove_users', 'promote_users', 'edit_theme_options', 'delete_themes', 'export' ), true );
57
58 ksort( $core_caps );
59 return $core_caps;
60 }
61
62 function _cme_is_read_removal_blocked( $role_name ) {
63 $role = get_role($role_name);
64 $rcaps = $role->capabilities;
65
66 $core_caps = array_diff_key( _cme_core_caps(), array_fill_keys( array( 'unfiltered_html', 'unfiltered_upload', 'upload_files', 'edit_files', 'read' ), true ) );
67
68 if ( empty( $rcaps['dashboard_lockout_ok'] ) ) {
69 $edit_caps = array();
70 foreach ( get_post_types( array( 'public' => true ), 'object' ) as $type_obj ) {
71 $edit_caps = array_merge( $edit_caps, array_values( array_diff_key( (array) $type_obj->cap, array( 'read_private_posts' => true ) ) ) );
72 }
73
74 $edit_caps = array_fill_keys( $edit_caps, true );
75 unset( $edit_caps['read'] );
76 unset( $edit_caps['upload_files'] );
77 unset( $edit_caps['edit_files'] );
78
79 if ( $role_has_admin_caps = in_array( $role_name, _cme_core_roles() ) && ( array_intersect_key( $rcaps, array_diff_key( $core_caps, array( 'read' => true ) ) ) || array_intersect_key( $rcaps, $edit_caps ) ) ) {
80 return true;
81 }
82 }
83
84 return false;
85 }
86
87 /**
88 * Class CapabilityManager.
89 * Sets the main environment for all Capability Manager components.
90 *
91 * @author Jordi Canals, Kevin Behrens
92 * @link https://publishpress.com/
93 */
94 class CapabilityManager
95 {
96 /**
97 * Array with all capabilities to be managed. (Depends on user caps).
98 * The array keys are the capability, the value is its screen name.
99 * @var array
100 */
101 var $capabilities = array();
102
103 /**
104 * Array with roles that can be managed. (Depends on user roles).
105 * The array keys are the role name, the value is its translated name.
106 * @var array
107 */
108 var $roles = array();
109
110 /**
111 * Current role we are managing
112 * @var string
113 */
114 var $current;
115
116 /**
117 * Maximum level current manager can assign to a user.
118 * @var int
119 */
120 private $max_level;
121
122 private $log_db_role_objects = array();
123
124 var $message;
125
126 /**
127 * Module ID. Is the module internal short name.
128 *
129 * @var string
130 */
131 public $ID;
132
133 /**
134 * Module URL.
135 *
136 * @var string
137 */
138 public $mod_url;
139
140 public function __construct()
141 {
142 $this->ID = 'capsman';
143 $this->mod_url = plugins_url( '', CME_FILE );
144
145 if (is_admin() && !empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page']) && !empty($_POST['all_options'])) {
146 add_action('init', function() {
147 if (isset($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'pp-capabilities-settings') && current_user_can('manage_capabilities_settings')) {
148 require_once (dirname(CME_FILE) . '/includes/settings-handler.php');
149 }
150 }, 1);
151 }
152
153 $this->moduleLoad();
154
155 add_action('admin_menu', array($this, 'adminMenus'), 5); // execute prior to PP, to use menu hook
156
157 // Load styles
158 add_action('admin_print_styles', array($this, 'adminStyles'));
159
160 if ( isset($_REQUEST['page']) && ( 'pp-capabilities' == $_REQUEST['page'] ) ) {
161 add_action('admin_enqueue_scripts', array($this, 'adminScriptsPP'));
162 }
163
164 add_action('init', [$this, 'initRolesAdmin']);
165
166 add_action('wp_ajax_pp-roles-add-role', [$this, 'handleRolesAjax']);
167 add_action('wp_ajax_pp-roles-delete-role', [$this, 'handleRolesAjax']);
168
169 if (defined('PRESSPERMIT_VERSION')) {
170 add_action('wp_ajax_pp-roles-hide-role', [$this, 'handleRolesAjax']);
171 add_action('wp_ajax_pp-roles-unhide-role', [$this, 'handleRolesAjax']);
172 }
173
174 //process export
175 add_action( 'admin_init', [$this, 'processExport']);
176
177 //redirect for profile features capturing
178 add_action('admin_init', [$this, 'profileFeaturesCaptureRedirect']);
179
180 //Initialize plugin capabilities class
181 add_action('admin_init', [$this, 'initPluginCapabilities']);
182 }
183
184 /**
185 * Enqueues administration styles.
186 *
187 * @hook action 'admin_print_styles'
188 *
189 * @return void
190 */
191 function adminStyles()
192 {
193 if (empty($_REQUEST['page'])
194 || !in_array(
195 $_REQUEST['page'],
196 ['pp-capabilities', 'pp-capabilities-backup', 'pp-capabilities-roles', 'pp-capabilities-admin-menus', 'pp-capabilities-editor-features', 'pp-capabilities-nav-menus', 'pp-capabilities-settings', 'pp-capabilities-admin-features', 'pp-capabilities-profile-features', 'pp-capabilities-dashboard', 'pp-capabilities-frontend-features', 'pp-capabilities-redirects']
197 )
198 ) {
199 return;
200 }
201
202 wp_enqueue_style('cme-admin-common', $this->mod_url . '/common/css/pressshack-admin.css', [], PUBLISHPRESS_CAPS_VERSION);
203
204 wp_register_style( $this->ID . 'framework_admin', $this->mod_url . '/framework/styles/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
205 wp_enqueue_style( $this->ID . 'framework_admin');
206
207 if ('pp-capabilities' == $_REQUEST['page']) {
208 wp_register_style( $this->ID . '_admin', $this->mod_url . '/common/css/admin-caps.css', false, PUBLISHPRESS_CAPS_VERSION);
209 } else {
210 // @todo: remove Capabilities-specific styles from admin.css
211 wp_register_style( $this->ID . '_admin', $this->mod_url . '/common/css/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
212 }
213 wp_enqueue_style( $this->ID . '_admin');
214
215 wp_enqueue_script('jquery-ui-sortable');
216
217 $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : '';
218 $url = $this->mod_url . "/common/js/admin{$suffix}.js";
219 wp_enqueue_script( 'cme_admin', $url, array('jquery', 'wp-i18n', 'jquery-ui-sortable'), PUBLISHPRESS_CAPS_VERSION, true );
220
221 $capNegated = '<span class="tool-tip-text">
222 <p>'. __( 'This capability is explicitly negated. Click to add/remove normally.', 'capability-manager-enhanced' ) .'</p>
223 <i></i>
224 </span>
225 X';
226
227 wp_localize_script( 'cme_admin', 'cmeAdmin', [
228 'ajaxurl' => admin_url('admin-ajax.php'),
229 'nonce' => wp_create_nonce('pp-capabilities-dashboard-nonce'),
230 'negationCaption' => __( 'Explicity negate this capability by storing as disabled', 'capability-manager-enhanced' ),
231 'typeCapsNegationCaption' => __( 'Explicitly negate these capabilities by storing as disabled', 'capability-manager-enhanced' ),
232 'typeCapUnregistered' => __( 'Post type registration does not define this capability distinctly', 'capability-manager-enhanced' ),
233 'capNegated' => $capNegated,
234 'chkCaption' => __( 'Add or remove this capability from the WordPress role', 'capability-manager-enhanced' ),
235 'switchableCaption' => __( 'Add or remove capability from the role normally', 'capability-manager-enhanced' ),
236 'deleteWarning' => __( 'Are you sure you want to delete this item ?', 'capability-manager-enhanced' ),
237 'saveWarning' => __( 'Add or clear custom item entry before saving changes.', 'capability-manager-enhanced' )
238 ]
239 );
240 }
241
242 function adminScriptsPP() {
243 wp_enqueue_style( 'plugin-install' );
244 wp_enqueue_script( 'plugin-install' );
245 add_thickbox();
246 }
247
248 /**
249 * Creates some filters at module load time.
250 *
251 * @return void
252 */
253 protected function moduleLoad ()
254 {
255 $old_version = get_option($this->ID . '_version');
256 if ( version_compare( $old_version, PUBLISHPRESS_CAPS_VERSION, 'ne') ) {
257 update_option($this->ID . '_version', PUBLISHPRESS_CAPS_VERSION);
258 $this->pluginUpdate();
259 }
260
261 // Only roles that a user can administer can be assigned to others.
262 add_filter('editable_roles', array($this, 'filterEditRoles'));
263
264 // Users with roles that cannot be managed, are not allowed to be edited.
265 add_filter('map_meta_cap', array(&$this, 'filterUserEdit'), 10, 4);
266
267 // ensure storage, retrieval of db-stored customizations to dynamic roles
268 if ( isset($_REQUEST['page']) && in_array( $_REQUEST['page'], array( 'pp-capabilities', 'pp-capabilities-backup' ) ) ) {
269 global $wpdb;
270 $role_key = $wpdb->prefix . 'user_roles';
271 $this->log_db_roles();
272 add_filter( 'option_' . $role_key, array( &$this, 'reinstate_db_roles' ), PHP_INT_MAX );
273 }
274
275 $action = (defined('PP_CAPABILITIES_COMPAT_MODE')) ? 'init' : 'publishpress_capabilities_loaded';
276 add_action( $action, array( &$this, 'processRoleUpdate' ) );
277 }
278
279 public function set_current_role($role_name) {
280 global $current_user;
281
282 if ($role_name && !empty($current_user) && !empty($current_user->ID)) {
283 update_option("capsman_last_role_{$current_user->ID}", $role_name);
284 }
285 }
286
287 public function get_last_role() {
288 global $current_user;
289
290 $role_name = get_option("capsman_last_role_{$current_user->ID}");
291
292 if (!$role_name || !get_role($role_name)) {
293 $role_name = get_option('default_role');
294 }
295
296 return $role_name;
297 }
298
299 // Direct query of stored role definitions
300 function log_db_roles( $legacy_arg = '' ) {
301 global $wpdb;
302
303 $results = (array) maybe_unserialize( $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = '{$wpdb->prefix}user_roles' LIMIT 1") );
304 foreach( $results as $_role_name => $_role ) {
305 $this->log_db_role_objects[$_role_name] = (object) $_role;
306 }
307
308 return $legacy_arg;
309 }
310
311 // note: this is only applied when accessing the cme role edit form
312 function reinstate_db_roles( $passthru_roles = array() ) {
313 global $wp_roles;
314
315 if ( isset($wp_roles) && $this->log_db_role_objects ) {
316 $intersect = array_intersect_key( $wp_roles->role_objects, $this->log_db_role_objects );
317 foreach( array_keys( $intersect ) as $key ) {
318 if ( ! empty( $this->log_db_role_objects[$key]->capabilities ) )
319 $wp_roles->role_objects[$key]->capabilities = $this->log_db_role_objects[$key]->capabilities;
320 }
321 }
322
323 return $passthru_roles;
324 }
325
326 /**
327 * Updates Capability Manager to a new version
328 *
329 * @return void
330 */
331 protected function pluginUpdate ()
332 {
333 global $wpdb;
334
335 $backup = get_option($this->ID . '_backup');
336 if ( false === $backup ) { // No previous backup found. Save it!
337 $roles = get_option($wpdb->prefix . 'user_roles');
338 update_option( $this->ID . '_backup', $roles, false );
339 update_option( $this->ID . '_backup_datestamp', current_time( 'timestamp' ), false );
340 }
341
342 if (!$wpdb->get_var("SELECT COUNT(option_id) FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%'")) {
343 pp_capabilities_autobackup();
344 }
345 }
346
347 /**
348 * Adds admin panel menus.
349 * User needs to have 'manage_capabilities' to access this menus.
350 * This is set as an action in the parent class constructor.
351 *
352 * @hook action admin_menu
353 * @return void
354 */
355 public function adminMenus ()
356 {
357 add_action( 'admin_menu', array( &$this, 'cme_menu' ), 18 );
358 }
359
360 public function cme_menu() {
361
362 global $menu, $submenu, $capabilities_toplevel_page;
363
364 //we need to set primary menu capability to the first menu user has access to
365 $sub_menu_pages = pp_capabilities_sub_menu_lists();
366 $user_menu_caps = pp_capabilities_user_can_caps();
367 $menu_cap = false;
368 $cap_callback = false;
369 $cap_page_slug = false;
370 $cap_title = 'Capabilities'; // Pass title into add_menu_page() untranslated so hook name, body class and current_screen are not translated
371 $cap_title_i8n = __('Capabilities', 'capability-manager-enhanced');
372 $cap_name = false;
373
374 //remove caps that doesn't have menu
375 if (in_array('manage_capabilities_user_testing', $user_menu_caps)) {
376 $cap_key = array_search('manage_capabilities_user_testing', $user_menu_caps);
377 if ($cap_key !== false) {
378 unset($user_menu_caps[$cap_key]);
379 $user_menu_caps = array_filter($user_menu_caps);
380 }
381 }
382
383 if (is_multisite() && is_super_admin()) {
384 $cap_name = 'read';
385 $cap_callback = [$this, 'dashboardPage'];
386 $cap_page_slug = 'pp-capabilities-dashboard';
387 } elseif (count($user_menu_caps) > 0) {
388 $cap_name = $user_menu_caps[0];
389 $cap_index = str_replace(['manage_capabilities_', 'manage_', '_'], ['', '', '-'], $cap_name);
390 if (($cap_index !== 'capabilities') && (count($user_menu_caps) === 1)) {
391 $cap_title = $sub_menu_pages[$cap_index]['title'];
392 $using_submenu_title = true;
393 }
394 $cap_page_slug = $sub_menu_pages[$cap_index]['page'];
395 $cap_callback = $sub_menu_pages[$cap_index]['callback'];
396 }
397
398 $capabilities_toplevel_page = $cap_page_slug;
399
400 if (!$cap_name) {
401 return;
402 }
403
404 $menu_order = 72;
405
406 if (defined('PUBLISHPRESS_PERMISSIONS_MENU_GROUPING')) {
407 foreach ((array)get_option('active_plugins') as $plugin_file) {
408 if ( false !== strpos($plugin_file, 'publishpress.php') ) {
409 $menu_order = 27;
410 }
411 }
412 }
413
414 add_menu_page(
415 $cap_title,
416 $cap_title,
417 $cap_name,
418 $cap_page_slug,
419 $cap_callback,
420 'dashicons-admin-network',
421 $menu_order
422 );
423
424 // Translate plugin menu title if needed. Title was passed untranslated to avoid translating hook name, body class, current screen
425 if (($cap_title != $cap_title_i8n) && empty($using_submenu_title)) {
426 if (!empty($menu) && is_array($menu) && !defined('PP_CAPABILITIES_DISABLE_MENU_TRANSLATION_SUPPORT')) {
427 foreach ($menu as $k => $m) {
428 if (is_array($m) && isset($m[5]) && ('toplevel_page_pp-capabilities-dashboard' == $m[5])) {
429 $menu[$k][0] = $cap_title_i8n;
430 }
431 }
432 }
433 }
434
435 $dashboard_screen = (isset($_GET['page']) && $_GET['page'] === $cap_page_slug) ? true : false;
436 $submenu_slugs = [];
437 $submenu_slugs_conditions = [];
438
439 foreach ($sub_menu_pages as $feature => $subpage_option) {
440 if ($subpage_option['dashboard_control'] === false
441 || pp_capabilities_feature_enabled($feature)
442 //we'll be using css to hide menu on dashboard control screen to enable dynamic menu control
443 || $dashboard_screen
444 ) {
445 //register the menu if enabled
446 $hook = add_submenu_page($cap_page_slug, $subpage_option['title'], $subpage_option['title'], $subpage_option['capabilities'], $subpage_option['page'], $subpage_option['callback']);
447 if ($feature === 'roles' && !empty($hook)) {
448 add_action(
449 "load-$hook",
450 function () {
451 require_once(dirname(CME_FILE) . '/includes/roles/roles-functions.php');
452 admin_roles_page_load();
453 }
454 );
455 }
456 }
457 if ($dashboard_screen) {
458 $submenu_slugs[] = $subpage_option['page'];
459 $submenu_slugs_conditions[] = [ $subpage_option['page'], pp_capabilities_feature_enabled($feature)];
460 }
461 }
462
463 if ($dashboard_screen) {
464 /**
465 * Add CSS classes to these submenus to dynamically show/hide them
466 * through dashboard page enable/disable features.
467 * Copied from PublishPress Blocks
468 */
469 foreach ($submenu[$cap_page_slug] as $key => $value) {
470 if (in_array($submenu[$cap_page_slug][$key][2], $submenu_slugs)) {
471 $slug_ = $submenu[$cap_page_slug][$key][2];
472
473 // Add a class to hide menu if feature is disabled on Dashboard
474 foreach ($submenu_slugs_conditions as $item) {
475 if ($item[0] === $slug_) {
476 $showHide = $item[1] === false ? ' ppc-hide-menu-item' : '';
477 break;
478 }
479 }
480
481 $submenu[$cap_page_slug][$key][4] = $slug_ . '-menu-item' . $showHide;
482 }
483 }
484 }
485
486 }
487
488 function initRolesAdmin() {
489 // @todo: solve order of execution issue so this column headers definition is not duplicated
490 if (!empty($_REQUEST['page']) && ('pp-capabilities-roles' == $_REQUEST['page'])) {
491 add_filter(
492 "manage_capabilities_page_pp-capabilities-roles_columns",
493
494 function($arr) {
495 return [
496 'cb' => '<input type="checkbox"/>',
497 'name' => esc_html__('Role Name', 'capability-manager-enhanced'),
498 'count' => esc_html__('Users'),
499 'role_type' => esc_html__('Role Type', 'capability-manager-enhanced'),
500 'default_role' => esc_html__('Default Role', 'capability-manager-enhanced'),
501 'admin_access' => esc_html__('Admin Access', 'capability-manager-enhanced'),
502 ];
503 }
504 );
505 }
506 }
507
508 function handleRolesAjax() {
509 require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
510
511 if (!class_exists('PP_Capabilities_Roles')) {
512 require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
513 }
514
515 $roles = pp_capabilities_roles()->run();
516 }
517
518 /**
519 * Manages roles
520 *
521 * @hook add_management_page
522 * @return void
523 */
524 public function ManageRoles ()
525 {
526 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_roles')) {
527 // TODO: Implement exceptions.
528 wp_die('<strong>' . esc_html__('You do not have permission to manage roles.', 'capability-manager-enhanced') . '</strong>');
529 }
530
531 require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
532
533 if (!class_exists('PP_Capabilities_Roles')) {
534 require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
535 }
536
537 $roles = pp_capabilities_roles()->run();
538
539 require_once ( dirname(CME_FILE) . '/includes/roles/roles.php' );
540 }
541
542
543 /**
544 * Manages Editor Features
545 *
546 * @return void
547 */
548 public function ManageEditorFeatures() {
549 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_editor_features')) {
550 // TODO: Implement exceptions.
551 wp_die('<strong>' . esc_html__('You do not have permission to manage editor features.', 'capability-manager-enhanced') . '</strong>');
552 }
553
554 $this->generateNames();
555 $roles = array_keys($this->roles);
556
557 if (!isset($this->current)) {
558 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
559 $this->set_current_role(sanitize_key($_REQUEST['role']));
560 }
561 }
562
563 if (!isset($this->current) || !get_role($this->current)) {
564 $this->current = get_option('default_role');
565 }
566
567 if (!in_array($this->current, $roles)) {
568 $this->current = array_shift($roles);
569 }
570
571 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-editor-features-role']) && !empty($_REQUEST['_wpnonce'])) {
572 if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-editor-features')) {
573 wp_die('<strong>' . esc_html__('You do not have permission to manage editor features.', 'capability-manager-enhanced') . '</strong>');
574 } else {
575 $this->set_current_role(sanitize_key($_POST['ppc-editor-features-role']));
576
577 $classic_editor = pp_capabilities_is_classic_editor_available();
578
579 $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
580
581 $active_tab = isset($_POST['pp_caps_tab']) ? sanitize_key($_POST['pp_caps_tab']) : 'post';
582
583 foreach ($def_post_types as $post_type) {
584 if ($classic_editor) {
585
586 if (isset($_POST['editor-features-all-submit'])){
587 $posted_settings = (isset($_POST["capsman_feature_restrict_classic_{$active_tab}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_classic_{$active_tab}"]) : [];
588 } else {
589 $posted_settings = (isset($_POST["capsman_feature_restrict_classic_{$post_type}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_classic_{$post_type}"]) : [];
590 }
591
592 $post_features_option = (array)get_option("capsman_feature_restrict_classic_{$post_type}", []);
593 $post_features_option[sanitize_key($_POST['ppc-editor-features-role'])] = $posted_settings;
594 update_option("capsman_feature_restrict_classic_{$post_type}", $post_features_option, false);
595 }
596
597 if (isset($_POST['editor-features-all-submit'])){
598 $posted_settings = (isset($_POST["capsman_feature_restrict_{$active_tab}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_{$active_tab}"]) : [];
599 }else {
600 $posted_settings = (isset($_POST["capsman_feature_restrict_{$post_type}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_{$post_type}"]) : [];
601 }
602
603 $post_features_option = (array)get_option("capsman_feature_restrict_{$post_type}", []);
604 $post_features_option[sanitize_key($_POST['ppc-editor-features-role'])] = $posted_settings;
605 update_option("capsman_feature_restrict_{$post_type}", $post_features_option, false);
606 }
607
608 ak_admin_notify(__('Settings updated.', 'capability-manager-enhanced'));
609 }
610 }
611
612 do_action('pp_capabilities_editor_features');
613 include(dirname(CME_FILE) . '/includes/features/editor-features.php');
614 }
615
616 /**
617 * Manages Admin Features
618 *
619 * @return void
620 */
621 public function ManageAdminFeatures() {
622 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_admin_features')) {
623 // TODO: Implement exceptions.
624 wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capability-manager-enhanced') . '</strong>');
625 }
626
627 $this->generateNames();
628 $roles = array_keys($this->roles);
629
630 if (!isset($this->current)) {
631 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
632 $this->set_current_role(sanitize_key($_REQUEST['role']));
633 }
634 }
635
636 if (!isset($this->current) || !get_role($this->current)) {
637 $this->current = get_option('default_role');
638 }
639
640 if (!in_array($this->current, $roles)) {
641 $this->current = array_shift($roles);
642 }
643
644 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-admin-features-role']) && !empty($_REQUEST['_wpnonce'])) {
645 if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-admin-features')) {
646 wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capability-manager-enhanced') . '</strong>');
647 } else {
648 $features_role = sanitize_key($_POST['ppc-admin-features-role']);
649
650 $this->set_current_role($features_role);
651
652 $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
653 $disabled_admin_items[$features_role] = isset($_POST['capsman_disabled_admin_features']) ? array_map('sanitize_text_field', $_POST['capsman_disabled_admin_features']) : '';
654
655 update_option('capsman_disabled_admin_features', $disabled_admin_items, false);
656
657 //set reload option for instant reflection if user is updating own role
658 if (in_array($features_role, wp_get_current_user()->roles)){
659 $ppc_page_reload = '1';
660 }
661
662 ak_admin_notify(__('Settings updated.', 'capability-manager-enhanced'));
663 }
664 }
665
666 include(dirname(CME_FILE) . '/includes/features/admin-features.php');
667 }
668
669 /**
670 * Manages Frontend Features
671 *
672 * @return void
673 */
674 public function ManageFrontendFeatures() {
675 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_frontend_features')) {
676 // TODO: Implement exceptions.
677 wp_die('<strong>' . esc_html__('You do not have permission to manage frontend features.', 'capability-manager-enhanced') . '</strong>');
678 }
679
680 $this->generateNames();
681 $roles = array_keys($this->roles);
682
683 if (!isset($this->current)) {
684 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
685 $this->set_current_role(sanitize_key($_REQUEST['role']));
686 }
687 }
688
689 if (!isset($this->current) || !get_role($this->current)) {
690 $this->current = get_option('default_role');
691 }
692
693 if (!in_array($this->current, $roles)) {
694 $this->current = array_shift($roles);
695 }
696
697 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-frontend-features-role']) && !empty($_REQUEST['_wpnonce'])) {
698 if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-frontend-features')) {
699 wp_die('<strong>' . esc_html__('You do not have permission to manage frontend features.', 'capability-manager-enhanced') . '</strong>');
700 } else {
701 $features_role = sanitize_key($_POST['ppc-frontend-features-role']);
702
703 $this->set_current_role($features_role);
704
705 $disabled_frontend_items = !empty(get_option('capsman_disabled_frontend_features')) ? (array)get_option('capsman_disabled_frontend_features') : [];
706 $disabled_frontend_items[$features_role] = isset($_POST['capsman_disabled_frontend_features']) ? array_map('sanitize_text_field', $_POST['capsman_disabled_frontend_features']) : '';
707
708 update_option('capsman_disabled_frontend_features', $disabled_frontend_items, false);
709
710 ak_admin_notify(__('Settings updated.', 'capability-manager-enhanced'));
711 }
712 }
713
714 include(dirname(CME_FILE) . '/includes/features/frontend-features/frontend-features.php');
715 }
716
717 /**
718 * Manage Nave Menus
719 *
720 * @return void
721 */
722 public function ManageNavMenus() {
723 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_nav_menus')) {
724 // TODO: Implement exceptions.
725 wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capability-manager-enhanced') . '</strong>');
726 }
727
728 $this->generateNames();
729 $roles = array_keys($this->roles);
730
731 if (!isset($this->current)) {
732 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
733 $this->set_current_role(sanitize_key($_REQUEST['role']));
734 }
735 }
736
737 if (!isset($this->current) || !get_role($this->current)) {
738 $this->current = get_option('default_role');
739 }
740
741 if (!in_array($this->current, $roles)) {
742 $this->current = array_shift($roles);
743 }
744
745 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-nav-menu-role']) && !empty($_REQUEST['_wpnonce'])) {
746 if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-nav-menus')) {
747 wp_die('<strong>' . esc_html__('You do not have permission to manage navigation menus.', 'capability-manager-enhanced') . '</strong>');
748 } else {
749 $menu_role = sanitize_key($_POST['ppc-nav-menu-role']);
750
751 $this->set_current_role($menu_role);
752
753 //set role nav child menu
754 $nav_item_menu_option = !empty(get_option('capsman_nav_item_menus')) ? get_option('capsman_nav_item_menus') : [];
755
756 $nav_item_menu_option[$menu_role] = isset($_POST['pp_cababilities_restricted_items']) ? array_map('sanitize_text_field', $_POST['pp_cababilities_restricted_items']) : '';
757
758 update_option('capsman_nav_item_menus', $nav_item_menu_option, false);
759
760 ak_admin_notify(__('Settings updated.', 'capability-manager-enhanced'));
761 }
762 }
763
764 include(dirname(CME_FILE) . '/includes/features/nav-menus.php');
765 }
766
767
768 /**
769 * Manages Profile Features
770 *
771 * @return void
772 */
773 public function ManageProfileFeatures() {
774 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_profile_features')) {
775 // TODO: Implement exceptions.
776 wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capability-manager-enhanced') . '</strong>');
777 }
778
779 $this->generateNames();
780 $roles = array_keys($this->roles);
781
782 if (!isset($this->current)) {
783 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
784 $this->set_current_role(sanitize_key($_REQUEST['role']));
785 }
786 }
787
788 if (!isset($this->current) || !get_role($this->current)) {
789 $this->current = get_option('default_role');
790 }
791
792 if (!in_array($this->current, $roles)) {
793 $this->current = array_shift($roles);
794 }
795
796 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-profile-features-role']) && !empty($_REQUEST['_wpnonce'])) {
797 if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-profile-features')) {
798 wp_die('<strong>' . esc_html__('You do not have permission to manage profile features.', 'capability-manager-enhanced') . '</strong>');
799 } else {
800 $features_role = sanitize_key($_POST['ppc-profile-features-role']);
801
802 $this->set_current_role($features_role);
803
804 $previous_elements = !empty(get_option('capsman_profile_features_elements')) ? (array)get_option('capsman_profile_features_elements') : [];
805 $previous_disabled_profile_items = !empty(get_option('capsman_disabled_profile_features')) ? (array)get_option('capsman_disabled_profile_features') : [];
806 $new_disabled_element = isset($_POST['capsman_disabled_profile_features']) ? array_map('sanitize_text_field', $_POST['capsman_disabled_profile_features']) : [];
807 $previous_role_disabled_element = !empty($previous_disabled_profile_items[$features_role]) ? (array)$previous_disabled_profile_items[$features_role] : [];
808 $previous_role_element = !empty($previous_elements[$features_role]) ? (array)$previous_elements[$features_role] : [];
809
810 if (!empty($previous_role_element)) {
811 $previous_role_element_items = array_column($previous_role_element, 'elements');
812 } else {
813 $previous_role_element_items = [];
814 }
815
816
817 $disabled_element_differences = array_diff($previous_role_disabled_element, $previous_role_element_items);
818 $new_disabled_element_items = array_merge($new_disabled_element, $disabled_element_differences);
819 $new_disabled_element_items = array_filter($new_disabled_element_items);
820
821 $previous_disabled_profile_items[$features_role] = $new_disabled_element_items;
822
823 update_option('capsman_disabled_profile_features', $previous_disabled_profile_items, false);
824
825 //update element sort
826 $profile_features_elements_order = !empty($_POST['capsman_profile_features_elements_order']) ? sanitize_text_field($_POST['capsman_profile_features_elements_order']) : false;
827 if ($profile_features_elements_order) {
828 $profile_features_elements_order = explode(",", $profile_features_elements_order);
829 $profile_features_elements_order = array_filter($profile_features_elements_order);
830 if (!empty($profile_features_elements_order)) {
831 $new_elements = [];
832 foreach($profile_features_elements_order as $element_key) {
833 if (isset($previous_role_element[$element_key])) {
834 $new_elements[$element_key] = $previous_role_element[$element_key];
835 }
836 }
837 $previous_elements[$features_role] = $new_elements;
838 update_option('capsman_profile_features_elements', $previous_elements, false);
839 }
840 }
841
842 ak_admin_notify(__('Settings updated.', 'capability-manager-enhanced'));
843 }
844 }
845
846 include(dirname(CME_FILE) . '/includes/features/profile-features.php');
847 }
848
849
850 /**
851 * Manage Redirect
852 *
853 * @return void
854 */
855 public function ManageRedirects() {
856 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_redirects')) {
857 // TODO: Implement exceptions.
858 wp_die('<strong>' . esc_html__('You do not have permission to manage redirect.', 'capability-manager-enhanced') . '</strong>');
859 }
860
861 $this->generateNames();
862 $roles = array_keys($this->roles);
863
864 if (!isset($this->current)) {
865 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
866 $this->set_current_role(sanitize_key($_REQUEST['role']));
867 }
868 }
869
870 if (!isset($this->current) || !get_role($this->current)) {
871 $this->current = get_option('default_role');
872 }
873
874 if (!in_array($this->current, $roles)) {
875 $this->current = array_shift($roles);
876 }
877
878 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['redirects-features-submit']) && !empty($_REQUEST['_wpnonce'])) {
879 if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-redirects-features')) {
880 wp_die('<strong>' . esc_html__('Invalid form. Reload this page and try again.', 'capability-manager-enhanced') . '</strong>');
881 } else {
882 $features_role = sanitize_key($_POST['ppc-redirects-features-role']);
883
884 $this->set_current_role($features_role);
885
886 $custom_redirect = !empty($_POST['custom_redirect']) ? (int) $_POST['custom_redirect'] : 0;
887 $referer_redirect = !empty($_POST['referer_redirect']) ? (int) $_POST['referer_redirect'] : 0;
888 $login_redirect = !empty($_POST['login_redirect']) ? home_url(str_replace(home_url(), '', sanitize_text_field($_POST['login_redirect']))) : '';
889 $logout_redirect = !empty($_POST['logout_redirect']) ? home_url(str_replace(home_url(), '', sanitize_text_field($_POST['logout_redirect']))) : '';
890 $registration_redirect = !empty($_POST['registration_redirect']) ? home_url(str_replace(home_url(), '', sanitize_text_field($_POST['registration_redirect']))) : '';
891 $first_login_redirect = !empty($_POST['first_login_redirect']) ? home_url(str_replace(home_url(), '', sanitize_text_field($_POST['first_login_redirect']))) : '';
892
893 $role_redirects = !empty(get_option('capsman_role_redirects')) ? (array)get_option('capsman_role_redirects') : [];
894
895 $role_redirects[$features_role] = [
896 'custom_redirect' => $custom_redirect,
897 'referer_redirect' => $referer_redirect,
898 'login_redirect' => $login_redirect,
899 'logout_redirect' => $logout_redirect,
900 'registration_redirect' => $registration_redirect,
901 'first_login_redirect' => $first_login_redirect
902 ];
903
904 update_option('capsman_role_redirects', $role_redirects);
905
906 ak_admin_notify(__('Settings updated.', 'capability-manager-enhanced'));
907 }
908 }
909
910 include(dirname(CME_FILE) . '/includes/redirects/redirects.php');
911 }
912
913
914
915 /**
916 * Manages Dashboard
917 *
918 * @return void
919 */
920 public function dashboardPage() {
921 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_dashboard')) {
922 // TODO: Implement exceptions.
923 wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capability-manager-enhanced') . '</strong>');
924 }
925
926 include(dirname(CME_FILE) . '/includes/dashboard.php');
927 }
928
929 /**
930 * Filters roles that can be shown in roles list.
931 * This is mainly used to prevent an user admin to create other users with
932 * higher capabilities.
933 *
934 * @hook 'editable_roles' filter.
935 *
936 * @param $roles List of roles to check.
937 * @return array Restircted roles list
938 */
939 function filterEditRoles ( $roles )
940 {
941 global $current_user;
942
943 if (function_exists('wp_get_current_user') || defined('PP_CAPABILITIES_ROLES_FILTER_EARLY_EXECUTION')) { // Avoid downstream fatal error from premature current_user_can() call if get_editable_roles() is called too early
944 $this->generateNames();
945 $valid = array_keys($this->roles);
946
947 foreach ( $roles as $role => $caps ) {
948 if ( ! in_array($role, $valid) ) {
949 unset($roles[$role]);
950 }
951 }
952 }
953
954 return $roles;
955 }
956
957 /**
958 * Checks if a user can be edited or not by current administrator.
959 * Returns array('do_not_allow') if user cannot be edited.
960 *
961 * @hook 'map_meta_cap' filter
962 *
963 * @param array $caps Current user capabilities
964 * @param string $cap Capability to check
965 * @param int $user_id Current user ID
966 * @param array $args For our purpose, we receive edited user id at $args[0]
967 * @return array Allowed capabilities.
968 */
969 function filterUserEdit ( $caps, $cap, $user_id, $args )
970 {
971 if ( ! in_array( $cap, array( 'edit_user', 'delete_user', 'promote_user', 'remove_user' ) ) || ( ! isset($args[0]) ) || $user_id == (int) $args[0] ) {
972 return $caps;
973 }
974
975 $user = new WP_User( (int) $args[0] );
976
977 $this->generateNames();
978
979 if ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) {
980 $valid = array_keys($this->roles);
981
982 foreach ( $user->roles as $role ) {
983 if ( ! in_array($role, $valid) ) {
984 $caps = array('do_not_allow');
985 break;
986 }
987 }
988 } else {
989 global $wp_roles;
990
991 foreach ( $user->roles as $role ) {
992 $r = get_role( $role );
993 $level = ak_caps2level($r->capabilities);
994
995 if ( ( ! $level ) && ( 'administrator' == $role ) )
996 $level = 10;
997
998 if ( $level > $this->max_level ) {
999 $caps = array('do_not_allow');
1000 break;
1001 }
1002 }
1003
1004 }
1005
1006 return $caps;
1007 }
1008
1009 function processRoleUpdate() {
1010 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && ( ! empty($_REQUEST['SaveRole']) || ! empty($_REQUEST['AddCap']) ) ) {
1011 check_admin_referer('capsman-general-manager');
1012
1013 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
1014 // TODO: Implement exceptions.
1015 wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capability-manager-enhanced') . '</strong>');
1016 }
1017
1018 if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
1019 $role = get_role(sanitize_key($_REQUEST['current']));
1020 $current_level = ($role) ? ak_caps2level($role->capabilities) : 0;
1021
1022 $this->processAdminGeneral();
1023
1024 $set_level = (isset($_POST['level'])) ? (int) $_POST['level'] : 0;
1025
1026 if ($set_level != $current_level) {
1027 global $wp_roles, $wp_version;
1028
1029 if ( version_compare($wp_version, '4.9', '>=') ) {
1030 $wp_roles->for_site();
1031 } else {
1032 $wp_roles->reinit();
1033 }
1034
1035 foreach( get_users(array('role' => sanitize_key($_REQUEST['current']), 'fields' => 'ID')) as $ID ) {
1036 $user = new WP_User($ID);
1037 $user->get_role_caps();
1038 $user->update_user_level_from_caps();
1039 }
1040 }
1041 }
1042 }
1043
1044 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && ( ! empty($_REQUEST['RenameRole']) ) ) {
1045 check_admin_referer('capsman-general-manager');
1046
1047 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
1048 // TODO: Implement exceptions.
1049 wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capability-manager-enhanced') . '</strong>');
1050 }
1051
1052 if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
1053 $this->processAdminGeneral();
1054 }
1055 }
1056 }
1057
1058 /**
1059 * Manages global settings admin.
1060 *
1061 * @hook add_submenu_page
1062 * @return void
1063 */
1064 function generalManager () {
1065 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
1066 // TODO: Implement exceptions.
1067 wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capability-manager-enhanced') . '</strong>');
1068 }
1069
1070 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD'])) {
1071 if ( empty($_REQUEST['SaveRole']) && empty($_REQUEST['AddCap']) && empty($_REQUEST['RenameRole']) ) {
1072 check_admin_referer('capsman-general-manager');
1073 $this->processAdminGeneral();
1074 } elseif ( ! empty($_REQUEST['SaveRole']) ) {
1075 ak_admin_notify( $this->message ); // moved update operation to earlier action to avoid UI refresh issues. But outputting notification there breaks styling.
1076 } elseif ( ! empty($_REQUEST['AddCap']) ) {
1077 ak_admin_notify( $this->message );
1078 }
1079 } else {
1080 if (!empty($_REQUEST['added'])) {
1081 ak_admin_notify(__('New capability added to role.', 'capability-manager-enhanced'));
1082 }
1083 }
1084
1085 $this->generateNames();
1086 $roles = array_keys($this->roles);
1087
1088 if ( ! isset($this->current) ) { // By default, we manage the default role
1089 if ('POST' !== $_SERVER['REQUEST_METHOD'] && !empty($_REQUEST['role'])) {
1090 $role = sanitize_key($_REQUEST['role']);
1091
1092 if (!pp_capabilities_is_editable_role($role)) {
1093 wp_die(esc_html__('The selected role is not editable.', 'capability-manager-enhanced'));
1094 }
1095
1096 $this->set_current_role($role);
1097 }
1098 }
1099
1100 if (!isset($this->current) || !get_role($this->current)) {
1101 $this->current = $this->get_last_role();
1102 }
1103
1104 if ( ! in_array($this->current, $roles) ) { // Current role has been deleted.
1105 $this->current = array_shift($roles);
1106 }
1107
1108 include ( dirname(CME_FILE) . '/includes/admin.php' );
1109 }
1110
1111 /**
1112 * Processes and saves the changes in the general capabilities form.
1113 *
1114 * @return void
1115 */
1116 private function processAdminGeneral ()
1117 {
1118 check_admin_referer('capsman-general-manager');
1119
1120 if (! isset($_POST['action']) || 'update' != $_POST['action'] ) {
1121 // TODO: Implement exceptions. This must be a fatal error.
1122 ak_admin_error(__('Bad form Received', 'capability-manager-enhanced'));
1123 return;
1124 }
1125
1126 // Select a new role.
1127 if ( ! empty($post['LoadRole']) && !empty($_POST['role']) ) {
1128 $this->set_current_role(sanitize_key($_POST['role']));
1129 } elseif (!empty($_POST['current'])) {
1130 $this->set_current_role(sanitize_key($_POST['current']));
1131
1132 require_once( dirname(__FILE__).'/handler.php' );
1133 $capsman_modify = new CapsmanHandler( $this );
1134 $capsman_modify->processAdminGeneral();
1135 }
1136
1137 //save user sidebar panel state
1138 if (!empty($_POST['ppc_metabox_state'])) {
1139 $metabox_state = map_deep($_POST['ppc_metabox_state'], 'sanitize_text_field');
1140 update_user_meta(get_current_user_id(), 'ppc_sidebar_metabox_state', $metabox_state);
1141 }
1142 }
1143
1144 /**
1145 * Callback function to create names.
1146 * Replaces underscores by spaces and uppercases the first letter.
1147 *
1148 * @access private
1149 * @param string $cap Capability name.
1150 * @return string The generated name.
1151 */
1152 function _capNamesCB ( $cap )
1153 {
1154 $cap = str_replace('_', ' ', $cap);
1155
1156 return $cap;
1157 }
1158
1159 /**
1160 * Generates an array with the system capability names.
1161 * The key is the capability and the value the created screen name.
1162 *
1163 * @uses self::_capNamesCB()
1164 * @return void
1165 */
1166 function generateSysNames ()
1167 {
1168 $this->max_level = 10;
1169 $this->roles = ak_get_roles(true);
1170 $caps = array();
1171
1172 foreach ( array_keys($this->roles) as $role ) {
1173 $role_caps = get_role($role);
1174 $caps = array_merge( $caps, (array) $role_caps->capabilities ); // user reported PHP 5.3.3 error without array cast
1175 }
1176
1177 $keys = array_keys($caps);
1178 $names = array_map(array($this, '_capNamesCB'), $keys);
1179 $this->capabilities = array_combine($keys, $names);
1180
1181 asort($this->capabilities);
1182 }
1183
1184 /**
1185 * Generates an array with the user capability names.
1186 * If user has 'administrator' role, system roles are generated.
1187 * The key is the capability and the value the created screen name.
1188 * A user cannot manage more capabilities that has himself (Except for administrators).
1189 *
1190 * @uses self::_capNamesCB()
1191 * @return void
1192 */
1193 function generateNames ()
1194 {
1195 if ( current_user_can('administrator') || ( is_multisite() && is_super_admin() ) ) {
1196 $this->generateSysNames();
1197 } else {
1198 global $user_ID;
1199 $user = new WP_User($user_ID);
1200 $this->max_level = ak_caps2level($user->allcaps);
1201
1202 $keys = array_keys($user->allcaps);
1203 $names = array_map(array($this, '_capNamesCB'), $keys);
1204
1205 $this->capabilities = ( $keys ) ? array_combine($keys, $names) : array();
1206
1207 $roles = ak_get_roles(true);
1208 unset($roles['administrator']);
1209
1210 if ( ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) || ( ! empty( $_REQUEST['page'] ) && 'pp-capabilities' == $_REQUEST['page'] ) ) {
1211 foreach ( $user->roles as $role ) { // Unset the roles from capability list.
1212 unset ( $this->capabilities[$role] );
1213 unset ( $roles[$role]); // User cannot manage his roles.
1214 }
1215 }
1216
1217 asort($this->capabilities);
1218
1219 foreach ( array_keys($roles) as $role ) {
1220 $r = get_role($role);
1221 $level = ak_caps2level($r->capabilities);
1222
1223 if ( $level > $this->max_level ) {
1224 unset($roles[$role]);
1225 }
1226 }
1227
1228 $this->roles = $roles;
1229 }
1230 }
1231
1232 /**
1233 * Manages backup, restore and resset roles and capabilities
1234 *
1235 * @hook add_management_page
1236 * @return void
1237 */
1238 function backupTool ()
1239 {
1240 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_backup')) {
1241 // TODO: Implement exceptions.
1242 wp_die('<strong>' . esc_html__('You do not have permission to restore roles.', 'capability-manager-enhanced') . '</strong>');
1243 }
1244
1245 if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD'])) {
1246 check_admin_referer('pp-capabilities-backup');
1247 require_once( dirname(__FILE__).'/backup-handler.php' );
1248 $cme_backup_handler = new Capsman_BackupHandler( $this );
1249 $cme_backup_handler->processBackupTool();
1250 }
1251
1252 if ( isset($_GET['action']) && 'reset-defaults' == $_GET['action']) {
1253 check_admin_referer('capsman-reset-defaults');
1254 require_once( dirname(__FILE__).'/backup-handler.php' );
1255 $cme_backup_handler = new Capsman_BackupHandler( $this );
1256 $cme_backup_handler->backupToolReset();
1257 }
1258
1259 include ( dirname(CME_FILE) . '/includes/backup.php' );
1260 }
1261
1262
1263 /**
1264 * Processes export.
1265 *
1266 * This function need to run in admin init
1267 * to enable clean download.
1268 *
1269 * @return void
1270 */
1271 function processExport()
1272 {
1273 global $wpdb;
1274
1275 if ( isset($_POST['export_backup']) && isset($_POST['pp_capabilities_export_section']) && !empty($_POST['pp_capabilities_export_section'])) {
1276 check_admin_referer('pp-capabilities-backup');
1277
1278 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_backup')) {
1279 // TODO: Implement exceptions.
1280 wp_die('<strong>' . esc_html__('You do not have permission to perform this action.', 'capability-manager-enhanced') . '</strong>');
1281 }
1282
1283 $export_option = array_map('sanitize_text_field', $_POST['pp_capabilities_export_section']);
1284 $backup_sections = pp_capabilities_backup_sections();
1285 $charset = get_option( 'blog_charset' );
1286 $data = [];
1287
1288 //add role
1289 if(in_array('user_roles', $export_option)){
1290 $data['user_roles'] = get_option($wpdb->prefix . 'user_roles');
1291 }
1292
1293 //other section
1294 foreach($backup_sections as $backup_key => $backup_section){
1295
1296 if(!in_array($backup_key, $export_option)){
1297 continue;
1298 }
1299 $section_options = $backup_section['options'];
1300 if(is_array($section_options) && !empty($section_options)){
1301 foreach($section_options as $section_option){
1302 $active_backup[] = $backup_section['label'];
1303 $data[$section_option] = get_option($section_option);
1304 }
1305 }
1306 }
1307
1308 // Set the download headers.
1309 nocache_headers();
1310 header( 'Content-Type: application/json; charset=' . $charset );
1311 header( 'Content-Disposition: attachment; filename=capabilities-export-' . current_time('Y-m-d_g-i-s_a') . '.json' );
1312 header( "Expires: 0" );
1313
1314 // encode the export data.
1315 echo json_encode($data);
1316
1317 // Start the download.
1318 die();
1319
1320 }
1321 }
1322
1323 function settingsPage() {
1324 include ( dirname(CME_FILE) . '/includes/settings.php' );
1325 }
1326
1327 /**
1328 * Initialize plugin capabilities class
1329 *
1330 * @return void
1331 */
1332 public function initPluginCapabilities() {
1333 require_once dirname(CME_FILE) . '/includes/plugin-capabilities.php';
1334 \PublishPress\Capabilities\Plugin_Capabilities::instance();
1335 }
1336
1337 /**
1338 * Redirect for profile features capturing
1339 *
1340 * @return void
1341 */
1342 function profileFeaturesCaptureRedirect() {
1343
1344 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities_profile_features')) {
1345 return;
1346 }
1347
1348 if (is_admin() && pp_capabilities_feature_enabled('profile-features') && !empty($_REQUEST['page']) && 'pp-capabilities-profile-features' === $_REQUEST['page']) {
1349 global $capsman, $role_has_user;
1350 $default_role = $capsman->get_last_role();
1351
1352 if (!empty($_REQUEST['role'])) {
1353 $default_role = sanitize_key($_REQUEST['role']);
1354 $this->set_current_role($default_role);
1355 }
1356
1357 $profile_element_updated = (array) get_option("capsman_profile_features_updated", []);
1358 $refresh_element = isset($_REQUEST['refresh_element']) ? (int) $_REQUEST['refresh_element'] : 0;
1359 $role_refresh = isset($_REQUEST['role_refresh']) ? (int) $_REQUEST['role_refresh'] : 0;
1360
1361 //get user in current role
1362 $role_user = get_users(
1363 [
1364 'role' => $default_role,
1365 'exclude' => [get_current_user_id()],
1366 'number' => 1,
1367 ]
1368 );
1369
1370 $role_has_user = true;
1371 if (empty($role_user) && $default_role !== 'administrator') {
1372 $role_has_user = false;
1373 }
1374
1375 if (
1376 is_array($profile_element_updated)
1377 && isset($profile_element_updated[$default_role])
1378 && (int)$profile_element_updated[$default_role] > 0
1379 ) {
1380 if ($refresh_element === 0 && $role_refresh === 0) {
1381 return;
1382 }
1383 }
1384
1385 if (!get_option('cme_profile_features_auto_redirect') && !$role_refresh) {
1386 return;
1387 }
1388
1389 if (empty($role_user) && $default_role !== 'administrator') {
1390 return;
1391 }
1392
1393 $can_redirect = true;
1394
1395 if (!empty($role_user)) {
1396 $testing_user = $role_user[0];
1397 if (!user_can($testing_user->ID, 'read')) {
1398 $can_redirect = false;
1399 }
1400
1401 }
1402
1403 if ($can_redirect) {
1404 //redirect user to test link for validation and redirection
1405 if (empty($role_user)) {
1406 $test_link = admin_url('profile.php?ppc_profile_element=1');
1407 } else {
1408 $test_as_user = $role_user[0];
1409 $test_link = add_query_arg(
1410 [
1411 'ppc_test_user' => base64_encode($test_as_user->ID),
1412 'profile_feature_action' => 1,
1413 '_wpnonce' => wp_create_nonce('ppc-test-user')
1414 ],
1415 admin_url('users.php')
1416 );
1417 }
1418 if ($refresh_element > 0) {
1419 delete_option('capsman_profile_features_updated');
1420 }
1421 update_option('capsman_profile_features_elements_testing_role', $default_role, false);
1422 wp_safe_redirect($test_link);
1423 exit();
1424 }
1425 }
1426 }
1427 }
1428
1429 function cme_publishpressFooter() {
1430 ?>
1431 <footer>
1432
1433 <div class="pp-rating">
1434 <a href="https://wordpress.org/support/plugin/capability-manager-enhanced/reviews/#new-post" target="_blank" rel="noopener noreferrer">
1435 <?php printf(
1436 esc_html__('If you like %s, please leave us a %s rating. Thank you!', 'capability-manager-enhanced'),
1437 '<strong>PublishPress Capabilities</strong>',
1438 '<span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span>'
1439 );
1440 ?>
1441 </a>
1442 </div>
1443
1444 <hr>
1445 <nav>
1446 <ul>
1447 <li><a href="https://publishpress.com/capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('About PublishPress Capabilities', 'capability-manager-enhanced');?>"><?php esc_html_e('About', 'capability-manager-enhanced');?>
1448 </a></li>
1449 <li><a href="https://publishpress.com/knowledge-base/how-to-use-capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('Capabilites Documentation', 'capability-manager-enhanced');?>"><?php esc_html_e('Documentation', 'capability-manager-enhanced');?>
1450 </a></li>
1451 <li><a href="https://publishpress.com/contact" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('Contact the PublishPress team', 'capability-manager-enhanced');?>"><?php esc_html_e('Contact', 'capability-manager-enhanced');?>
1452 </a></li>
1453 <li><a href="https://twitter.com/publishpresscom" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-twitter"></span>
1454 </a></li>
1455 <li><a href="https://facebook.com/publishpress" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-facebook"></span>
1456 </a></li>
1457 </ul>
1458 </nav>
1459
1460 <div class="pp-pressshack-logo">
1461 <a href="https://publishpress.com" target="_blank" rel="noopener noreferrer">
1462
1463 <img src="<?php echo esc_url_raw(plugins_url('', CME_FILE) . '/common/img/publishpress-logo.png');?>" />
1464 </a>
1465 </div>
1466
1467 </footer>
1468 <?php
1469 }
1470