Wordpress: How to allow some comment-actions (delete, edit...) only to specific roles?

1.7k Views Asked by At

Is it possible to customize Wordpress via action, hook or anything, that

  1. only users of role "administrator" or "editor" may trash, spam or edit comments from the backend?
  2. only users of role "administrator" or "editor" may trash, spam or edit comments from mail that will be generated on new comments?

I did not find anything on codex.wordpress.org as well as I did not find a proper plugin. :-/

Thanks!

2

There are 2 best solutions below

1
On BEST ANSWER

I would advice using a plugin such as User Role Editor for this, but hey - heres a working code example :):

In the the class WP_Role you'll find a property named ‘edit_comment’ which is mapped to the ‘edit_posts’ thus isn't handled as a separate capability. we can however modify the behaviour by applying a filter to the selected user role we want to restrict editing comments on by using the map_meta_cap function.

Example for: Only users "administrator" or "editor" may trash, spam or edit comments from the backend:

<?php
// Restrict editing capability of comments using `map_meta_cap`
function restrict_comment_editing( $caps, $cap, $user_id, $args ) {
 if ( 'edit_comment' == $cap ) {
      // Allowed roles 
      $allowed_roles = ['editor', 'administrator'];

      // Checks for multiple users roles
      $user = wp_get_current_user();
      $is_allowed = array_diff($allowed_roles, (array)$user->roles);

      // Remove editing capabilities on the back-end if the role isn't allowed
      if(count($allowed_roles) == count($is_allowed))
        $caps[] = 'moderate_comments';
      }
  }

  return $caps;
}

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

// Hide comment editing options on the back-end*
add_action('init', function() {
  // Allowed roles
  $allowed_roles = ['editor', 'administrator'];

  // Checks for multiple users roles
  $user = wp_get_current_user();
  $is_allowed = array_diff($allowed_roles, (array)$user->roles);

  if(count($allowed_roles) == count($is_allowed)) {
    add_filter('bulk_actions-edit-comments', 'remove_bulk_comments_actions');
    add_filter('comment_row_actions', 'remove_comment_row_actions');
  }
});

function remove_bulk_comments_actions($actions) {
  unset($actions['unapprove']);
  unset($actions['approve']);
  unset($actions['spam']);
  unset($actions['trash']);

  return $actions;
}

function remove_comment_row_actions($actions) {
  unset($actions['approve']);
  unset($actions['unapprove']);
  unset($actions['quickedit']);
  unset($actions['edit']);
  unset($actions['spam']);
  unset($actions['trash']);

  return $actions;
}
?>

Code goes into your functions.php file

0
On

Thanks to @Kradyy I came around to map_meta_cap and remove_cap.

With the following in the functions.php, the links are removed in the comments section of the dashboard as well as in the email sent to the author (except for admins and editors):

global $wp_roles;
$allowed_roles = ['editor', 'administrator'];
foreach (array_keys($wp_roles->roles) as $role){
    if (!in_array($role, $allowed_roles)) {
        $wp_roles->remove_cap( $role, 'moderate_comments' );
    }
}