You should not use the page
parameter in an admin url unless you are going to go to an options page because a check for the ‘manage_options’ capability is the default permissions check. The goal of the ‘Delete Cache’ link is to run an action, then redirect to the current page/post; it is not to view an options page. The WP Super Cache plugin was kind of misusing its settings page as a catch-all for both managing settings and running actions, such as ‘delete page cache’.
Code-wise, the solution involves the following changes.
Adding the ‘Delete Cache’ to the admin bar had to change a bit:
function supercache_admin_bar_render() {
global $wp_admin_bar, $wp_cache_not_logged_in;
if ( !is_user_logged_in() || !$wp_cache_not_logged_in )
return false;
if ( !current_user_can('wp_supercache_delete_page_cache') && !current_user_can('wp_supercache_manage_options') )
return false;
$wp_admin_bar->add_menu( array(
'parent' => '',
'id' => 'delete-cache',
'title' => __( 'Delete Cache', 'wp-super-cache' ),
'meta' => array( 'title' => __( 'Delete cache of the current page', 'wp-super-cache' ) ),
// NOTE: post.php is irrelevant; stripping page=xxx IS relevant; changed action value from 'delete' to 'wpsupercache-delete-page-cache' to keep it in a sensible namespace
'href' => wp_nonce_url( admin_url( 'post.php?action=wpsupercache-delete-page-cache&path=" . urlencode( $_SERVER[ "REQUEST_URI' ] ) ), 'delete-cache' )
) );
}
Also changed code which adds hook to admin_init to look for this new action:
if ( ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wpsupercache' ) || ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'wpsupercache-delete-page-cache' ) ) {
add_action( 'admin_init', 'wp_cache_manager_updates' );
}
Finally, altered the wp_cache_manager_updates
function to take the new action into account AND allow the function to run if the user has wpsupercache_delete_page_cache capability. I’m not posting this code as it’s not really relevant to the solution and it’s very long.