Is it possible to intercept calls to current_user_can() ?
Example:
current_user_can('rate', $post_id)
There’s no “rate” capability registered, but could I somehow hook into that function and do my own checks, without having to register a role capability?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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;
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0