diff --git a/capsman-enhanced.php b/capsman-enhanced.php index 76bc572f..e20e42a0 100644 --- a/capsman-enhanced.php +++ b/capsman-enhanced.php @@ -142,7 +142,7 @@ function cme_submenus() { $cap_name = ( is_super_admin() ) ? 'manage_capabilities' : 'restore_roles'; add_management_page(__('Capability Manager', 'capsman-enhanced'), __('Capability Manager', 'capsman-enhanced'), $cap_name, 'capsman' . '-tool', 'cme_fakefunc'); - if ( did_action( 'pp_admin_menu' ) ) { // Put Capabilities link on Permissions menu if Press Permit is active and user has access to it + if (did_action('pp_admin_menu')) { // Put Capabilities link on Permissions menu if Press Permit is active and user has access to it global $pp_admin; $menu_caption = ( defined('WPLANG') && WPLANG && ( 'en_EN' != WPLANG ) ) ? __('Capabilities', 'capsman-enhanced') : 'Role Capabilities'; add_submenu_page( $pp_admin->get_menu('options'), __('Capability Manager', 'capsman-enhanced'), $menu_caption, 'manage_capabilities', 'capsman', 'cme_fakefunc' ); diff --git a/includes/admin.php b/includes/admin.php index d4cb8334..2ecd0f39 100644 --- a/includes/admin.php +++ b/includes/admin.php @@ -267,7 +267,7 @@ ); $type_caps = array(); $type_metacaps = array(); - + // Role Scoper and PP1 adjust attachment access based only on user's capabilities for the parent post if ( defined('OLD_PRESSPERMIT_ACTIVE') ) { unset( $defined['type']['attachment'] ); @@ -299,131 +299,131 @@ if ( ! $any_term_deletion_caps ) continue; } - - if ( ! count( $cap_properties[$cap_type][$item_type] ) ) - continue; - - echo ''; + + if ( ! count( $cap_properties[$cap_type][$item_type] ) ) + continue; + + echo '
'; - echo ''; + echo ''; + + // label cap properties + foreach( $cap_properties[$cap_type][$item_type] as $prop ) { + $prop = str_replace( '_posts', '', $prop ); + $prop = str_replace( '_pages', '', $prop ); + $prop = str_replace( '_terms', '', $prop ); + $tip = ( isset( $cap_tips[$prop] ) ) ? "title='{$cap_tips[$prop]}'" : ''; + $prop = str_replace( '_', '
', $prop ); + $th_class = ( 'taxonomy' == $item_type ) ? ' class="term-cap"' : ' class="post-cap"'; + echo "'; + if ( ( 'delete' != $prop ) || ( 'taxonomy' != $item_type ) || cme_get_detailed_taxonomies() ) { + echo ucwords($prop); } + + echo ''; + } - echo ''; + echo ''; - foreach( $defined[$item_type] as $key => $type_obj ) { - if ( in_array( $key, $unfiltered[$item_type] ) ) - continue; + foreach( $defined[$item_type] as $key => $type_obj ) { + if ( in_array( $key, $unfiltered[$item_type] ) ) + continue; - $row = ""; - - if ( $cap_type ) { - if ( empty($force_distinct_ui) && empty( $cap_properties[$cap_type][$item_type] ) ) - continue; + $row = ""; + + if ( $cap_type ) { + if ( empty($force_distinct_ui) && empty( $cap_properties[$cap_type][$item_type] ) ) + continue; + + $row .= "'; - $row .= "'; - - $display_row = ! empty($force_distinct_ui); + $display_row = ! empty($force_distinct_ui); - foreach( $cap_properties[$cap_type][$item_type] as $prop ) { - $td_classes = array(); - $checkbox = ''; - $title = ''; + foreach( $cap_properties[$cap_type][$item_type] as $prop ) { + $td_classes = array(); + $checkbox = ''; + $title = ''; + + if ( ! empty($type_obj->cap->$prop) && ( in_array( $type_obj->name, array( 'post', 'page' ) ) + || ! in_array( $type_obj->cap->$prop, $default_caps ) + || ( ( 'manage_categories' == $type_obj->cap->$prop ) && ( 'manage_terms' == $prop ) && ( 'category' == $type_obj->name ) ) ) ) { + + // if edit_published or edit_private cap is same as edit_posts cap, don't display a checkbox for it + if ( ( ! in_array( $prop, array( 'edit_published_posts', 'edit_private_posts', 'create_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->edit_posts ) ) + && ( ! in_array( $prop, array( 'delete_published_posts', 'delete_private_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->delete_posts ) ) + && ( ! in_array( $prop, array( 'edit_terms', 'delete_terms' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->manage_terms ) ) - if ( ! empty($type_obj->cap->$prop) && ( in_array( $type_obj->name, array( 'post', 'page' ) ) - || ! in_array( $type_obj->cap->$prop, $default_caps ) - || ( ( 'manage_categories' == $type_obj->cap->$prop ) && ( 'manage_terms' == $prop ) && ( 'category' == $type_obj->name ) ) ) ) { - - // if edit_published or edit_private cap is same as edit_posts cap, don't display a checkbox for it - if ( ( ! in_array( $prop, array( 'edit_published_posts', 'edit_private_posts', 'create_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->edit_posts ) ) - && ( ! in_array( $prop, array( 'delete_published_posts', 'delete_private_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->delete_posts ) ) - && ( ! in_array( $prop, array( 'edit_terms', 'delete_terms' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->manage_terms ) ) + && ( ! in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) ) + || empty($cme_cap_helper->all_taxonomy_caps[$type_obj->cap->$prop]) + || ( $cme_cap_helper->all_taxonomy_caps[ $type_obj->cap->$prop ] <= 1 ) + || $type_obj->cap->$prop == str_replace( '_terms', "_{$type_obj->name}s", $prop ) + || $type_obj->cap->$prop == str_replace( '_terms', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop ) + ) + + && ( in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) ) + || empty($cme_cap_helper->all_type_caps[$type_obj->cap->$prop]) + || ( $cme_cap_helper->all_type_caps[ $type_obj->cap->$prop ] <= 1 ) + || $type_obj->cap->$prop == 'upload_files' && 'create_posts' == $prop && 'attachment' == $type_obj->name + || $type_obj->cap->$prop == str_replace( '_posts', "_{$type_obj->name}s", $prop ) + || $type_obj->cap->$prop == str_replace( '_pages', "_{$type_obj->name}s", $prop ) + || $type_obj->cap->$prop == str_replace( '_posts', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop ) + || $type_obj->cap->$prop == str_replace( '_pages', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop ) + ) + ) { + // only present these term caps up top if we are ensuring that they get enforced separately from manage_terms + if ( in_array( $prop, array( 'edit_terms', 'delete_terms', 'assign_terms' ) ) && ( ! in_array( $type_obj->name, cme_get_detailed_taxonomies() ) || defined( 'OLD_PRESSPERMIT_ACTIVE' ) ) ) { + continue; + } - && ( ! in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) ) - || empty($cme_cap_helper->all_taxonomy_caps[$type_obj->cap->$prop]) - || ( $cme_cap_helper->all_taxonomy_caps[ $type_obj->cap->$prop ] <= 1 ) - || $type_obj->cap->$prop == str_replace( '_terms', "_{$type_obj->name}s", $prop ) - || $type_obj->cap->$prop == str_replace( '_terms', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop ) - ) + $cap_name = $type_obj->cap->$prop; - && ( in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) ) - || empty($cme_cap_helper->all_type_caps[$type_obj->cap->$prop]) - || ( $cme_cap_helper->all_type_caps[ $type_obj->cap->$prop ] <= 1 ) - || $type_obj->cap->$prop == 'upload_files' && 'create_posts' == $prop && 'attachment' == $type_obj->name - || $type_obj->cap->$prop == str_replace( '_posts', "_{$type_obj->name}s", $prop ) - || $type_obj->cap->$prop == str_replace( '_pages', "_{$type_obj->name}s", $prop ) - || $type_obj->cap->$prop == str_replace( '_posts', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop ) - || $type_obj->cap->$prop == str_replace( '_pages', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop ) - ) - ) { - // only present these term caps up top if we are ensuring that they get enforced separately from manage_terms - if ( in_array( $prop, array( 'edit_terms', 'delete_terms', 'assign_terms' ) ) && ( ! in_array( $type_obj->name, cme_get_detailed_taxonomies() ) || defined( 'OLD_PRESSPERMIT_ACTIVE' ) ) ) { - continue; + if ( 'taxonomy' == $item_type ) + $td_classes []= "term-cap"; + else + $td_classes []= "post-cap"; + + if ( ! empty($pp_metagroup_caps[$cap_name]) ) + $td_classes []='cm-has-via-pp'; + + if ( $is_administrator || current_user_can($cap_name) ) { + if ( ! empty($pp_metagroup_caps[$cap_name]) ) { + $title_text = sprintf( __( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name ); + } else { + $title_text = $cap_name; } - $cap_name = $type_obj->cap->$prop; + $disabled = ''; + $checked = checked(1, ! empty($rcaps[$cap_name]), false ); - if ( 'taxonomy' == $item_type ) - $td_classes []= "term-cap"; - else - $td_classes []= "post-cap"; + $checkbox = ''; - if ( ! empty($pp_metagroup_caps[$cap_name]) ) - $td_classes []='cm-has-via-pp'; - - if ( $is_administrator || current_user_can($cap_name) ) { - if ( ! empty($pp_metagroup_caps[$cap_name]) ) { - $title_text = sprintf( __( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name ); - } else { - $title_text = $cap_name; - } - - $disabled = ''; - $checked = checked(1, ! empty($rcaps[$cap_name]), false ); - - $checkbox = ''; - - $type_caps [$cap_name] = true; - $display_row = true; - } - } else { - //$td_classes []= "cap-unreg"; - $title = 'title="' . sprintf( __( 'shared capability: %s', 'capsman-enhanced' ), esc_attr( $type_obj->cap->$prop ) ) . '"'; - } - - if ( isset($rcaps[$cap_name]) && empty($rcaps[$cap_name]) ) { - $td_classes []= "cap-neg"; - } + $type_caps [$cap_name] = true; + $display_row = true; + } } else { - $td_classes []= "cap-unreg"; + //$td_classes []= "cap-unreg"; + $title = 'title="' . sprintf( __( 'shared capability: %s', 'capsman-enhanced' ), esc_attr( $type_obj->cap->$prop ) ) . '"'; } - $td_class = ( $td_classes ) ? 'class="' . implode(' ', $td_classes) . '"' : ''; - - $row .= ""; + if ( isset($rcaps[$cap_name]) && empty($rcaps[$cap_name]) ) { + $td_classes []= "cap-neg"; + } + } else { + $td_classes []= "cap-unreg"; } + + $td_class = ( $td_classes ) ? 'class="' . implode(' ', $td_classes) . '"' : ''; + + $row .= ""; + } if ('type' == $item_type) { $type_metacaps[$type_obj->cap->read_post] = true; @@ -433,15 +433,15 @@ $type_metacaps[$type_obj->cap->edit_term] = true; $type_metacaps[$type_obj->cap->delete_term] = true; } - } + } - if ( $display_row ) { - $row .= ''; - echo $row; - } + if ( $display_row ) { + $row .= ''; + echo $row; } + } - echo '
"; - // label cap properties - foreach( $cap_properties[$cap_type][$item_type] as $prop ) { - $prop = str_replace( '_posts', '', $prop ); - $prop = str_replace( '_pages', '', $prop ); - $prop = str_replace( '_terms', '', $prop ); - $tip = ( isset( $cap_tips[$prop] ) ) ? "title='{$cap_tips[$prop]}'" : ''; - $prop = str_replace( '_', '
', $prop ); - $th_class = ( 'taxonomy' == $item_type ) ? ' class="term-cap"' : ' class="post-cap"'; - echo "
"; - - if ( ( 'delete' != $prop ) || ( 'taxonomy' != $item_type ) || cme_get_detailed_taxonomies() ) { - echo ucwords($prop); - } - - echo '
" . $type_obj->labels->name . ''; + $row .= ' x '; + $row .= '" . $type_obj->labels->name . ''; - $row .= ' x '; - $row .= 'X$checkbox"; - - if ( false !== strpos( $td_class, 'cap-neg' ) ) - $row .= ''; - - $row .= "X$checkbox"; + + if ( false !== strpos( $td_class, 'cap-neg' ) ) + $row .= ''; + + $row .= "
'; + echo ''; } // end foreach item type @@ -728,7 +728,7 @@ if ( ! $is_administrator && ! current_user_can($cap_name) ) continue; - + if ( $i == $checks_per_row ) { echo ''; $i = 0; @@ -802,11 +802,11 @@ } uasort( $this->capabilities, 'strnatcasecmp' ); // sort by array values, but maintain keys ); - + foreach ( $this->capabilities as $cap_name => $cap ) : if ( isset( $type_caps[$cap_name] ) || isset($core_caps[$cap_name]) || isset($type_metacaps[$cap_name]) ) continue; - + foreach(array_keys($plugin_caps) as $plugin) { if ( in_array( $cap_name, $plugin_caps[$plugin]) ) { continue 2; @@ -940,10 +940,10 @@ $checked = checked(1, ! empty($rcaps[$cap_name]), false ); ?> X x  @@ -969,15 +969,15 @@ echo ''; } } - ?> - + ?> +   X X - + - + "edit_users").', 'capsman-enhanced' ); ?> @@ -1112,6 +1112,7 @@
  • + diff --git a/readme.txt b/readme.txt index 2981a46c..f7c0a635 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: publishpress, kevinB, stevejburge, andergmartins Tags: role, capabilities, post types, taxonomies, editor, network, woocommerce Requires at least: 4.1 Tested up to: 5.2.4 -Stable tag: 1.8 +Stable tag: 1.8.1 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -15,37 +15,29 @@ Control permissions requirements for your post types, and assign those capabilit = Features: = -* Create Roles +* Create or Copy Roles * Manage Role Capabilities -* Cause type-specific Capabilities to be required and applied for any Post Type -* Cause distinct edit, delete and assign Capabilities to be required and applied for any Taxonomy +* Enable type-specific capability requirements and assignments for any Post Type +* Enable distinct edit, delete and assign capabilities for any Taxonomy * Some specialized support for WooCommerce Post Types -* Supports negation: set any Capability to granted, not granted, or blocked -* Integration with Press Permit and PublishPress for comprehensive publishing solutions -* Copy any Role to all network sites -* Mark any Role for auto-copy to future network sites -* Backup and restore Roles and Capabilities to revert your last changes. -* Revert Roles and Capabilities to WordPress defaults. +* Negation: any capability can be granted, not granted, or blocked +* Integration with PressPermit and PublishPress for comprehensive publishing solutions +* Network: Copy any role to all sites, or auto-copy to future sites +* Backup (automatic / manual) and restore roles and capabilities to revert your changes Capability Manager Enhanced is professionally developed and supported by the experienced PublishPress team. It has been a reliable tool since 2012, when PublishPress team member Kevin Behrens forked it from Jordi Canals' abandoned Capability Manager plugin. -For additional versatility and convenience, enjoy Press Permit plugin integration. Capability Manager Enhanced will show which capabilities have been added indirectly (as a pre-defined subset) by supplemental Type-Specific Roles (Page Contributor, Media Author, Product Editor, etc.) - -Role management can also be delegated: - -* Only Users with 'manage_capabilities' can manage them. This Capability is created at install time and assigned to Administrators. -* Administrator Role cannot be deleted. -* Non-administrators can only manager Roles or Users with same or lower capabilities. +For additional versatility and convenience, try PressPermit plugin integration. Capabilities added indirectly by supplemental type-specific roles (Page Contributor, Product Editor, etc.) will be highlighted in the CME role editor. == Screenshots == -1. Users Menu -2. View or modify Capabilities for any Role +1. View or modify Capabilities for any Role +2. Users Menu 3. Network: copy Role to existing or future Sites 4. Role operations -5. Permissions Menu (Press Permit integration) +5. Permissions Menu (PressPermit integration) 6. Shading of Capabilities granted by supplemental Type-Specific Roles 7. Enforce Type-Specific Capabilities 8. Enforce Taxonomy-Specific Capabilities @@ -54,7 +46,7 @@ Role management can also be delegated: == Frequently Asked Questions == -= How can I grant capabilities for a custom post type = += How can I grant capabilities for a custom post type? = The custom post type must be defined to impose type-specific capability requirements. This is normally done by setting the "capability type" property equal to the post type name. @@ -62,10 +54,14 @@ The custom post type must be defined to impose type-specific capability requirem You may need to adjust your custom post type definition by enabling the map_meta_cap property. If you are calling register_post_type manually, just add this property to the options array. -= Even after I added capabilities, WordPress is not working the way I want = += Even after I added capabilities, WordPress is not working the way I want. = Keep in mind that this plugin's main purpose is to expose switches (defined capabilities). The wiring of those switches is up to the WordPress core or other plugins. If granting or removing a capability does not cause the expected results, your issue is probably with the other package. With that context in mind, you are still welcome to contact us about it. += Can role management be delegated? = + +Yes. Users with the 'manage_capabilities' capability can edit roles. This Capability is created at install time and assigned to Administrators. You can add it to any role, but non-administrators cannot manage roles or users that have a higher role level than their own. + = Where can I find more information about this plugin, usage and support ? = * Feel free to submit a help ticket if you can't find an answer in the documentation.