Custom User Roles and WordPress Core Code Compatibility Issues

Custom User Roles

Custom User Roles

WordPress has good built-in users level/capabilities/roles system. Standard roles are administrator, editor, author, contributor, subscriber. This roles set is enough in the most cases for the most needs. But from time to time you need something special, something yours only. In such cases you can use User Role Editor WordPress plugin and build your own custom user role. But you should do it carefully and make thorough testing for new created user role as:

  • 1st, you could create some breaches in WordPress security system;
  • 2nd, you can loose some useful WordPress functionality.

One example of lost WordPress functionality for custom user role is described here:

If you include to the role edit pages rights only (except of posts edit rights), such role will loose the revisions edit and ‘Restore’ action links. Why is it possible? Because of standard WordPress roles include post and page edit capabilities together only. Let’s look into the code
at the wp-includes/post-template.php file:

1084
1085
if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
		$date = "$date";

and

1154
$can_edit_post = current_user_can( 'edit_post', $post->ID );

and function get_edit_post_link() at the wp-includes/link-template.php file has the ‘post_edit’ capability check only too:

804
805
if ( !current_user_can( $post_type_object->cap->edit_post, $post->ID ) )
	return;

As you can see above, WordPress developer checks ‘post_edit’ capability in his code only. Later in the code (wp-includes/post-template.php file) we see:

1173
1174
1175
1176
if ( $post->ID != $revision->ID && $can_edit_post )
    $actions = '<a href="' . wp_nonce_url( add_query_arg( array( 'revision' => $revision->ID, 'action' => 'restore' ) ), "restore-post_$post->ID|$revision->ID" ) . '">' . __( 'Restore' ) . '</a>';
else
    $actions = '';

This way, if your new custom user role gives to the user ‘edit_page’ capability, but doesn’t include ‘edit_post’ capability, such user will not see ‘Restore’ action links for page revisions in the page editor.

How to fix it? It is not so compex. But we should change a line at WordPress core code. So, please, be aware that this change will be lost surely with one of the next WordPress core code update and you should to restore it again and again probably.
We can apply these changes to the code:
wp-includes/link-template.php file (to be honest, I added more simple checking here than original one, as $post_type_object->cap doesn’t contain ‘edit_page’ option. It doesn’t contain capabilities options for pages at all):

804
805
if ( ! (current_user_can( $post_type_object->cap->edit_post, $post->ID) || current_user_can('edit_page', $post->ID)) )
	return;

and wp-includes/post-template.php file:

1154
$can_edit_post = current_user_can( 'edit_post', $post->ID ) || current_user_can( 'edit_page', $post->ID );

We just added ‘edit_page’ capability checking there. This way revisions edit and “Restore” action links will exist in both cases for posts editor and pages editor roles.

For those of you who don’t like to edit WordPress core source code, there is another decision – left all needed capabilities to work with posts, disable ‘publish_posts’ capability only and hide ‘Posts’ menu from the admin back-end. You can read about hiding menu items from admin back-end here. You can use this code snippet to remove ‘Posts’ menu:

function removeMenu(){
 
global $menu;
 
//remove post top level menu
unset($menu[5]);
}
 
add_action( 'admin_head' , 'removeMenu');

If, playing with User Role Editor plugin, you met similar WordPress capabilities and functionality compatibility problem, lost some useful functionality after new custom user role try, please consider to share that information with us, send your comments here. If you not found decision for your problem yet, it is possible that we could find it together :).

Tags: , ,