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.

This question relates to another question I asked recently (http://wordpress.stackexchange.com/questions/29009/how-to-assign-specific-users-the-capability-to-edit-specific-pages-posts-cus/), the answer to which got me most of the way there to what I was trying to do. However, rather than keep updating that question I thought it better to post a new one as I really consider it more of a new issue now.

I am basically restricting Read access to a custom post type (projects) on a per-user basis, I'm using the user_has_cap hook and I check whether the User trying to Read a page has the post type's ID in an array of IDs that are assigned to the User, depending on whether the array has the current post ID in it then Read capabilities are added / removed accordingly. This is done with the following code:

function allow_user_to_read_cpt_filter($allcaps, $cap, $args) {
    global $current_user; // Get user id
    get_currentuserinfo(); //...
    $userid = $current_user->ID; //...
    $wos_uspr_checked_read_ids = explode(',',esc_attr(get_the_author_meta('wos_uspr_read_data', $userid)));
    /* The above is a comma separated list of IDS, e.g. 724,736,784 */
    global $wpdb;
    $post = get_post($args[2]);
    if (!in_array($post->ID, $wos_uspr_checked_read_ids)) {
        $user = wp_get_current_user();
        $user->remove_cap('read_project');
        $user->remove_cap('read_projects');
        $user->remove_cap('read_others_projects');
        $user->remove_cap('read_published_projects');       
    } else {
        $user = wp_get_current_user();
        $user->add_cap('read_project');
        $user->add_cap('read_projects');
        $user->add_cap('read_others_projects');
        $user->add_cap('read_published_projects');
    }

    return $allcaps;
}

add_filter('user_has_cap', 'allow_user_to_read_cpt_filter', 100, 3);

(Yes, I have used different code than the answer given to my previous question, I don't think this is contributing to the problem here though as I have used the other method of assigning capabilities, I just prefer using the above method.)

Anyway, the problem I am encountering with this is that it is taking two loads of the page before my post types content is being hidden. The code I am using on my page looks like this:

if (current_user_can('read_projects')) {
    echo '<p>Yes, you can read this.</p>';
} else if (!current_user_can('read_projects')) {
    echo '<p>No, you cannot read this.</p>';
}

My guess was that the hook was not being triggered quickly enough when the page is loaded in order to show or hide the content on the first load, but I'm struggling to find an answer to when user_has_cap is triggered.

share|improve this question
    
After a good deal more experimenting I seem to have now got it working on first load of a page. I'm slightly unsure about exactly why this is the case though so I'm hesitant to add my updated code as an answer! However, I will do so anyway in the hope that the code may be useful to someone else. –  Rick Curran Nov 7 '11 at 12:35

1 Answer 1

I finally managed to get the required behaviour, I ended up using updated code from the example I showed in my question - and actually closer to the code suggested in the question I referenced in my question text! Here is the code that worked in the end:

function allow_user_to_edit_cpt_filter($allcaps, $cap, $args) {
    global $current_user; // Get user id
    get_currentuserinfo(); //...
    $userid = $current_user->ID; //...
    $a_user = new WP_User($userid); // Get user details
    if ($a_user->roles[0] != 'administrator')  { // Don't apply if administrator
        $wos_uspr_checked_edit_ids = explode(',',esc_attr(get_the_author_meta('wos_uspr_edit_data', $userid)));
        global $wpdb;
        $post = get_post($args[2]);
            // UPDATED CODE BLOCK BEGINS
        if (!in_array($post->ID, $wos_uspr_checked_edit_ids)) {
            if (($args[0] == "edit_project") || ($args[0] == "edit_others_projects") || ($args[0] == "edit_published_projects")) {
                foreach((array) $cap as $capasuppr) {
                   if (array_key_exists($capasuppr, $allcaps)) {
                      $allcaps[$capasuppr] = 0;
                   }
                }
            }
        }
            // UPDATED CODE BLOCK ENDS
    }
    return $allcaps;
}
add_filter('user_has_cap', 'allow_user_to_edit_cpt_filter', 100, 3);

Using this code instead of what I've quoted in my question seems to trigger correctly on first page load, and my content is restricted from view the first time. I'm sure I'd tried this format before and had no success but it is now working as desired.

share|improve this answer

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.