5

I have the following 3 different Roles: Admin, Editor, and SEO. I have installed WordPress SEO by Yoast, and I want to get this:

  • I don't want the editors to see the SEO options, because they only write posts and don't know about SEO. There is a person with the SEO role, who will do the optimization.
  • I don't want the SEO person to see other plugins options. I just want to have the same capabilities that Editors, but with the SEO functions enabled.

I have been trying with some snippets from this site, and I am able to hide the meta box to the Editors, but not the little 'rating box' over the Publish button.

Also I don't know how to deal with the second point, because all the plugins uses the same manage_options capability, so I can't assign that capability to the SEO role. And I don't know how to change the capability needed without modifying the plugin files (what will be lost on plugin update).

Thanks in advance.

  • use manage_options for seo, then set rules for seo role from your theme's functions.php to disallow access to other plugin admin pages. you can redirect those pages to 404 page. – тнє Sufi Jul 28 '14 at 12:45
  • Could be a solution @тнєSufi. I was researching about hiding menu options with remove_menu_page, and get some results. I know that does not prevent the access but its a visual thing this time. – EliasNS Jul 29 '14 at 13:58
  • yes, it's not preventing. but you csn redirect those pages to 404 page, so anyone with seo role trying to access those pages with direct url will see a 404 page. – тнє Sufi Jul 29 '14 at 18:19
5

Maybe this isn't the best method because it does give an editor access to Settings and Options, but what this does is gives the a specific editor (based on user ID) the permissions to edit options. We then test if we're loading one of the options template, if we are AND the user id is the same id we've given permissions to, kill the process and spit out a message.

1) So first thing's first, create your SEO user and assign him an Editor role.

2) Next we need to give this user the ability to manage_options. You can find this by editing the user and looking at the URL, it should be one of the last parameters in the URL.

/** Give our SEO Guy Permissions **/
function give_seo_yoastToast() {
    $user = new WP_User( $seo_user_id );
    $user->add_cap( 'manage_options');
}
add_action( 'admin_init', 'give_seo_yoastToast');

3) Now we need to make sure all our SEO dudeski can't access any of the critical options. To my knowledge, the pages below are the only way this user can edit crucial information. IF they do view these pages, we kill it and spit out a message, feel free to change the message.

/** Remove Access to Certain Pages **/
add_action( 'load-options-general.php', 'prevent_seoguy_access' );
add_action( 'load-options-writing.php', 'prevent_seoguy_access' );
add_action( 'load-options-reading.php', 'prevent_seoguy_access' );
add_action( 'load-options-discussion.php', 'prevent_seoguy_access' );
add_action( 'load-options-media.php', 'prevent_seoguy_access' );
add_action( 'load-options-permalink.php', 'prevent_seoguy_access' );
add_action( 'load-options.php', 'prevent_seoguy_access' );
function prevent_seoguy_access(){
    $currID = is_user_logged_in() ? get_current_user_id() : 0;

    if($currID == $seo_user_id ){
        wp_die("There was a hole here once, it's gone now.");
        exit();
    }
}

4) Right now, he can view the pages in the menu but when he access them he sees the message above. Just as an extra step, let's actually remove this page from our menu. Please note that if you do remove the menu page without the above function, a savvy user could go to any of the option pages directly via URL.

/** Remove Settings Menu Page from SEO Guy **/
function seo_guy_menu() {
    if(!current_user_can('administrator')){
        remove_menu_page('options-general.php');
    }
}
add_action('admin_menu', 'seo_guy_menu');

5) And you're done!

Unfortunately as you pointed out in your question, Yoast doesn't look like it has a capability to give a user specific permission to all the SEO stuff without giving them unnecessary extra permissions as well which kind of sucks. And on another sidenote you could instead of going with a static $seo_user_id make a SEO Role instead, give that role editor permissions along with the above. That's a bit more work (not too much though) but if you only have 1 guy doing your SEO forever then the above method is fine I guess.

  • Thanks for the point 3. I don't need now but could be useful in the future. I achieved to hide the 'rating box' with a conditional function and CSS. It's only a visual problem, so it works. – EliasNS Jul 29 '14 at 14:04
  • Note that WP_User->add_cap will write to the database, so it just creates unneeded overhead to have this hooked on admin_init in: add_action( 'admin_init', 'give_seo_yoastToast'); Instead the Codex recommends to run this on theme/plugin activation. I.e.: add_action("after_switch_theme", "your_add_cap_function"); and add_action('switch_theme', 'your_remove_cap_function'); Or run it once and disable the code. – Pim Schaaf Dec 4 '15 at 13:57
4

The best way to change the capability that users need to view the Yoast SEO settings pages is by using the wpseo_manage_options_capability filter.

Here's an example of how this is used (placed in your functions.php file):

/**
 * Return the capability that users need to view the Yoast SEO settings pages.
 *
 * @return mixed|void
 */
function my_custom_wpseo_manage_options_capability() {

    $manage_options_cap = 'edit_others_posts';

    return $manage_options_cap;
}
add_filter( 'wpseo_manage_options_capability', 'my_custom_wpseo_manage_options_capability' );

In the above example, the edit_others_posts capability is used so that (in a default WordPress install) both Editors and Admins can access the Yoast SEO settings.

In your case where you don't wish 'normal' Editors to have access, you will need to create a new role (i.e. 'SEO') which has the same capabilities as an Editor, plus an additional custom capability (i.e. manage_wpseo_options) which can be used in the function above in place of edit_others_posts.

The Members plugin by Justin Tadlock allows you to easily create new roles and capabilities for this.

Note: This may not work on Multisite due to this issue.


Update: In Yoast SEO v5.5+, the wpseo_manage_options_capability filter has been renamed to wpseo_manage_options.

  • what does the part @return mixed|void do ?? – Mau Aug 14 '17 at 2:12
  • The @return tag is used to document the return value of functions or methods when using phpDocumentor. @return mixed|void simply means that the value returned by the function could be of any type, or void (i.e. does not return a value). – Matt Sims Aug 14 '17 at 8:53
  • 1
    This should be the chosen answer. – Matthew Clark Sep 14 '17 at 13:53
1

I just found a very simple solution. If you haven't already - install some form of a capabilities manager plugin. Then, create a new capability from within the capabilities manager - call it "CUSTOM_CAPABILITY_NAME" or whatever you want. Then assign it to a specific role or user.

Important: copy and backup and file you intend to modify in case you f*ck up, you can always restore the original.

Then, on the actual server you need to change directories down to wp-content/plugins/ and then grep and find all the files that have 'manage_options'.

Example: grep 'manage_options' */*

Tricky part, you'll have to find the main function that adds the menu or submenu to the dashboard. Here are my two examples for Yoast SEO specific access.

$manage_options_cap = apply_filters( 'wpseo_manage_options_capability', 'CUSTOM_CAPABILITY_NAME' );


add_submenu_page( 'wpseo_dashboard', __( 'WooCommerce SEO Settings', 'yoast-woo-seo' ), __( 'WooCommerce SEO', 'yoast-woo-seo' ), 'CUSTOM_CAPABILITY_NAME', $this->short_name, array(

PS - don't change anything that starts with a '$' - that's a variable. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.