programing

WordPress user with custom role cannot view list page for custom post types without the "create_posts" capabililty

instargram 2023. 10. 9. 21:19
반응형

WordPress user with custom role cannot view list page for custom post types without the "create_posts" capabililty

I am running a WordPress 5.2.3 site and having trouble with something in the admin panel.

나는 맞춤형 역할이 있어요, 그냥 그렇게 하죠.librarian, 그리고 맞춤형 포스트 타입이라 부르자구요.book.

나는 그것을 만들기를 원합니다.librarian편집할 수 있습니다.book새것을 만들지는 못합니다.

Following the advice in another question (WordPress: Disable “Add New” on Custom Post Type) and WordPress documentation, I have ended up with this code:

// Custom post type.
register_post_type('book',
    array(
        'labels'                => array(
            'name' => __( 'book' ),
            'singular_name' => __( 'Book' )
        ),
        'capability_type'       => array('book', 'books'),
        'capabilities'          => array(
            'create_posts' => 'do_not_allow' // <-- The important bit.
        ),
        'map_meta_cap'          => true,
        'description'           => 'Book full of pages',
        'exclude_from_search'   => true,
        'publicly_queryable'    => false,
        'show_in_nav_menus'     => false,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'show_in_rest'          => true,
        'menu_icon'             => 'dashicons-location',
        'menu_position'         => 5,
        'supports'              => array('title', 'revisions')
    ));
// Custom role.
add_role('librarian', 'Librarian', array(
    'read'                  => true,
    'edit_books'            => true,
    'edit_published_books'  => true
));

내가 방문했을 때 나는 그것을 기대하고 있었습니다.edit.php?post_type=book로서librariran그러면 나는 목록을 볼 것입니다.books편집을 위해 새로 추가 단추가 표시되지 않습니다.하지만 제가 실제로 얻은 것은403응답:

Sorry, you are not allowed to access this page.

I think this may be a bug in WordPress, because of the following cases:

  • 방문하면edit.php?post_type=book…로서administrator, 원하는 대로 Add New(새로 추가) 버튼이 없는 목록 페이지가 나타납니다.
  • 제가 만약에.librarian역할을 맡다edit_postscapability(기능), 원하는 대로 Add New(새로 추가) 버튼이 없는 목록 페이지가 나타납니다(단, 그들에게 다음을 제공하고 싶지 않습니다).edit_posts능력!)

These make me think that it isn't a problem with the custom post type set up in general.

  • 제거하면.'create_posts' => 'do_not_allow'로부터book유형 등록,librarian 목록 페이지를 볼 수 있지만 새로 추가 단추가 포함되어 있습니다.

This makes me think that it isn't a problem with the custom role set up in general.

Has anyone encountered this issue before? Have I missed anything from my configuration? Or is there an easy patch or workaround?

Any help would be appreciated! Thanks.

It appears that this is a bug in WordPress. I have found the source of the problem and a workaround.

Workaround

원인에 관심이 없다면 해결 방법은 이 화장품 코드를 언급하는 것입니다.wp-admin/includes/menu.php:

https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/menu.php#L168

/*
 * 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] ] );
    }
}

This will mean that some menu items that previously didn't show a submenu now will (with a single item the same as the main menu item), but that is only a cosmetic UI change.

Cause

For those of you that want to know the detail…

액세스edit.php?post_type=book이 검문에 실패하고 있었습니다.wp-admin/includes/menu.php:

https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/menu.php#L341

if ( ! user_can_access_admin_page() ) {

    /**
     * Fires when access to an admin page is denied.
     *
     * @since 2.5.0
     */
    do_action( 'admin_page_access_denied' );

    wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
}

로 전화가 걸려옵니다.

get_admin_page_parent()합니다가 합니다.user_can_access_admin_page()falselibrarian()administrator다른 이유로 역할이 전달됩니다.

,get_admin_page_parent()비어 있지 않은 부모를 반환하고 액세스 검사는 여기서 올바르게 진행됩니다.

인 입니다.$submenuUI를 결정하고 권한 계층에 대한 결정을 내리는 데 모두 사용되고 있습니다.위의 해결 방법 외에 워드프레스 코드 전체에서 부작용이 발생하지 않는 이 문제에 대한 즉각적인 해결책은 찾을 수 없습니다.

핵심 파일을 편집할 필요 없이 해결책을 찾은 것 같습니다.

말씀하신 것처럼, 이 버그의 원인은 하위 메뉴 항목이 없는 빈 메뉴로 인해 액세스 검사가 잘못된 오류를 반환하게 됩니다.

따라서 해결 방법은 목록 페이지를 최상위 메뉴로 만들지 않는 것입니다.대신 기존 메뉴의 하위 메뉴로 만듭니다.이렇게 하면 빈 최상위 메뉴가 나타나지 않고 '새로 추가' 버튼 없이 목록 페이지를 올바르게 볼 수 있습니다.

이것은 단지 해결책일 뿐이지 이상적이지는 않습니다.하지만 아마 핵심 파일을 편집하는 것보다는 나을 것입니다.

목록 페이지를 하위 메뉴 항목으로 지정하면서 사용자 지정 게시 유형을 만드는 방법은 간단합니다.스의 .register_post_type다라는 를 가지고 .show_in_menu. 문서에 따르면 다음과 같습니다.

기존 최상위 메뉴의 문자열(예:'도구.php' 또는 'edit. php?post_type=page')의 하위 메뉴로 게시 유형이 배치됩니다.

코드는 다음과 같습니다.

register_post_type('book',
array(
    'labels'                => array(
        'name' => __( 'book' ),
        'singular_name' => __( 'Book' )
    ),
    'capability_type'       => array('book', 'books'),
    'capabilities'          => array(
        'create_posts' => 'do_not_allow'
    ),
    'map_meta_cap'          => true,
    'show_ui'               => true,
    'show_in_menu'          => 'tools.php',   //or whatever top-level menu you'd like
    //... other args omitted
));

이 문제에 대해 두 가지 해결 방법을 찾았습니다.

custom_post_type create_posts custom_posts 를을 사용하는 에 이 더 .do_not_allow

그래서 다음을 사용합니다.

...
'capability_type'     => 'books',
'capabilities'        => array(
    'create_posts' => 'add_new_books'
),
'map_meta_cap'        => true,
...

이렇게 하면 관리자 또는 다른 관리자에게 add_new_books 기능을 할당할 수 있지만 다른 역할에는 허용하지 않습니다.

옵션 1:
가 '를 있는 후(user_has_cap가 'edit_posts'음 Posts합니다)

add_filter(
    'user_has_cap',
    function( $all_caps, $caps ) {
        global $typenow, $menu;

        if ( is_admin() && ! empty( $typenow ) && stripos( $_SERVER['REQUEST_URI'], 'edit.php' ) && stripos( $_SERVER['REQUEST_URI'], 'post_type=' . $typenow ) && in_array( 'edit_posts', $caps, true ) ) {
            // Temporarily assign the user the edit_posts capability
            $all_caps['edit_posts'] = true;
            // Now Remove any menu items with edit_posts besides the custom post type pages.
            if ( ! empty( $menu ) ) {
                foreach ( $menu as $menu_key => $menu_item ) {
                    if ( ! empty( $menu_item[1] ) && ( $menu_item[1] === 'edit_posts' || $menu_item[2] === 'edit.php' ) ) {
                        remove_menu_page( $menu_item[2] );
                    }
                }
            }
        }

        return $all_caps;
    },
    10,
    2
);

이것이 작동하는 동안 정의되지 않은 인덱스에 대한 PHP Notice를 추가합니다.

옵션 2:
now )($page now링)

add_action(
    'admin_menu',
    function () {
        global $pagenow, $typenow;

        if ( is_admin() && ! empty( $typenow ) && ! empty( $pagenow ) && $pagenow === 'edit.php' && stripos( $_SERVER['REQUEST_URI'], 'edit.php' ) && stripos( $_SERVER['REQUEST_URI'], 'post_type=' . $typenow ) ) {
            $pagenow = 'custom_post_type_edit.php';
        }
    }
);

이것은 PHP Notice를 추가하지 않고 작동하지만 $page now 변수를 변경하기 때문에 예상치 못한 문제가 발생할 수 있지만 해당 페이지에서만 발생할 수 있습니다.

지금까지는 옵션 2를 문제없이 사용하고 있습니다.

이 코드는 나를 위해 작동됩니다.

/**
 *  Fix Disable add new cpt post (post-new.php?post_type=) - craete_posts
 */

function disable_create_newpost()
{
    global $pagenow, $typenow;

    if (is_admin() && !empty($typenow) && !empty($pagenow) && $pagenow === 'edit.php' && stripos($_SERVER['REQUEST_URI'], 'edit.php') && stripos($_SERVER['REQUEST_URI'], 'post_type=' . $typenow)) {
        $pagenow = 'edit-' . $typenow . '.php';
    }
}

add_action('admin_menu', 'disable_create_newpost');


// END PART


고마워요 @ggedde

언급URL : https://stackoverflow.com/questions/58218457/wordpress-user-with-custom-role-cannot-view-list-page-for-custom-post-types-with

반응형