WordPress.org

Make WordPress Core

Opened 3 months ago

#48511 new defect (bug)

issue with custom post type capabilities

Reported by: mmenciassi Owned by:
Milestone: Awaiting Review Priority: normal
Severity: major Version: 5.2.4
Component: Role/Capability Keywords: needs-testing needs-patch
Focuses: administration Cc:
PR Number:

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".

Attachments (3)

simple-user-post-type-single.png (52.9 KB) - added by mmenciassi 3 months ago.
simple-user-post-type-summary.png (33.4 KB) - added by mmenciassi 3 months ago.
simple-user-dashboard.png (76.4 KB) - added by mmenciassi 3 months ago.

Download all attachments as: .zip

Change History (3)

Note: See TracTickets for help on using tickets.