The other suggestions (and the accepted answer in your link) temporarily change a user’s capabilities globally. That is a hack. There is hook specifically designed for conditionally adjusting capabilities for specific content: map_meta_cap
.
When WordPress checks whether a user can edit a post, it checks if the user can edit_post
. WordPress decides which actual capability users have that this maps to using the map_meta_cap()
function.
For example, when checking if a user can edit a post, it checks if the post was authored by the current user. If it was, then it maps the ‘meta capability’ edit_post
to the ‘primitive capability’ edit_posts
. If the post was authored by someone else it maps it to edit_others_posts
. Then it checks if the current user has the mapped capability.
So we can hook into this process so that whenever WordPress maps edit_post
we will check if the current user is a Contributor, and if the post is older than 12 hours. If both those things are true we will map edit_post
to do_not_allow
, meaning that the user will not be allowed to edit it:
function wpse_319901_contributor_can_edit( $caps, $cap, $user_id, $args ) {
// Stop if this isn't a check for edit_post or delete_post.
if ( $cap !== 'edit_post' || $cap !== 'delete_post' ) {
return $caps;
}
// Get the current user's roles.
$user = get_userdata( $user_id );
$roles = $user->roles;
// Stop if the user is not a Contributor.
if ( ! in_array( 'contributor', $roles ) ) {
return $caps;
}
// For edit_post the post ID will be the first argument in $args.
$post = get_post( $args[0] );
// Is the post older than 12 hours?
if ( get_the_time( 'U', $post ) < strtotime( '-12 hours' ) ) {
// If so, do not allow the user to edit it.
$caps[] = 'do_not_allow';
}
return $caps;
}
add_filter( 'map_meta_cap', 'wpse_319901_contributor_can_edit', 10, 4 );
You can read more about capabilities and how meta capabilities are mapped to primitive capabilities here.