Search code examples
phpwordpresscustom-wordpress-pageswordpress-plugin-creationwordpress-capabilities

WordPress: Custom User Role cannot access Custom Post Type | "Sorry, you are not allowed to access this page"


The Objective: Create a custom post type and only give administrator and a custom role permission to view / control it.

The Problem: For administrators, it works perfectly fine but for the custom role I get: Sorry, you are not allowed to access this page.

At first, I thought it could just be a matter of capability to access it, but this bit of code begs to differ:

add_submenu_page( /*  STAFF PAGES   */
                'redacted', //Parent Menu Slug
                'Staff Pages', //Page Title text
                'Staff Pages', //Menu Title text
                'edit_staff', //Capability required for this menu to be displayed by user
                'edit.php?post_type=staff' //Link to page
);

The custom role can see the link to the custom post type but cannot access it. Also, running print_r($wp_roles->get_role( 'supervisor' )->capabilities); does show that the role correctly possesses the necessary capabilities. I've had a few theories as to how to solve this, but so far none have panned out.

My code is as follows:

function initialize_plugin(){
//Non-relevant code redacted
add_action( 'admin_init', array($this, 'admin_init') );
}
function activate(){
    $this->custom_post_types();
    $this->adjust_user_roles();
    //Non-relevant code redacted
}



/* My Custom Post Type */
function custom_post_types(){
            register_post_type( 'staff', array(
                'labels' => array(
                    //labels redacted
                ),
                'has_archive'       => false,
                'hierarchical'      => true,
                'menu_icon'         => 'dashicons-groups',
                'capability_type'   => array('staff', 'staffs'),
                'map_meta_cap'      => true,
                'public'            => true,
                'show_in_menu'      => false,
                'rewrite'           => array( 'slug' => 'staff', 'with_front' => false ),
                'supports'          => array( 'title', 'thumbnail', 'custom-fields', 'revisions'),
                'show_in_rest'      => true,
                'taxonomies'        => array( 'member-type' ),
                'menu_position'     => 2,
            ));



/* My Custom Role */
function adjust_user_roles(){
$wp_roles = new WP_Roles(); 

$wp_roles->add_role(
              'supervisor', __( 'Supervisor' ),
               array(
                    //General
                    'moderate_comments'         => true,
                    'upload_files'              => true,
                   
                    //Blog Posts
                    'read'                      => true,
                    'read_post'                 => true,
                    'edit_post'                 => true,
                    'edit_posts'                => true,
                    'edit_others_posts'         => true,
                    'delete_posts'              => false, //Can't delete posts

                    //Staff (Custom Post Type)
                    'create_staffs'             => true,
                    'read_staff'                => true,
                    'edit_staff'                => true,
                    'edit_staffs'               => true,
                    'edit_others_staffs'        => true,
                    'edit_published_staffs'     => true,
                    'edit_private_staffs'       => true,
                    'delete_staff'              => true,
                    'delete_others_staffs'      => true,
                    'delete_published_staffs'   => true,
                    'delete_private_staffs'     => true,
                    'publish_staffs'            => true,
                    'read_private_staffs'       => true,
              )
);



/* Adding to administrator */
function admin_init(){
   //Non-relevant code redacted
   $this->adjust_user_capabilities("add");
}

function adjust_user_capabilities($action, $roles=array('administrator','editor', 'supervisor')){
  $staffCaps = array(
                'create_staff',
                'read_staff',
                'edit_staff',
                'edit_staffs',
                'edit_others_staffs',
                'edit_published_staffs',
                'edit_private_staffs',
                'delete_staff',
                'delete_others_staffs',
                'delete_published_staffs',
                'delete_private_staffs',
                'publish_staffs',
                'read_private_staffs',              
            );

            //Cycle through each role
            foreach($roles as $roleType) :
                $role = get_role( $roleType );
            
                //Add each capability
                if($action == "add"){
                    foreach($staffCaps as $staffCap){   
                        $role->add_cap( $staffCap );
                    }
                }
            
                //Remove each capability
                elseif($action == "remove"){
                    foreach($staffCaps as $staffCap){
                        $role->remove_cap( $staffCap );
                    }
                }
            endforeach;
}

NOTE: This code appears in wp-content/plugins/myplugin/myplugin.php. In addition, I have redacted some non-relevant portions of my code for clarity, such as adding or removing a submenu, and tried to expound more of the structure. Feel free to let me know if there is anything I missed or anyone has questions on. :-D

In Closing: I could just be a major idiot overlooking something obvious, but regardless, any and all help / advice / suggestions are highly appreciated! If I get the answer on my own, I'll add it to this discussion to help anyone else out facing a similar problem and/or my future self lol


Solution

  • SOLUTION: With some playing around I realized I am definitely an idiot and WAY over-thought things. While I had previously read and tried some of the things in this similar post, I ended up substituting their code for mine and found it actually worked for my use case. In trying to understand why that was, I began trying to convert it to become mine and quickly found the root of my problem:

    /* My Custom Post Type */
    function custom_post_types(){
                register_post_type( 'staff', array(
                    'labels' => array(
                        //labels redacted
                    ),
                    'has_archive'       => false,
                    'hierarchical'      => true,
                    'menu_icon'         => 'dashicons-groups',
                    'capability_type'   => array('staff', 'staffs'),
                    'map_meta_cap'      => true,
                    'public'            => true,
    /*---------> */ 'show_in_menu'      => false, /* <---------*/
                    'rewrite'           => array( 'slug' => 'staff', 'with_front' => false ),
                    'supports'          => array( 'title', 'thumbnail', 'custom-fields', 'revisions'),
                    'show_in_rest'      => true,
                    'taxonomies'        => array( 'member-type' ),
                    'menu_position'     => 2,
                ));
    

    In an effort to have a clean custom menu, I set show_in_menu to false which created the issues for me. When I changed it to 'show_in_menu' => true, my issue was resolved. In addressing this, I am tempted to just try remove_menu_page(); or perhaps consider something more elegant.

    Anyways, the lesson for today is not to be hyper-focused on one aspect. Hopefully this helps someone else and happy coding!