PluginProbe ʕ •ᴥ•ʔ
PublishPress Capabilities – User Role Editor, Access Permissions, User Capabilities, Admin Menus / 2.3.1
PublishPress Capabilities – User Role Editor, Access Permissions, User Capabilities, Admin Menus v2.3.1
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
features 4 years ago roles 4 years ago admin-load.php 4 years ago admin.php 4 years ago backup-handler.php 4 years ago backup.php 4 years ago cap-helper.php 4 years ago filters-admin.php 4 years ago filters-woocommerce.php 7 years ago filters-wp_rest_workarounds.php 5 years ago filters.php 4 years ago functions-admin.php 4 years ago functions.php 4 years ago handler.php 4 years ago inflect-cme.php 7 years ago manager.php 4 years ago network.php 4 years ago pp-handler.php 4 years ago pp-ui.php 4 years ago publishpress-roles.php 5 years ago settings-handler.php 4 years ago settings.php 4 years ago
manager.php
932 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 require_once( dirname(__FILE__).'/pp-handler.php' );
41 return _cme_update_pp_usage();
42 }
43 }
44
45 // Core WP roles to apply safeguard preventing accidental lockout from dashboard
46 function _cme_core_roles() {
47 return apply_filters( 'pp_caps_core_roles', array( 'administrator', 'editor', 'revisor', 'author', 'contributor', 'subscriber' ) );
48 }
49
50 function _cme_core_caps() {
51 $core_caps = array_fill_keys( array( 'switch_themes', 'edit_themes', 'activate_plugins', 'edit_plugins', 'edit_users', 'edit_files', 'manage_options', 'moderate_comments',
52 'manage_links', 'upload_files', 'import', 'unfiltered_html', 'read', 'delete_users', 'create_users', 'unfiltered_upload', 'edit_dashboard',
53 'update_plugins', 'delete_plugins', 'install_plugins', 'update_themes', 'install_themes',
54 'update_core', 'list_users', 'remove_users', 'promote_users', 'edit_theme_options', 'delete_themes', 'export' ), true );
55
56 // @todo (possibly)
57 /*
58 if (is_multisite()) {
59 $core_caps['manage_network_plugins'] = true;
60 }
61 */
62
63 ksort( $core_caps );
64 return $core_caps;
65 }
66
67 function _cme_is_read_removal_blocked( $role_name ) {
68 $role = get_role($role_name);
69 $rcaps = $role->capabilities;
70
71 $core_caps = array_diff_key( _cme_core_caps(), array_fill_keys( array( 'unfiltered_html', 'unfiltered_upload', 'upload_files', 'edit_files', 'read' ), true ) );
72
73 if ( empty( $rcaps['dashboard_lockout_ok'] ) ) {
74 $edit_caps = array();
75 foreach ( get_post_types( array( 'public' => true ), 'object' ) as $type_obj ) {
76 $edit_caps = array_merge( $edit_caps, array_values( array_diff_key( (array) $type_obj->cap, array( 'read_private_posts' => true ) ) ) );
77 }
78
79 $edit_caps = array_fill_keys( $edit_caps, true );
80 unset( $edit_caps['read'] );
81 unset( $edit_caps['upload_files'] );
82 unset( $edit_caps['edit_files'] );
83
84 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 ) ) ) {
85 return true;
86 }
87 }
88
89 return false;
90 }
91
92 /**
93 * Class CapabilityManager.
94 * Sets the main environment for all Capability Manager components.
95 *
96 * @author Jordi Canals, Kevin Behrens
97 * @link https://publishpress.com/
98 */
99 class CapabilityManager
100 {
101 /**
102 * Array with all capabilities to be managed. (Depends on user caps).
103 * The array keys are the capability, the value is its screen name.
104 * @var array
105 */
106 var $capabilities = array();
107
108 /**
109 * Array with roles that can be managed. (Depends on user roles).
110 * The array keys are the role name, the value is its translated name.
111 * @var array
112 */
113 var $roles = array();
114
115 /**
116 * Current role we are managing
117 * @var string
118 */
119 var $current;
120
121 /**
122 * Maximum level current manager can assign to a user.
123 * @var int
124 */
125 private $max_level;
126
127 private $log_db_role_objects = array();
128
129 var $message;
130
131 /**
132 * Module ID. Is the module internal short name.
133 *
134 * @var string
135 */
136 public $ID;
137
138 public function __construct()
139 {
140 $this->ID = 'capsman';
141 $this->mod_url = plugins_url( '', CME_FILE );
142
143 if (is_admin() && !empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page']) && (!empty($_POST['all_options']) || !empty($_POST['all_options_pro']))) {
144 require_once (dirname(CME_FILE) . '/includes/settings-handler.php');
145 }
146
147 $this->moduleLoad();
148
149 add_action('admin_menu', array($this, 'adminMenus'), 5); // execute prior to PP, to use menu hook
150
151 // Load styles
152 add_action('admin_print_styles', array($this, 'adminStyles'));
153
154 if ( isset($_REQUEST['page']) && ( 'pp-capabilities' == $_REQUEST['page'] ) ) {
155 add_action('admin_enqueue_scripts', array($this, 'adminScriptsPP'));
156 }
157
158 add_action('init', [$this, 'initRolesAdmin']);
159
160 add_action('wp_ajax_pp-roles-add-role', [$this, 'handleRolesAjax']);
161 add_action('wp_ajax_pp-roles-delete-role', [$this, 'handleRolesAjax']);
162
163 if (defined('PRESSPERMIT_VERSION')) {
164 add_action('wp_ajax_pp-roles-hide-role', [$this, 'handleRolesAjax']);
165 add_action('wp_ajax_pp-roles-unhide-role', [$this, 'handleRolesAjax']);
166 }
167 }
168
169 /**
170 * Enqueues administration styles.
171 *
172 * @hook action 'admin_print_styles'
173 *
174 * @return void
175 */
176 function adminStyles()
177 {
178 if (empty($_REQUEST['page'])
179 || !in_array(
180 $_REQUEST['page'],
181 ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-admin-menus', 'pp-capabilities-nav-menus', 'pp-capabilities-editor-features', 'pp-capabilities-backup', 'pp-capabilities-settings', 'pp-capabilities-admin-features']
182 )
183 ) {
184 return;
185 }
186
187 wp_enqueue_style('cme-admin-common', $this->mod_url . '/common/css/pressshack-admin.css', [], PUBLISHPRESS_CAPS_VERSION);
188
189 wp_register_style( $this->ID . 'framework_admin', $this->mod_url . '/framework/styles/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
190 wp_enqueue_style( $this->ID . 'framework_admin');
191
192 wp_register_style( $this->ID . '_admin', $this->mod_url . '/common/css/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
193 wp_enqueue_style( $this->ID . '_admin');
194
195 $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : '';
196 $url = $this->mod_url . "/common/js/admin{$suffix}.js";
197 wp_enqueue_script( 'cme_admin', $url, array('jquery'), PUBLISHPRESS_CAPS_VERSION, true );
198 wp_localize_script( 'cme_admin', 'cmeAdmin', [
199 'negationCaption' => __( 'Explicity negate this capability by storing as disabled', 'capsman-enhanced' ),
200 'typeCapsNegationCaption' => __( 'Explicitly negate these capabilities by storing as disabled', 'capsman-enhanced' ),
201 'typeCapUnregistered' => __( 'Post type registration does not define this capability distinctly', 'capsman-enhanced' ),
202 'capNegated' => __( 'This capability is explicitly negated. Click to add/remove normally.', 'capsman-enhanced' ),
203 'chkCaption' => __( 'Add or remove this capability from the WordPress role', 'capsman-enhanced' ),
204 'switchableCaption' => __( 'Add or remove capability from the role normally', 'capsman-enhanced' ) ,
205 'deleteWarning' => __( 'Are you sure you want to delete this item ?', 'capsman-enhanced' ),
206 'saveWarning' => __( 'Add or clear custom item entry before saving changes.', 'capsman-enhanced' )
207 ]
208 );
209 }
210
211 function adminScriptsPP() {
212 wp_enqueue_style( 'plugin-install' );
213 wp_enqueue_script( 'plugin-install' );
214 add_thickbox();
215 }
216
217 /**
218 * Creates some filters at module load time.
219 *
220 * @return void
221 */
222 protected function moduleLoad ()
223 {
224 $old_version = get_option($this->ID . '_version');
225 if ( version_compare( $old_version, PUBLISHPRESS_CAPS_VERSION, 'ne') ) {
226 update_option($this->ID . '_version', PUBLISHPRESS_CAPS_VERSION);
227 $this->pluginUpdate();
228 }
229
230 // Only roles that a user can administer can be assigned to others.
231 add_filter('editable_roles', array($this, 'filterEditRoles'));
232
233 // Users with roles that cannot be managed, are not allowed to be edited.
234 add_filter('map_meta_cap', array(&$this, 'filterUserEdit'), 10, 4);
235
236 // ensure storage, retrieval of db-stored customizations to dynamic roles
237 if ( isset($_REQUEST['page']) && in_array( $_REQUEST['page'], array( 'pp-capabilities', 'pp-capabilities-backup' ) ) ) {
238 global $wpdb;
239 $role_key = $wpdb->prefix . 'user_roles';
240 $this->log_db_roles();
241 add_filter( 'option_' . $role_key, array( &$this, 'reinstate_db_roles' ), PHP_INT_MAX );
242 }
243
244 add_filter( 'plugins_loaded', array( &$this, 'processRoleUpdate' ) );
245 }
246
247 public function set_current_role($role_name) {
248 global $current_user;
249
250 if ($role_name && !empty($current_user) && !empty($current_user->ID)) {
251 update_option("capsman_last_role_{$current_user->ID}", $role_name);
252 }
253 }
254
255 public function get_last_role() {
256 global $current_user;
257
258 $role_name = get_option("capsman_last_role_{$current_user->ID}");
259
260 if (!$role_name || !get_role($role_name)) {
261 $role_name = get_option('default_role');
262 }
263
264 return $role_name;
265 }
266
267 // Direct query of stored role definitions
268 function log_db_roles( $legacy_arg = '' ) {
269 global $wpdb;
270
271 $results = (array) maybe_unserialize( $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = '{$wpdb->prefix}user_roles' LIMIT 1") );
272 foreach( $results as $_role_name => $_role ) {
273 $this->log_db_role_objects[$_role_name] = (object) $_role;
274 }
275
276 return $legacy_arg;
277 }
278
279 // note: this is only applied when accessing the cme role edit form
280 function reinstate_db_roles( $passthru_roles = array() ) {
281 global $wp_roles;
282
283 if ( isset($wp_roles) && $this->log_db_role_objects ) {
284 $intersect = array_intersect_key( $wp_roles->role_objects, $this->log_db_role_objects );
285 foreach( array_keys( $intersect ) as $key ) {
286 if ( ! empty( $this->log_db_role_objects[$key]->capabilities ) )
287 $wp_roles->role_objects[$key]->capabilities = $this->log_db_role_objects[$key]->capabilities;
288 }
289 }
290
291 return $passthru_roles;
292 }
293
294 /**
295 * Updates Capability Manager to a new version
296 *
297 * @return void
298 */
299 protected function pluginUpdate ()
300 {
301 global $wpdb;
302
303 $backup = get_option($this->ID . '_backup');
304 if ( false === $backup ) { // No previous backup found. Save it!
305 global $wpdb;
306 $roles = get_option($wpdb->prefix . 'user_roles');
307 update_option( $this->ID . '_backup', $roles, false );
308 update_option( $this->ID . '_backup_datestamp', current_time( 'timestamp' ), false );
309 }
310
311 if (!$wpdb->get_var("SELECT COUNT(option_id) FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%'")) {
312 pp_capabilities_autobackup();
313 }
314 }
315
316 /**
317 * Adds admin panel menus. (At plugins loading time. This is before plugins_loaded).
318 * User needs to have 'manage_capabilities' to access this menus.
319 * This is set as an action in the parent class constructor.
320 *
321 * @hook action admin_menu
322 * @return void
323 */
324 public function adminMenus ()
325 {
326 // First we check if user is administrator and can 'manage_capabilities'.
327 if ( current_user_can('administrator') && ! current_user_can('manage_capabilities') ) {
328 $this->setAdminCapability();
329 }
330
331 add_action( 'admin_menu', array( &$this, 'cme_menu' ), 18 );
332 }
333
334 public function cme_menu() {
335 $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
336
337 $permissions_title = __('Capabilities', 'capsman-enhanced');
338
339 $menu_order = 72;
340
341 if (defined('PUBLISHPRESS_PERMISSIONS_MENU_GROUPING')) {
342 foreach ((array)get_option('active_plugins') as $plugin_file) {
343 if ( false !== strpos($plugin_file, 'publishpress.php') ) {
344 $menu_order = 27;
345 }
346 }
347 }
348
349 add_menu_page(
350 $permissions_title,
351 $permissions_title,
352 $cap_name,
353 'pp-capabilities',
354 array($this, 'generalManager'),
355 'dashicons-admin-network',
356 $menu_order
357 );
358
359 $hook = add_submenu_page('pp-capabilities', __('Roles', 'capsman-enhanced'), __('Roles', 'capsman-enhanced'), $cap_name, 'pp-capabilities-roles', [$this, 'ManageRoles']);
360
361 if (!empty($hook)) {
362 add_action(
363 "load-$hook",
364 function() {
365 require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
366 admin_roles_page_load();
367 }
368 );
369 }
370
371 add_submenu_page('pp-capabilities', __('Editor Features', 'capsman-enhanced'), __('Editor Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-editor-features', [$this, 'ManageEditorFeatures']);
372
373 add_submenu_page('pp-capabilities', __('Admin Features', 'capsman-enhanced'), __('Admin Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-features', [$this, 'ManageAdminFeatures']);
374
375 do_action('pp-capabilities-admin-submenus');
376
377 add_submenu_page('pp-capabilities', __('Backup', 'capsman-enhanced'), __('Backup', 'capsman-enhanced'), $cap_name, 'pp-capabilities-backup', array($this, 'backupTool'));
378
379 if (defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
380 add_submenu_page('pp-capabilities', __('Settings', 'capsman-enhanced'), __('Settings', 'capsman-enhanced'), $cap_name, 'pp-capabilities-settings', array($this, 'settingsPage'));
381 }
382
383 if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
384 add_submenu_page(
385 'pp-capabilities',
386 __('Upgrade to Pro', 'capsman-enhanced'),
387 __('Upgrade to Pro', 'capsman-enhanced'),
388 'manage_capabilities',
389 'capsman-enhanced',
390 array($this, 'generalManager')
391 );
392 }
393 }
394
395 function initRolesAdmin() {
396 // @todo: solve order of execution issue so this column headers definition is not duplicated
397 if (!empty($_REQUEST['page']) && ('pp-capabilities-roles' == $_REQUEST['page'])) {
398 add_filter(
399 "manage_capabilities_page_pp-capabilities-roles_columns",
400
401 function($arr) {
402 return [
403 'cb' => '<input type="checkbox"/>',
404 'name' => __('Name', 'capsman-enhanced'),
405 'role' => __('Role', 'capsman-enhanced'),
406 'count' => __('Users', 'capsman-enhanced'),
407 ];
408 }
409 );
410 }
411 }
412
413 function handleRolesAjax() {
414 require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
415
416 if (!class_exists('PP_Capabilities_Roles')) {
417 require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
418 }
419
420 $roles = pp_capabilities_roles()->run();
421 }
422
423 /**
424 * Manages roles
425 *
426 * @hook add_management_page
427 * @return void
428 */
429 public function ManageRoles ()
430 {
431 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
432 // TODO: Implement exceptions.
433 wp_die('<strong>' .__('You do not have permission to manage roles.', 'capsman-enhanced') . '</strong>');
434 }
435
436 require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
437
438 if (!class_exists('PP_Capabilities_Roles')) {
439 require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
440 }
441
442 $roles = pp_capabilities_roles()->run();
443
444 require_once ( dirname(CME_FILE) . '/includes/roles/roles.php' );
445 }
446
447
448 /**
449 * Manages Editor Features
450 *
451 * @return void
452 */
453 public function ManageEditorFeatures() {
454 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
455 // TODO: Implement exceptions.
456 wp_die('<strong>' .__('You do not have permission to manage editor features.', 'capabilities-pro') . '</strong>');
457 }
458
459 $this->generateNames();
460 $roles = array_keys($this->roles);
461
462 if (!isset($this->current)) {
463 if (empty($_POST) && !empty($_REQUEST['role'])) {
464 $this->set_current_role($_REQUEST['role']);
465 }
466 }
467
468 if (!isset($this->current) || !get_role($this->current)) {
469 $this->current = get_option('default_role');
470 }
471
472 if (!in_array($this->current, $roles)) {
473 $this->current = array_shift($roles);
474 }
475
476 if ('POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['ppc-editor-features-role'])) {
477 $this->set_current_role($_POST['ppc-editor-features-role']);
478
479 $classic_editor = pp_capabilities_is_classic_editor_available();
480
481 //$def_post_types = apply_filters('pp_capabilities_feature_post_types', get_post_types(['public' => true]));
482 $def_post_types = apply_filters('pp_capabilities_feature_post_types', ['post', 'page']);
483
484 foreach ($def_post_types as $post_type) {
485 if ($classic_editor) {
486 $posted_settings = (isset($_POST["capsman_feature_restrict_classic_{$post_type}"])) ? $_POST["capsman_feature_restrict_classic_{$post_type}"] : [];
487 $post_features_option = get_option("capsman_feature_restrict_classic_{$post_type}", []);
488 $post_features_option[$_POST['ppc-editor-features-role']] = $posted_settings;
489 update_option("capsman_feature_restrict_classic_{$post_type}", $post_features_option, false);
490 }
491
492 $posted_settings = (isset($_POST["capsman_feature_restrict_{$post_type}"])) ? $_POST["capsman_feature_restrict_{$post_type}"] : [];
493 $post_features_option = get_option("capsman_feature_restrict_{$post_type}", []);
494 $post_features_option[$_POST['ppc-editor-features-role']] = $posted_settings;
495 update_option("capsman_feature_restrict_{$post_type}", $post_features_option, false);
496 }
497
498 ak_admin_notify(__('Settings updated.', 'capabilities-pro'));
499 }
500
501 do_action('pp_capabilities_editor_features');
502 include(dirname(CME_FILE) . '/includes/features/editor-features.php');
503 }
504
505 /**
506 * Manages Admin Features
507 *
508 * @return void
509 */
510 public function ManageAdminFeatures() {
511 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
512 // TODO: Implement exceptions.
513 wp_die('<strong>' .__('You do not have permission to manage admin features.', 'capabilities-pro') . '</strong>');
514 }
515
516 $this->generateNames();
517 $roles = array_keys($this->roles);
518
519 if (!isset($this->current)) {
520 if (empty($_POST) && !empty($_REQUEST['role'])) {
521 $this->set_current_role($_REQUEST['role']);
522 }
523 }
524
525 if (!isset($this->current) || !get_role($this->current)) {
526 $this->current = get_option('default_role');
527 }
528
529 if (!in_array($this->current, $roles)) {
530 $this->current = array_shift($roles);
531 }
532
533 if ('POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['ppc-admin-features-role'])) {
534 $this->set_current_role($_POST['ppc-admin-features-role']);
535
536 $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
537 $disabled_admin_items[$_POST['ppc-admin-features-role']] = isset($_POST['capsman_disabled_admin_features']) ? $_POST['capsman_disabled_admin_features'] : '';
538
539 update_option('capsman_disabled_admin_features', $disabled_admin_items, false);
540
541 //set reload option for instant reflection if user is updating own role
542 if(in_array($_POST['ppc-admin-features-role'], wp_get_current_user()->roles)){
543 $ppc_page_reload = '1';
544 }
545
546 ak_admin_notify(__('Settings updated.', 'capabilities-pro'));
547 }
548
549 include(dirname(CME_FILE) . '/includes/features/admin-features.php');
550 }
551
552 /**
553 * Sets the 'manage_capabilities' cap to the administrator role.
554 *
555 * @return void
556 */
557 public function setAdminCapability ()
558 {
559 if ($admin = get_role('administrator')) {
560 $admin->add_cap('manage_capabilities');
561 }
562 }
563
564 /**
565 * Filters roles that can be shown in roles list.
566 * This is mainly used to prevent an user admin to create other users with
567 * higher capabilities.
568 *
569 * @hook 'editable_roles' filter.
570 *
571 * @param $roles List of roles to check.
572 * @return array Restircted roles list
573 */
574 function filterEditRoles ( $roles )
575 {
576 global $current_user;
577
578 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
579 $this->generateNames();
580 $valid = array_keys($this->roles);
581
582 foreach ( $roles as $role => $caps ) {
583 if ( ! in_array($role, $valid) ) {
584 unset($roles[$role]);
585 }
586 }
587 }
588
589 return $roles;
590 }
591
592 /**
593 * Checks if a user can be edited or not by current administrator.
594 * Returns array('do_not_allow') if user cannot be edited.
595 *
596 * @hook 'map_meta_cap' filter
597 *
598 * @param array $caps Current user capabilities
599 * @param string $cap Capability to check
600 * @param int $user_id Current user ID
601 * @param array $args For our purpose, we receive edited user id at $args[0]
602 * @return array Allowed capabilities.
603 */
604 function filterUserEdit ( $caps, $cap, $user_id, $args )
605 {
606 if ( ! in_array( $cap, array( 'edit_user', 'delete_user', 'promote_user', 'remove_user' ) ) || ( ! isset($args[0]) ) || $user_id == (int) $args[0] ) {
607 return $caps;
608 }
609
610 $user = new WP_User( (int) $args[0] );
611
612 $this->generateNames();
613
614 if ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) {
615 $valid = array_keys($this->roles);
616
617 foreach ( $user->roles as $role ) {
618 if ( ! in_array($role, $valid) ) {
619 $caps = array('do_not_allow');
620 break;
621 }
622 }
623 } else {
624 global $wp_roles;
625
626 foreach ( $user->roles as $role ) {
627 $r = get_role( $role );
628 $level = ak_caps2level($r->capabilities);
629
630 if ( ( ! $level ) && ( 'administrator' == $role ) )
631 $level = 10;
632
633 if ( $level > $this->max_level ) {
634 $caps = array('do_not_allow');
635 break;
636 }
637 }
638
639 }
640
641 return $caps;
642 }
643
644 function processRoleUpdate() {
645 if ( 'POST' == $_SERVER['REQUEST_METHOD'] && ( ! empty($_REQUEST['SaveRole']) || ! empty($_REQUEST['AddCap']) ) ) {
646 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
647 // TODO: Implement exceptions.
648 wp_die('<strong>' .__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
649 }
650
651 if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
652 check_admin_referer('capsman-general-manager');
653
654 $role = get_role($_REQUEST['current']);
655 $current_level = ($role) ? ak_caps2level($role->capabilities) : 0;
656
657 $this->processAdminGeneral();
658
659 $set_level = (isset($_POST['level'])) ? $_POST['level'] : 0;
660
661 if ($set_level != $current_level) {
662 global $wp_roles, $wp_version;
663
664 if ( version_compare($wp_version, '4.9', '>=') ) {
665 $wp_roles->for_site();
666 } else {
667 $wp_roles->reinit();
668 }
669
670 foreach( get_users(array('role' => $_REQUEST['current'], 'fields' => 'ID')) as $ID ) {
671 $user = new WP_User($ID);
672 $user->get_role_caps();
673 $user->update_user_level_from_caps();
674 }
675 }
676 }
677 }
678 }
679
680 /**
681 * Manages global settings admin.
682 *
683 * @hook add_submenu_page
684 * @return void
685 */
686 function generalManager () {
687 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
688 // TODO: Implement exceptions.
689 wp_die('<strong>' .__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
690 }
691
692 if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
693 if ( empty($_REQUEST['SaveRole']) && empty($_REQUEST['AddCap']) ) {
694 check_admin_referer('capsman-general-manager');
695 $this->processAdminGeneral();
696 } elseif ( ! empty($_REQUEST['SaveRole']) ) {
697 ak_admin_notify( $this->message ); // moved update operation to earlier action to avoid UI refresh issues. But outputting notification there breaks styling.
698 } elseif ( ! empty($_REQUEST['AddCap']) ) {
699 ak_admin_notify( $this->message );
700 }
701 } else {
702 if (!empty($_REQUEST['added'])) {
703 ak_admin_notify(__('New capability added to role.'));
704 }
705 }
706
707 $this->generateNames();
708 $roles = array_keys($this->roles);
709
710 if ( isset($_GET['action']) && 'delete' == $_GET['action']) {
711 require_once( dirname(__FILE__).'/handler.php' );
712 $capsman_modify = new CapsmanHandler( $this );
713 $capsman_modify->adminDeleteRole();
714 }
715
716 if ( ! isset($this->current) ) { // By default, we manage the default role
717 if (empty($_POST) && !empty($_REQUEST['role'])) {
718 $role = $_REQUEST['role'];
719
720 if (!pp_capabilities_is_editable_role($role)) {
721 wp_die(__('The selected role is not editable.', 'capsman-enhanced'));
722 }
723
724 $this->set_current_role($role);
725 }
726 }
727
728 if (!isset($this->current) || !get_role($this->current)) {
729 $this->current = $this->get_last_role();
730 }
731
732 if ( ! in_array($this->current, $roles) ) { // Current role has been deleted.
733 $this->current = array_shift($roles);
734 }
735
736 include ( dirname(CME_FILE) . '/includes/admin.php' );
737 }
738
739 /**
740 * Processes and saves the changes in the general capabilities form.
741 *
742 * @return void
743 */
744 private function processAdminGeneral ()
745 {
746 if (! isset($_POST['action']) || 'update' != $_POST['action'] ) {
747 // TODO: Implement exceptions. This must be a fatal error.
748 ak_admin_error(__('Bad form Received', 'capsman-enhanced'));
749 return;
750 }
751
752 $post = stripslashes_deep($_POST);
753 if ( empty ($post['caps']) ) {
754 $post['caps'] = array();
755 }
756
757 // Select a new role.
758 if ( ! empty($post['LoadRole']) ) {
759 $this->set_current_role($post['role']);
760 } else {
761 $this->set_current_role($post['current']);
762
763 require_once( dirname(__FILE__).'/handler.php' );
764 $capsman_modify = new CapsmanHandler( $this );
765 $capsman_modify->processAdminGeneral( $post );
766 }
767 }
768
769 /**
770 * Callback function to create names.
771 * Replaces underscores by spaces and uppercases the first letter.
772 *
773 * @access private
774 * @param string $cap Capability name.
775 * @return string The generated name.
776 */
777 function _capNamesCB ( $cap )
778 {
779 $cap = str_replace('_', ' ', $cap);
780 //$cap = ucfirst($cap);
781
782 return $cap;
783 }
784
785 /**
786 * Generates an array with the system capability names.
787 * The key is the capability and the value the created screen name.
788 *
789 * @uses self::_capNamesCB()
790 * @return void
791 */
792 function generateSysNames ()
793 {
794 $this->max_level = 10;
795 $this->roles = ak_get_roles(true);
796 $caps = array();
797
798 foreach ( array_keys($this->roles) as $role ) {
799 $role_caps = get_role($role);
800 $caps = array_merge( $caps, (array) $role_caps->capabilities ); // user reported PHP 5.3.3 error without array cast
801 }
802
803 $keys = array_keys($caps);
804 $names = array_map(array($this, '_capNamesCB'), $keys);
805 $this->capabilities = array_combine($keys, $names);
806
807 asort($this->capabilities);
808 }
809
810 /**
811 * Generates an array with the user capability names.
812 * If user has 'administrator' role, system roles are generated.
813 * The key is the capability and the value the created screen name.
814 * A user cannot manage more capabilities that has himself (Except for administrators).
815 *
816 * @uses self::_capNamesCB()
817 * @return void
818 */
819 function generateNames ()
820 {
821 if ( current_user_can('administrator') || ( is_multisite() && is_super_admin() ) ) {
822 $this->generateSysNames();
823 } else {
824 global $user_ID;
825 $user = new WP_User($user_ID);
826 $this->max_level = ak_caps2level($user->allcaps);
827
828 $keys = array_keys($user->allcaps);
829 $names = array_map(array($this, '_capNamesCB'), $keys);
830
831 $this->capabilities = ( $keys ) ? array_combine($keys, $names) : array();
832
833 $roles = ak_get_roles(true);
834 unset($roles['administrator']);
835
836 if ( ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) || ( ! empty( $_REQUEST['page'] ) && 'pp-capabilities' == $_REQUEST['page'] ) ) {
837 foreach ( $user->roles as $role ) { // Unset the roles from capability list.
838 unset ( $this->capabilities[$role] );
839 unset ( $roles[$role]); // User cannot manage his roles.
840 }
841 }
842
843 asort($this->capabilities);
844
845 foreach ( array_keys($roles) as $role ) {
846 $r = get_role($role);
847 $level = ak_caps2level($r->capabilities);
848
849 if ( $level > $this->max_level ) {
850 unset($roles[$role]);
851 }
852 }
853
854 $this->roles = $roles;
855 }
856 }
857
858 /**
859 * Manages backup, restore and resset roles and capabilities
860 *
861 * @hook add_management_page
862 * @return void
863 */
864 function backupTool ()
865 {
866 if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles')) {
867 // TODO: Implement exceptions.
868 wp_die('<strong>' .__('You do not have permission to restore roles.', 'capsman-enhanced') . '</strong>');
869 }
870
871 if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
872 require_once( dirname(__FILE__).'/backup-handler.php' );
873 $cme_backup_handler = new Capsman_BackupHandler( $this );
874 $cme_backup_handler->processBackupTool();
875 }
876
877 if ( isset($_GET['action']) && 'reset-defaults' == $_GET['action']) {
878 require_once( dirname(__FILE__).'/backup-handler.php' );
879 $cme_backup_handler = new Capsman_BackupHandler( $this );
880 $cme_backup_handler->backupToolReset();
881 }
882
883 include ( dirname(CME_FILE) . '/includes/backup.php' );
884 }
885
886 function settingsPage() {
887 include ( dirname(CME_FILE) . '/includes/settings.php' );
888 }
889 }
890
891 function cme_publishpressFooter() {
892 ?>
893 <footer>
894
895 <div class="pp-rating">
896 <a href="https://wordpress.org/support/plugin/capability-manager-enhanced/reviews/#new-post" target="_blank" rel="noopener noreferrer">
897 <?php printf(
898 __('If you like %s, please leave us a %s rating. Thank you!', 'capsman-enhanced'),
899 '<strong>PublishPress Capabilities</strong>',
900 '<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>'
901 );
902 ?>
903 </a>
904 </div>
905
906 <hr>
907 <nav>
908 <ul>
909 <li><a href="https://publishpress.com/capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php _e('About PublishPress Capabilities', 'capsman-enhanced');?>"><?php _e('About', 'capsman-enhanced');?>
910 </a></li>
911 <li><a href="https://publishpress.com/knowledge-base/how-to-use-capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php _e('Capabilites Documentation', 'capsman-enhanced');?>"><?php _e('Documentation', 'capsman-enhanced');?>
912 </a></li>
913 <li><a href="https://publishpress.com/contact" target="_blank" rel="noopener noreferrer" title="<?php _e('Contact the PublishPress team', 'capsman-enhanced');?>"><?php _e('Contact', 'capsman-enhanced');?>
914 </a></li>
915 <li><a href="https://twitter.com/publishpresscom" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-twitter"></span>
916 </a></li>
917 <li><a href="https://facebook.com/publishpress" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-facebook"></span>
918 </a></li>
919 </ul>
920 </nav>
921
922 <div class="pp-pressshack-logo">
923 <a href="https://publishpress.com" target="_blank" rel="noopener noreferrer">
924
925 <img src="<?php echo plugins_url('', CME_FILE) . '/common/img/publishpress-logo.png';?>" />
926 </a>
927 </div>
928
929 </footer>
930 <?php
931 }
932