Opened 4 years ago
Closed 4 months ago
#48511 closed defect (bug) (duplicate)
issue with custom post type capabilities
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | major | Version: | 5.2.4 |
Component: | Role/Capability | Keywords: | needs-testing needs-patch |
Focuses: | administration | Cc: |
Description
The need
The WP installation should have a Custom Post Type (i.e. promo)
We need to have two kind of users, one that can create, update and publish a new promo post, and another one that can only view and update pending promo post and save a new revision.
To do that I tried to create a custom post type both with a plugin and rightly with code written in the theme function.php file.
The Issue
The users that have only the update capability (not the create one), can view the link in the admin menu with the "Custom Post type" list of items, but when they click over it they receive a message: 'Sorry, you are not allowed to access this page.' with 403 status.
This behaviour is strange.
The following URL returns 403 status
/wp-admin/edit.php?post_type=promo_toy
but contrary to the previous page, access to a single post is allowed
for example, the following url works fine
/wp-admin/post.php?post=9&action=edit
what's happened?
It happens only when the Custom Post has only 1 subpage.
In the case above, the user doesn't have the creation capability, so the "add new" page is not added in submenu, so the custom post type page have only one subpage "All promo toy" that show all the posts of this kind of post type.
but...
in /wp-admin/includes/menu.php there is a step that removes the submenu page if there is only one submenu and it has same destination as the parent (around row 170)
Well, I receive a 403 status only in the case there is only one submenu page (and it was removed)
if I add (via function.php) a fake submenu page, for example and info page, the link to the post listing works fine without checks failure.
<?php function promo_toy_info() { } function info_pages() { add_submenu_page( 'edit.php?post_type=promo_toy', 'info page', 'info page', 'edit_others_promo_toys', 'promo-toy-info', 'promo_toy_info'); } add_action('admin_menu', 'info_pages');
The same thing happens if I comment the code in the point that removes the submenu page (if is only one and it has the same link of the parent)
if I comment this point in /wp-admin/includes/menu.php it works fine
<?php /* * If there is only one submenu and it is has same destination as the parent, * remove the submenu. */ if ( ! empty( $submenu[ $data[2] ] ) && 1 == count( $submenu[ $data[2] ] ) ) { $subs = $submenu[ $data[2] ]; $first_sub = reset( $subs ); if ( $data[2] == $first_sub[2] ) { unset( $submenu[ $data[2] ] ); } }
the custom post type creation
"here the creation and setting of the custom post type inside functions.php"
<?php function custom_init() { $args = [ "labels" => [ "name" => "Promos Toy", "singular_name" => "Promo Toy", "all_items" => "All Promos Toy", "add_new_item" => "Add new Promo Toy", "edit_item" => "Edit Promo Toy", "new_item" => "New Promo Toy", "view_item" => "View Promo Toy", "search_items" => "Search Promos Toy", "not_found" => "No Promos Toy found.", "not_found_in_trash" => "No Promos Toy found in trash." ], "description" => "Test Post Type", "public" => false, "publicly_queryable" => true, "show_ui" => true, "show_in_nav_menus" => true, "has_archive" => false, "show_in_menu" => true, "show_in_rest" => true, "rest_base" => "", "rest_controller_class" => "", "exclude_from_search" => true, "capability_type" => array("promo_toy", "promo_toys"), "map_meta_cap" => true, "hierarchical" => false, "rewrite" => "", "menu_position" => "", "menu_icon" => "dashicons-admin-page", "query_var" => true, "supports" => ["title", "revisions", "author"], "taxonomies" => [], "capabilities" => [ "edit_post" => "edit_promo_toy", "edit_others_posts" => "edit_others_promo_toys", "edit_private_posts" => "edit_private_promo_toys", "edit_published_posts" => "edit_published_promo_toys", "read_private_posts" => "read_private_promo_toys", "delete_post" => "delete_promo_toy", "delete_others_posts" => "delete_others_promo_toys", "delete_private_posts" => "delete_private_promo_toys", "delete_published_posts" => "delete_published_promo_toys", "publish_posts" => "publish_promo_toys", "create_posts" => "create_promo_toys" ] ]; $res = register_post_type("promo_toy", $args); } add_action( 'init', 'custom_init' );
The users capabilities
The admin has all the custom post type capabilities
The user that could make new review but can't create or publish it has these capabilities:
read, edit_promo_toys, edit_others_promo_toys
the capabilities are assigned via plugin, I tried to use both Members (v. 2.2.0) and User Role Editor (v. 4.52) the results is the same.
Plugin installed
For this test I used a brand new WP installation (last version) with only one plugin: "members".
Duplicate of #22895.