0

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

2 Answers 2

1

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!

0

After your custom post registration complete use below type code it will help you as reference.

/**
 * Post Type: Blogs.
 */
function cptui_register_blog_cpts() {


    $labels = [
        "name" => __( "Blogs", "oba" ),
        "singular_name" => __( "Blog", "oba" ),
        "menu_name" => __( "Blogs", "oba" ),
        "all_items" => __( "All Blogs", "oba" ),
        "add_new" => __( "Add Blog", "oba" ),
        "add_new_item" => __( "Add New Blog", "oba" ),
        "edit_item" => __( "Edit Blog", "oba" ),
        "new_item" => __( "New Blog", "oba" ),
        "view_item" => __( "View Blog", "oba" ),
        "view_items" => __( "View Blog", "oba" ),
        "search_items" => __( "Search Blogs", "oba" ),
        "not_found" => __( "No Blogs Found", "oba" ),
        "not_found_in_trash" => __( "No Blogs found in Trash", "oba" ),
        "parent" => __( "Parent Blog", "oba" ),
        "featured_image" => __( "Featured image for this Blog", "oba" ),
        "set_featured_image" => __( "Set Featured image for this Blog", "oba" ),
        "remove_featured_image" => __( "Remove featured Image for this Blog", "oba" ),
        "use_featured_image" => __( "Use as featured image for this Blog", "oba" ),
        "archives" => __( "Blogs Archive", "oba" ),
        "insert_into_item" => __( "Insert into Blog", "oba" ),
        "uploaded_to_this_item" => __( "Uploaded to this Blog", "oba" ),
        "filter_items_list" => __( "Filter Blogs List", "oba" ),
        "items_list_navigation" => __( "Blog List Navigation", "oba" ),
        "items_list" => __( "Blogs list", "oba" ),
        "attributes" => __( "Blogs Attributes", "oba" ),
        "name_admin_bar" => __( "Blog", "oba" ),
        "item_published" => __( "Blog Published", "oba" ),
        "item_published_privately" => __( "Blog Published privately", "oba" ),
        "item_reverted_to_draft" => __( "Blog reverted to draft", "oba" ),
        "item_scheduled" => __( "Blog scheduled", "oba" ),
        "item_updated" => __( "Blog updated", "oba" ),
        "parent_item_colon" => __( "Parent Blog", "oba" ),
    ];

    $args = [
        "label" => __( "Blogs", "oba" ),
        "labels" => $labels,
        "description" => "This is a post type of Blog reading page",
        "public" => true,
        "publicly_queryable" => true,
        "show_ui" => true,
        "show_in_rest" => true,
        "rest_base" => "",
        "rest_controller_class" => "WP_REST_Posts_Controller",
        "has_archive" => false,
        "show_in_menu" => true,
        "show_in_nav_menus" => true,
        "delete_with_user" => false,
        "exclude_from_search" => false,
        "capability_type" => "blog",
        "map_meta_cap" => true,
        "hierarchical" => true,
        "rewrite" => [ "slug" => "blog", "with_front" => true ],
        "query_var" => true,
        "supports" => [ "title", "editor", "thumbnail", "custom-fields", "comments", "revisions", "author"],
        "taxonomies" => [ "blog_category", "blog_post_tag", "blog_post_author_name" ],
        // "capabilities" => array( 
        //         "manage_terms" => "manage_categories", 
        //         "edit_terms" => "manage_categories", 
        //         "delete_terms" => "manage_categories", 
        //         "assign_terms" => "edit_posts" 
        //     ), 
    ];

    register_post_type( "blog", $args );
    register_taxonomy('blog_category', 'blog', array('hierarchical' => true, 'label' => 'Blog Category', 'query_var' => true, 'rewrite' => array( 'slug' => 'blog-category' )));
    // register_taxonomy('blog_post_author_name', 'blog', array('hierarchical' => true, 'label' => 'E-Books Author', 'query_var' => true, 'rewrite' => array( 'slug' => 'blog-post-author-name' )));
}

add_action( 'init', 'cptui_register_blog_cpts' );

/**
 ** add teachers capability
 */
add_action('admin_init','blog_add_role_caps',999);
    function blog_add_role_caps() {

        // Add the roles you'd like to administer the custom post types
        $roles = 'administrator';

        // Loop through each role and assign capabilities
        // foreach($roles as $the_role) {    
             // $role = get_role($the_role);               
             $role = get_role($roles);               
             $role->add_cap( 'read' );
             $role->add_cap( 'read_blog');
             $role->add_cap( 'edit_blog' );
             $role->add_cap( 'edit_blogs' );
             $role->add_cap( 'edit_published_blogs' );
             $role->add_cap( 'publish_blogs' );
             $role->add_cap( 'delete_published_blogs' );
        // }
        }
        /**
 * Overwrite args of custom post type registered by plugin
 */
add_filter( 'register_post_type_args', 'change_capabilities_of_blog' , 10, 2 );

function change_capabilities_of_blog( $args, $post_type ){

 // Do not filter any other post type
 if ( 'blog' !== $post_type ) {

     // Give other post_types their original arguments
     return $args;

 }

 // Change the capabilities of the "book" post_type
 $args['capabilities'] = array(
            'edit_post' => 'edit_blog',
            'edit_posts' => 'edit_blogs',
            'edit_others_posts' => 'edit_other_blogs',
            'publish_posts' => 'publish_blogs',
            'read_post' => 'read_blog',
            'read_private_posts' => 'read_private_blogs',
            'delete_post' => 'delete_blog',
        );

  // Give the course_document post type it's arguments
  return $args;

}
2
  • Much appreciation for the response! While it didn't work in my case, see below, I am sure it'll help someone that finds this in the future. Thanks for the solid advice, man! :-D Jul 22, 2021 at 19:34
  • OK, I was edited my previous code so you copy that code and pest that in your function.php file. It must work.
    – Anjan
    Jul 24, 2021 at 18:38

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.