From 7d5cc745792951bf530f4f897a4ff5346e27b9a8 Mon Sep 17 00:00:00 2001 From: Kevin Behrens <43488774+agapetry@users.noreply.github.com> Date: Thu, 24 Oct 2019 18:01:33 -0400 Subject: [PATCH] Support grouping of plugin capabilities * Pre-define capabilities for WooCommerce, PublishPress, PressPermit * Support "cme_plugin_capabilities" filter for additional organization of third party capabilities --- admin.css | 4 + includes/admin.php | 372 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 352 insertions(+), 24 deletions(-) diff --git a/admin.css b/admin.css index e9d5179c..7a274898 100644 --- a/admin.css +++ b/admin.css @@ -84,6 +84,10 @@ table.cme-typecaps span.cap-x { display: none; } +h3.cme-cap-section { +margin-top:0; +} + a.neg-cap, a.cap-on, a.type-on, a.neg-type-caps, a.cme-neg-all { text-decoration: none; } diff --git a/includes/admin.php b/includes/admin.php index e7e0b183..425562aa 100644 --- a/includes/admin.php +++ b/includes/admin.php @@ -266,6 +266,7 @@ 'manage_categories' ); $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') ) { @@ -299,10 +300,6 @@ continue; } - //if ( ! $cap_type ) { - - //} else {} - if ( ! count( $cap_properties[$cap_type][$item_type] ) ) continue; @@ -401,7 +398,6 @@ $disabled = ''; $checked = checked(1, ! empty($rcaps[$cap_name]), false ); - //$checkbox = ''; $checkbox = ''; $type_caps [$cap_name] = true; @@ -428,6 +424,15 @@ $row .= ""; } + + if ('type' == $item_type) { + $type_metacaps[$type_obj->cap->read_post] = true; + $type_metacaps[$type_obj->cap->edit_post] = true; + $type_metacaps[$type_obj->cap->delete_post] = true; + } elseif ('taxonomy' == $item_type && !empty($type_obj->cap->edit_term) && !empty($type_obj->cap->delete_term)) { + $type_metacaps[$type_obj->cap->edit_term] = true; + $type_metacaps[$type_obj->cap->delete_term] = true; + } } if ( $display_row ) { @@ -438,8 +443,6 @@ echo ''; - //} // endif this iteration is for type caps checkbox display - } // end foreach item type echo ''; @@ -554,9 +557,238 @@ + capabilities ), $this->ID ); + $all_capabilities = apply_filters( 'members_get_capabilities', $all_capabilities ); + + $publishpress_status_change_caps = array(); + foreach( $all_capabilities as $cap_name ) { + if (0 === strpos($cap_name, 'status_change_')) { + $publishpress_status_change_caps []= $cap_name; + } + } + + $plugin_caps = apply_filters('cme_plugin_capabilities', + array( + 'PressPermit' => apply_filters('cme_presspermit_capabilities', + array( + 'edit_own_attachments', + 'list_others_unattached_files', + 'pp_administer_content', + 'pp_assign_roles', + 'pp_associate_any_page', + 'pp_create_groups', + 'pp_create_network_groups', + 'pp_define_moderation', + 'pp_define_post_status', + 'pp_define_privacy', + 'pp_delete_groups', + 'pp_edit_groups', + 'pp_exempt_edit_circle', + 'pp_exempt_read_circle', + 'pp_force_quick_edit', + 'pp_list_all_files', + 'pp_manage_capabilities', + 'pp_manage_members', + 'pp_manage_network_members', + 'pp_manage_roles', + 'pp_manage_settings', + 'pp_moderate_any', + 'pp_set_associate_exceptions', + 'pp_set_edit_exceptions', + 'pp_set_notification_channel', + 'pp_set_read_exceptions', + 'pp_set_revise_exceptions', + 'pp_set_term_assign_exceptions', + 'pp_set_term_associate_exceptions', + 'pp_set_term_manage_exceptions', + 'pp_unfiltered', + 'set_posts_status', + ) + ), + 'PublishPress' => apply_filters('cme_publishpress_capabilities', + array_merge( + array( + 'edit_post_subscriptions', + 'ppma_edit_orphan_post', + 'pp_manage_roles', + 'pp_set_notification_channel', + 'pp_view_calendar', + 'pp_view_content_overview', + 'status_change', + ), + $publishpress_status_change_caps + ) + ), + 'WooCommerce' => apply_filters('cme_woocommerce_capabilities', + array( + 'assign_product_terms', + 'assign_shop_coupon_terms', + 'assign_shop_discount_terms', + 'assign_shop_order_terms', + 'assign_shop_payment_terms', + 'create_shop_orders', + 'delete_others_products', + 'delete_others_shop_coupons', + 'delete_others_shop_discounts', + 'delete_others_shop_orders', + 'delete_others_shop_payments', + 'delete_private_products', + 'delete_private_shop_coupons', + 'delete_private_shop_orders', + 'delete_private_shop_discounts', + 'delete_private_shop_payments', + 'delete_product_terms', + 'delete_products', + 'delete_published_products', + 'delete_published_shop_coupons', + 'delete_published_shop_discounts', + 'delete_published_shop_orders', + 'delete_published_shop_payments', + 'delete_shop_coupons', + 'delete_shop_coupon_terms', + 'delete_shop_discount_terms', + 'delete_shop_discounts', + 'delete_shop_order_terms', + 'delete_shop_orders', + 'delete_shop_payments', + 'delete_shop_payment_terms', + 'edit_others_products', + 'edit_others_shop_coupons', + 'edit_others_shop_discounts', + 'edit_others_shop_orders', + 'edit_others_shop_payments', + 'edit_private_products', + 'edit_private_shop_coupons', + 'edit_private_shop_discounts', + 'edit_private_shop_orders', + 'edit_private_shop_payments', + 'edit_product_terms', + 'edit_products', + 'edit_published_products', + 'edit_published_shop_coupons', + 'edit_published_shop_discounts', + 'edit_published_shop_orders', + 'edit_published_shop_payments', + 'edit_shop_coupon_terms', + 'edit_shop_coupons', + 'edit_shop_discounts', + 'edit_shop_discount_terms', + 'edit_shop_order_terms', + 'edit_shop_orders', + 'edit_shop_payments', + 'edit_shop_payment_terms', + 'export_shop_payments', + 'export_shop_reports', + 'import_shop_discounts', + 'import_shop_payments', + 'manage_product_terms', + 'manage_shop_coupon_terms', + 'manage_shop_discounts', + 'manage_shop_discount_terms', + 'manage_shop_payment_terms', + 'manage_shop_order_terms', + 'manage_shop_settings', + 'manage_woocommerce', + 'publish_products', + 'publish_shop_coupons', + 'publish_shop_discounts', + 'publish_shop_orders', + 'publish_shop_payments', + 'read_private_products', + 'read_private_shop_coupons', + 'read_private_shop_discounts', + 'read_private_shop_payments', + 'read_private_shop_orders', + 'view_admin_dashboard', + 'view_shop_discount_stats', + 'view_shop_payment_stats', + 'view_shop_reports', + 'view_shop_sensitive_data', + 'view_woocommerce_reports', + ) + ), + )); + + foreach($plugin_caps as $plugin => $__plugin_caps) { + if (!$_plugin_caps = array_fill_keys( array_intersect($__plugin_caps, $all_capabilities), true )) { + continue; + } + + echo '

' . sprintf(__( '%s Capabilities', 'capsman-enhanced' ), str_replace('_', ' ', $plugin )) . '

'; + echo ''; + + $checks_per_row = get_option( 'cme_form-rows', 5 ); + $i = 0; $first_row = true; + + foreach( array_keys($_plugin_caps) as $cap_name ) { + if ( isset( $type_caps[$cap_name] ) || isset($core_caps[$cap_name]) || isset($type_metacaps[$cap_name]) ) { + continue; + } + + if ( ! $is_administrator && ! current_user_can($cap_name) ) + continue; + if ( $i == $checks_per_row ) { + echo ''; + $i = 0; + } + + if ( ! isset( $rcaps[$cap_name] ) ) + $class = 'cap-no'; + else + $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg'; + + if ( ! empty($pp_metagroup_caps[$cap_name]) ) { + $class .= ' cap-metagroup'; + $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 ); + $title = $title_text; + ?> + + + '; + $i = 0; + } elseif ( ! $first_row ) { + // Now close a wellformed table + for ( $i; $i < $checks_per_row; $i++ ){ + echo ''; + } + echo ''; + } + ?> + + + + +
X x  + + + +  
+ +   X X + +
 

' . __( 'Additional Capabilities', 'capsman-enhanced' ) . '

'; + } + + echo '

 

' . __( 'Additional Capabilities', 'capsman-enhanced' ) . '

'; ?> @@ -564,9 +796,6 @@ capabilities ), $this->ID ); - $all_capabilities = apply_filters( 'members_get_capabilities', $all_capabilities ); - foreach( $all_capabilities as $cap_name ) { if ( ! isset($this->capabilities[$cap_name]) ) $this->capabilities[$cap_name] = str_replace( '_', ' ', $cap_name ); @@ -575,15 +804,19 @@ 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]) ) + 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; + } + } + if ( ! $is_administrator && empty( $current_user->allcaps[$cap_name] ) ) { continue; } - // ============ End Kevin B mod =============== - // Levels are not shown. if ( preg_match( '/^level_(10|[0-9])$/i', $cap_name ) ) { continue; @@ -653,31 +886,122 @@ + +
+ +   X X + +
+ +  

' . __( 'Invalid Capabilities', 'capsman-enhanced' ) . '

'; + ?> + + + capabilities[$cap_name]) ) + $this->capabilities[$cap_name] = str_replace( '_', ' ', $cap_name ); + } + + uasort( $this->capabilities, 'strnatcasecmp' ); // sort by array values, but maintain keys ); + + foreach ( $this->capabilities as $cap_name => $cap ) : + if ( ! isset( $type_metacaps[$cap_name] ) ) + continue; + + if ( ! $is_administrator && empty( $current_user->allcaps[$cap_name] ) ) { + continue; + } + + if ( $i == $checks_per_row ) { + echo ''; + $i = 0; $first_row = false; + } + + if ( ! isset( $rcaps[$cap_name] ) ) + $class = 'cap-no'; + else + $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg'; + + if ( ! empty($pp_metagroup_caps[$cap_name]) ) { + $class .= ' cap-metagroup'; + $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 ); + ?> + + '; + } + + if ( $i == $checks_per_row ) { + echo ''; + $i = 0; + } else { + if ( ! $first_row ) { + // Now close a wellformed table + for ( $i; $i < $checks_per_row; $i++ ){ + echo ''; + } + echo ''; + } + } ?> - - + +
X
 
  X X
+ + +
+ + + + -
-
+ "edit_users").', 'capsman-enhanced' ); ?> -
+ +