Temporary capability for current_user_can()

Yes, just filter 'user_has_cap'. You get an array with the current capabilities that you can change without touching the database.

Sample Code

add_filter( 'user_has_cap', 'wpse_53230_catch_cap', 10, 3 );

/**
 * See WP_User::has_cap() in wp-includes/capabilities.php
 *
 * @param  array  $allcaps Existing capabilities for the user
 * @param  string $caps    Capabilities provided by map_meta_cap()
 * @param  array  $args    Arguments for current_user_can()
 * @return array
 */
function wpse_53230_catch_cap( $allcaps, $caps, $args )
{

  // $args[2] is the post ID
  if($args[0] !== 'beat_chuck_norris' || !isset($args[2]) || !my_checks($args[2]))
    return $allcaps;

  $allcaps['beat_chuck_norris'] = 1;

  return $allcaps;
}


function my_checks($post_id){
  // here check if the current user can rate this post
  return true;
} 

Test

current_user_can( 'beat_chuck_norris', get_the_ID() )
    and print 'The current user can beat Chuck Norris. Be nice to her!';

Handle super-admins

add_filter('map_meta_cap', 'wpse_53230_catch_cap_for_sa', 10, 4);

function wpse_53230_catch_cap_for_sa($caps, $req_cap, $user_id, $args){

  if(is_multisite() 
      && is_super_admin($user_id)
      && ($req_cap === 'beat_chuck_norris')
      && !empty($args[0]) // here post ID is $args[0]
      && !my_checks($args[0])
    ){
         $caps[] = 'do_not_allow';
     }      

  return $caps;    
}

Leave a Comment