1

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?

1

1 Answer 1

1

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
 * @author_url https://www.michaelbrentecklund.com/
 *
 * @return void
 */
function mbe_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', 'mbe_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
 * @author_url https://www.michaelbrentecklund.com/
 *
 * @return void
 */
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 = '';
    }

    # 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.' );
    }

}

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

add_action( 'admin_init', 'mbe_disallow_admin_pages' );
6
  • 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, 2013 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. Feb 15, 2013 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, 2013 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. Feb 15, 2013 at 22:48
  • So far, I've only needed the first loop.
    – Force Flow
    Mar 6, 2013 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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