Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm working on a modification to WP Super Cache which adds two new capabilities to give more control of restriction to certain features. My goal is to a) allow Editors to see the Delete Cache button on the admin bar and b) use it to delete the cache of the page they're editing. I got 'a', however when the Editor clicks Delete Cache, they get 'You do not have sufficient permissions to access this page.'

I cannot find what part of the plugin forced this permissions check, but I wonder if it has to do with the URL that the menu item points to.

Here is the function and hook to add the menu item:

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;

    // ORIGINALLY if ( wp_supercache_admin() )
    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' ),
                'href' => wp_nonce_url( admin_url( 'admin.php?page=wpsupercache&action=wpsupercachedelete&path=' . urlencode( $_SERVER[ 'REQUEST_URI' ] ) ), 'delete-cache' ) // ORIGINALLY pointed to options.general.php?page=wpsupercache&action=delete... 
                ) );
}
add_action( 'wp_before_admin_bar_render', 'supercache_admin_bar_render');

And I think this part is also relevant to solving this ... this is elsewhere in the plugin file, not within any function (do I need to up the priority?):

if ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wpsupercache' )
    add_action( 'admin_init', 'wp_cache_manager_updates' );

I have made the modifications to wp_cache_manager_updates so it accounts for the aforementioned capabilities. In fact, this function never runs. I put a die('got to wp_cache_manager_updates'); in there to see if it ever even gets touched. It does not. Something intercepts and sends me to Insufficient Permissions-ville.

share|improve this question
    
Here's the pertinent code. add_options_page( 'WP Super Cache', 'WP Super Cache', 'manage_options', 'wpsupercache', 'wp_cache_manager'); That manage_options bit is the capability that gets checked. If I change that up for the custom capability, I can run delete on the page for anyone with that capability, but it has the undesired consequence of letting the Editor into the super cache settings. I still need to learn how to change the code so I beat the capability check. Also, I don't fully understand why the capability for the options page affects running the action. –  James Revillini Apr 13 '12 at 19:47
    
interestingly enough, the href of the admin bar link can go to pretty much any valid php page in the admin section. Originally it was options-general.php, but I've tried swapping it out for admin.php and post.php, and they work or don't work based on what capability I use for the capability when I run add_options_page (see previous comment). ... I still don't see the connection. –  James Revillini Apr 13 '12 at 20:16
add comment

1 Answer

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.