I’m working on this:
- Create a menu entry in the admin panel name "Products"
- Have a dozen of custom post types, all as submenus items of my admin menu "Products" entry
- Allow a role to only show this, and not others custom post types.
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:
- If I add the
edit_posts
capability to my custom role, the user can display thepost-new.php
page properly for my custom post type items - or if I replace the
show_in_menu => 'products'
withshow_in_menu => true
to display all my post types at top first menu level items, this seems to be working too.
Maybe I’m doing something wrong, and if someone already face this kind of issue, he or she could be really helpful.