Site icon Hip-Hop Website Design and Development

Custom post types as sub menu pages and role capabilities issue

I’m working on this:

The two first points are working very well, here is my code:

class Product {
    private const POST_TYPES = array(...);

    public function __construct() {
        add_action('init', array($this, 'registerProductsPostTypes'));
        add_action('admin_menu', array($this, 'registerMenuProductPostType'));
    }

    public function registerMenuProductPostType(): void {
        add_menu_page(
            'Produits',
            'Produits',
            'products',
            'products',
            array($this, 'initProductsMenu'),
            'dashicons-products',
            '20'
        );
    }

    public function registerProductsPostTypes() {
        foreach (self::POSTS_TYPES as $postsType) {
            register_post_type($postsType['postType'], array(
                'labels' => array(
                    'name' => $postsType['label'],
                    'menu_name' => $postsType['menu'] ?? $postsType['label']
                ),
                'public' => true,
                'has_archive' => 'explorer/' . $postsType['slug'],
                'rewrite' => 'explorer/' . $postsType['slug'],
                'show_in_menu' => 'products',
                'supports' => array('title', 'editor', 'thumbnail'),
                'taxonomies' => array(),
                'capability_type' => array('product', 'products'),
                'map_meta_cap' => true
            ));
        }        
    }
}

How you can see it, I added a capability products to my menu item to make it available to my custom role (see below) and a capability_type on all my post types to trigger them on the custom role too, with the map_meta_cap param.

Here is my role creation:

add_role(self::ROLE_SLUG, self::ROLE_NAME); // (class constants are well defined)
$role = get_role(self::ROLE_SLUG);

$role->add_cap('read');

// To make the menu item displays and the list of post types on edit.php?post_type=xxx
$role->add_cap('products');

// Add all caps to allow full control of products post types
$role->add_cap('edit_product');
$role->add_cap('read_product');
$role->add_cap('create_product');
$role->add_cap('create_products');
$role->add_cap('delete_product');
$role->add_cap('edit_products');
$role->add_cap('edit_others_products');
$role->add_cap('read_private_products');
$role->add_cap('delete_products');
$role->add_cap('delete_private_products');
$role->add_cap('delete_published_products');
$role->add_cap('delete_others_products');
$role->add_cap('edit_private_products');
$role->add_cap('edit_published_products');

At this point, user with this custom role can access admin and display the whole post types on their edit.php?post_type=xxx page.

Problem: the user cannot create a new item on the post-new.php?post_type=xxx page. A "not allowed" WordPress error page appears.

I do not know if this can be a real WordPress bug, because:

Maybe I’m doing something wrong, and if someone already face this kind of issue, he or she could be really helpful.