'GET', 'callback' => [__CLASS__, 'get_roles'], 'permission_callback' => function () { return current_user_can('manage_options'); } ] ]); register_rest_route('plac/v1', '/all-capabilities', [ [ 'methods' => 'GET', 'callback' => [__CLASS__, 'get_all_capabilities'], 'permission_callback' => function () { return current_user_can('manage_options'); } ] ]); register_rest_route('plac/v1', '/role-capabilities', [ [ 'methods' => 'POST', 'callback' => [__CLASS__, 'get_role_capabilities'], 'permission_callback' => function () { return current_user_can('manage_options'); } ] ]); register_rest_route('plac/v1', '/capability-groups', [ [ 'methods' => 'GET', 'callback' => [__CLASS__, 'get_capability_groups'], 'permission_callback' => function () { return current_user_can('manage_options'); } ] ]); register_rest_route('plac/v1', '/update-capabilities', array( 'methods' => 'POST', 'callback' => [__CLASS__, 'update_capabilities'], 'permission_callback' => function () { return current_user_can('manage_options'); }, )); } public static function get_roles() { global $wp_roles; if (!isset($wp_roles)) { $wp_roles = new WP_Roles(); } // Get all role names $roles = $wp_roles->get_names(); // Remove administrator role from the response array unset($roles['administrator']); return new WP_REST_Response(['roles' => $roles], 200); } public static function get_all_capabilities() { global $wp_roles; if (!isset($wp_roles)) { $wp_roles = new WP_Roles(); } $all_capabilities = []; foreach ($wp_roles->roles as $role) { if (isset($role['capabilities']) && is_array($role['capabilities'])) { $all_capabilities = array_merge($all_capabilities, array_keys($role['capabilities'])); } } // Remove duplicate capabilities $all_capabilities = array_unique($all_capabilities); sort($all_capabilities); // Sort alphabetically for better display // Debug output to check what's being returned return new WP_REST_Response(['capabilities' => array_values($all_capabilities)], 200); } public static function get_role_capabilities(WP_REST_Request $request) { $role = $request->get_param('role'); global $wp_roles; if (!isset($wp_roles) || !isset($wp_roles->roles[$role])) { return new WP_REST_Response(['capabilities' => []], 200); } return new WP_REST_Response(['capabilities' => array_keys($wp_roles->roles[$role]['capabilities'])], 200); } public static function get_capability_groups() { global $wp_roles; if (!isset($wp_roles)) { $wp_roles = new WP_Roles(); } $all_caps = []; foreach ($wp_roles->roles as $role) { $all_caps = array_merge($all_caps, array_keys($role['capabilities'])); } $all_caps = array_unique($all_caps); // Define groups in the correct order to match the image (without CPT groups) $groups = [ 'Core' => [], 'General' => [], 'Themes' => [], 'Posts' => [], 'Pages' => [], 'Plugins' => [], 'Users' => [], 'Deprecated' => [], 'Products' => [], 'Variations' => [], 'Orders' => [], 'Refunds' => [], 'Coupons' => [], 'Patterns AI Data' => [], 'Custom capabilities' => [], 'User Role Editor' => [], 'WooCommerce' => [], // This will be a header only 'WC Core' => [], 'WC Products' => [], 'WC Orders' => [], 'WC Coupons' => [], 'WC Variations' => [], 'WC Refunds' => [], ]; // Core standard post capabilities $standard_post_caps = [ 'edit_post', 'read_post', 'delete_post', 'edit_posts', 'edit_others_posts', 'publish_posts', 'read_private_posts', 'delete_posts', 'delete_private_posts', 'delete_published_posts', 'delete_others_posts', 'edit_private_posts', 'edit_published_posts' ]; foreach ($all_caps as $cap) { // Deprecated capabilities $deprecated_caps = [ 'level_0', 'level_1', 'level_2', 'level_3', 'level_4', 'level_5', 'level_6', 'level_7', 'level_8', 'level_9', 'level_10', 'edit_files' ]; if (in_array($cap, $deprecated_caps)) { $groups['Deprecated'][] = $cap; continue; } // WooCommerce specific capabilities if (strpos($cap, 'woocommerce_') === 0) { $groups['WooCommerce'][] = $cap; continue; } if (strpos($cap, 'manage_woocommerce') !== false) { $groups['WC Core'][] = $cap; continue; } if (strpos($cap, 'product') !== false && strpos($cap, 'woocommerce') !== false) { $groups['WC Products'][] = $cap; continue; } else if (strpos($cap, 'product') !== false) { $groups['Products'][] = $cap; continue; } if (strpos($cap, 'variation') !== false && strpos($cap, 'woocommerce') !== false) { $groups['WC Variations'][] = $cap; continue; } else if (strpos($cap, 'variation') !== false) { $groups['Variations'][] = $cap; continue; } if (strpos($cap, 'order') !== false && strpos($cap, 'refund') === false && strpos($cap, 'woocommerce') !== false) { $groups['WC Orders'][] = $cap; continue; } else if (strpos($cap, 'order') !== false && strpos($cap, 'refund') === false) { $groups['Orders'][] = $cap; continue; } if (strpos($cap, 'refund') !== false && strpos($cap, 'woocommerce') !== false) { $groups['WC Refunds'][] = $cap; continue; } else if (strpos($cap, 'refund') !== false) { $groups['Refunds'][] = $cap; continue; } if (strpos($cap, 'coupon') !== false && strpos($cap, 'woocommerce') !== false) { $groups['WC Coupons'][] = $cap; continue; } else if (strpos($cap, 'coupon') !== false) { $groups['Coupons'][] = $cap; continue; } if (strpos($cap, 'pattern') !== false) { $groups['Patterns AI Data'][] = $cap; continue; } if (strpos($cap, 'role_editor') !== false) { $groups['User Role Editor'][] = $cap; continue; } if ( (strpos($cap, 'manage_') === 0 || strpos($cap, 'edit_') === 0 || strpos($cap, 'publish_') === 0 || strpos($cap, 'delete_') === 0) && !in_array($cap, $standard_post_caps) ) { $groups['Core'][] = $cap; continue; } // Post capabilities (standard only) if (in_array($cap, $standard_post_caps)) { $groups['Posts'][] = $cap; continue; } if (strpos($cap, 'page') !== false) { $groups['Pages'][] = $cap; continue; } if (strpos($cap, 'theme') !== false || strpos($cap, 'switch_') === 0) { $groups['Themes'][] = $cap; continue; } if ( strpos($cap, 'plugin') !== false || strpos($cap, 'install_') === 0 || strpos($cap, 'activate_') === 0 || strpos($cap, 'update_') === 0 ) { $groups['Plugins'][] = $cap; continue; } if ( strpos($cap, 'user') !== false || strpos($cap, 'profile') !== false || strpos($cap, 'promote_user') !== false ) { $groups['Users'][] = $cap; continue; } if ( strpos($cap, 'read') !== false || strpos($cap, 'upload_') !== false || strpos($cap, 'moderate_') !== false || strpos($cap, 'import') !== false || strpos($cap, 'export') !== false ) { $groups['General'][] = $cap; continue; } $groups['Custom capabilities'][] = $cap; } // Filter out empty groups $filtered_groups = []; foreach ($groups as $key => $caps) { if (!empty($caps)) { $filtered_groups[$key . ' (' . count($caps) . '/0)'] = $caps; } } return new WP_REST_Response($filtered_groups, 200); } public static function update_capabilities(WP_REST_Request $request) { $nonce = $request->get_param('_wpnonce'); // Check nonce for security if (!isset($nonce) || !wp_verify_nonce($nonce, 'plac_wp_rest')) { return new WP_REST_Response([ 'message' => 'Invalid nonce' ], 403); } // Create backup if it doesn't exist yet if (get_option('plac_role_backup') === false) { // Get all WordPress roles and capabilities $wp_roles = wp_roles(); $backup = array(); // Store all roles and their capabilities foreach ($wp_roles->roles as $role_key => $role_data) { $backup[$role_key] = $role_data['capabilities']; } // Save backup to wp_options update_option('plac_role_backup', $backup, false); } // Get parameters $role_name = sanitize_text_field($request['role']); $capabilities = $request['capabilities']; if (empty($role_name)) { return new WP_REST_Response(array( 'success' => false, 'message' => 'Role name is required' ), 400); } // Validate capabilities if (!is_array($capabilities)) { return new WP_REST_Response(array( 'success' => false, 'message' => 'Capabilities must be an array' ), 400); } // Get WordPress roles $wp_roles = wp_roles(); // Check if role exists if (!isset($wp_roles->roles[$role_name])) { return new WP_REST_Response(array( 'success' => false, 'message' => 'Role does not exist' ), 404); } // Get all existing capabilities $all_capabilities = array(); foreach ($wp_roles->roles as $role) { if (isset($role['capabilities']) && is_array($role['capabilities'])) { $all_capabilities = array_merge($all_capabilities, array_keys($role['capabilities'])); } } $all_capabilities = array_unique($all_capabilities); // Get role object $role = get_role($role_name); // Remove all existing capabilities first foreach ($all_capabilities as $cap) { $role->remove_cap($cap); } // Add the selected capabilities foreach ($capabilities as $cap) { $cap = sanitize_text_field($cap); $role->add_cap($cap); } return new WP_REST_Response(array( 'success' => true, 'message' => 'Role capabilities updated successfully' ), 200); } }