Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I created some custom post types, but I would like to hide them in the dashboard from Subscribers, Authors, and Editors (essentially, just allow administrators to access them).

Can I do this without installing a plugin?

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

I'm sure you could specify some capabilities while registering the Post Type itself. Although, here is a more robust version that can be used widely across the administration dashboard.

/**
 * Hide dashboard administrator menus from disallowed user roles.
 *
 * @author Michael Ecklund
 * @access public
 *
 * @return void
 */
public function hide_menus(){
    global $current_user, $menu;
    /* Set list of disallowed user roles. */
    $disallowed_roles = array('subscriber', 'author', 'editor');
    $disallowed = false;
    /* Check current user role against all disallowed roles. */
    foreach($disallowed_roles as $disallowed_role){
        /* Current user role must not be disallowed. */
        if(in_array($disallowed_role, $current_user->roles)){
            $disallowed = true;// User role disallowed.
            break;
        }
    }
    /* User passed the check. Bail before hiding the menu. */
    if($disallowed === false){
        return;
    }
    /* Set list of disallowed dashboard administration menus. */
    $restricted = array(
        __('INSERT MENU NAME HERE')// Text as it appears in the admin menu.
    );
    /* Attempt to hide admin menus. */
    foreach($menu as $index => $menu_data){
        if(in_array($menu_data[0], $restricted)){
            unset($menu[$index]);
        }
    }
}

In order to fire the function, you must add the action.

add_action('admin_menu', array($this, 'hide_menus'), 101);

The above code only goes as far as hiding the admin menus form displaying to the user. They can still directly access the pages if they know the correct URLs.

You can use this to deny specific admin pages from being accessed by unprivileged users.

/**
 * Restrict admin pages from unprivileged users.
 *
 * @author Michael Ecklund
 * @access public
 *
 * @return void
 */
public function mbe_disallow_admin_pages(){
    global $pagenow;
    /* Skip checking administrative users. */
    if(current_user_can('administrator')){
        return;
    }
    /* Set denyable & hookable list of admin pages.*/
    $page_slugs = apply_filters('mbe_disallowed_admin_pages', array(
        'admin.php' => 'jetpack',
        'options-general.php' => ''
    ));
    /* Page parameter isn't always present. */
    if(isset($_GET['page'])){
        $page = $_GET['page'];
    } else{
        $page = ''; 
    }
    /* Check current admin page against denied admin page list. */
    if(array_key_exists($pagenow, $page_slugs) && in_array($page, $page_slugs)){
        wp_die('You do not have sufficient permissions to access this page.');
    }
}
add_action('admin_init', array($this, 'mbe_disallow_admin_pages'));
share|improve this answer
    
Would be more practical to specify access while registering the post type? The custom post types are created in some custom plugins I built. –  Force Flow Feb 15 '13 at 14:54
    
Personally, I have this hide menus method built into a class of mine. So it's really quite easy for me to hide all different kinds of administration menus from different user roles, with minimal effort. –  Michael Ecklund Feb 15 '13 at 15:25
    
ok, I put your code in my functions.php file just to test it out. I had to change the add_action command to add_action('admin_menu', 'hide_menus'); Worked like a charm. The while loop for "hiding admin menus again" doesn't seem like it would be necessary. Have you encountered a situation where it was needed? –  Force Flow Feb 15 '13 at 17:31
    
It's likely not needed. However, there was one particular plugin I was trying to hide the menu from certain user roles, and it only worked if I had both loops. You can go ahead and remove it if the first loop does the job fine for you. –  Michael Ecklund Feb 15 '13 at 22:48
    
So far, I've only needed the first loop. –  Force Flow Mar 6 '13 at 14:25
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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