The ‘user_has_cap’ hook seems to take two page loads to trigger

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.

Leave a Comment