사용자가 특정 페이지 만 편집하도록 허용


16

특정 사용자가 한 페이지 만 편집하고 하위 페이지를 편집하도록 허용하고 싶습니다. 이것이 어떻게 가능할까요? 오래된 Role Scoper를 사용해 보았지만 많은 문제와 버그가있는 것 같습니다.


2
플러그인 추천에 대한 귀하의 요청이 주제를 벗어 났기 때문에 제거했습니다. 그렇습니다. 이것은 플러그인으로 가능해야하지만 기본 기능에 대한 이러한 종류의 해킹이 필요한 작업을 시도 할 때 도움이 될 수는 없지만 잘못된 접근법을 사용하고 있다고 생각합니다. 프로젝트를보다 자세히 설명 할 수 있습니까?
s_ha_dum

답변:


14

이러한 작업을 구현하기 위해 가장 먼저해야 할 일은 사용자가 편집 할 수있는 페이지를 인식하는 것입니다.

여러 가지 방법이 있습니다. 사용자 메타, 일부 구성 값이 될 수 있습니다 ...이 답변을 위해 함수 lile가 있다고 가정합니다.

function wpse_user_can_edit( $user_id, $page_id ) {

   $page = get_post( $page_id );

   // let's find the topmost page in the hierarchy
   while( $page && (int) $page->parent ) {
     $page = get_post( $page->parent );
   }

   if ( ! $page ) {
     return false;
   }

   // now $page is the top page in the hierarchy
   // how to know if an user can edit it, it's up to you...

}

사용자가 페이지를 편집 할 수 있는지 확인할 수있는 방법이 있으므로 WordPress에이 기능을 사용하여 페이지를 편집하는 데 사용 기능을 확인하도록 지시하면됩니다.

'map_meta_cap'필터 를 통해 수행 할 수 있습니다 .

다음과 같은 것 :

add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) {

    $to_filter = [ 'edit_post', 'delete_post', 'edit_page', 'delete_page' ];

    // If the capability being filtered isn't of our interest, just return current value
    if ( ! in_array( $cap, $to_filter, true ) ) {
        return $caps;
    }

    // First item in $args array should be page ID
    if ( ! $args || empty( $args[0] ) || ! wpse_user_can_edit( $user_id, $args[0] ) ) {
        // User is not allowed, let's tell that to WP
        return [ 'do_not_allow' ];
    }
    // Otherwise just return current value
    return $caps;

}, 10, 4 );

이 시점에서 사용자를 하나 이상의 페이지 에 연결 하는 방법 만 있으면됩니다 .

사용 사례에 따라 다른 솔루션이있을 수 있습니다.

유연한 해결책은 "루트"페이지 드롭 다운 ( wp_dropdown_pages)을 사용자 관리 편집 화면에 추가하고 선택한 페이지를 사용자 메타로 저장하는 것입니다.

'edit_user_profile'페이지 드롭 다운 필드를 추가 'edit_user_profile_update'하고 선택한 값을 사용자 메타로 저장하는 데 활용할 수 있습니다 .

이 웹 사이트에는 자세한 방법에 대한 충분한 지침이 있습니다.

페이지가 사용자 메타로 저장 wpse_user_can_edit()되면 페이지 ID가 사용자 메타 값의 일부인지 확인하여 위 의 기능을 완료 할 수 있습니다.

페이지를 편집하는 기능을 제거하면 WordPress에서 나머지 작업을 수행합니다. 백엔드 및 프론트 엔드에서 편집 링크를 제거하고 직접 액세스하지 못하게합니다.


3
이것은 내 대답보다 훨씬 낫습니다. 사용자의 기능을 수정하고 WordPress가 나머지를 처리하도록 할 때 편집 링크를 제한하는 이유는 무엇입니까?
ricotheque

긴 "u"는 자음으로 시작하는 "yu"처럼 들리므로 "an"이 아닌 "user"라는 단어 앞에 "a"를 사용해야합니다.
Philip

7

글로벌 변수를 피하기 위해 PHP 클래스를 사용하더라도이 기능을 구현하려면 적은 양의 코드가 필요합니다. 또한 대시 보드에서 사용자에게 금지 된 페이지를 숨기고 싶지 않았습니다. 사이트에 이미있는 콘텐츠를 추가하면 어떻게됩니까?

$user_edit_limit = new NS_User_Edit_Limit(
    15,       // User ID we want to limit
    [2, 17]   // Array of parent page IDs user is allowed to edit
                 (also accepts sub-page IDs)
);

class NS_User_Edit_Limit {

    /**
     * Store the ID of the user we want to control, and the
     * posts we will let the user edit.
     */
    private $user_id = 0;
    private $allowed = array();

    public function __construct( $user_id, $allowed ) {

        // Save the ID of the user we want to limit.
        $this->user_id = $user_id;

        // Expand the list of allowed pages to include sub pages
        $all_pages = new WP_Query( array(
            'post_type' => 'page',
            'posts_per_page' => -1,
        ) );            
        foreach ( $allowed as $page ) {
            $this->allowed[] = $page;
            $sub_pages = get_page_children( $page, $all_pages );
            foreach ( $sub_pages as $sub_page ) {
                $this->allowed[] = $sub_page->ID;
            }
        }

        // For the prohibited user...
        // Remove the edit link from the front-end as needed
        add_filter( 'get_edit_post_link', array( $this, 'remove_edit_link' ), 10, 3 );
        add_action( 'admin_bar_menu', array( $this, 'remove_wp_admin_edit_link' ), 10, 1 );
        // Remove the edit link from wp-admin as needed
        add_action( 'page_row_actions', array( $this, 'remove_page_list_edit_link' ), 10, 2 );
    }

    /**
     * Helper functions that check if the current user is the one
     * we want to limit, and check if a specific post is in our
     * list of posts that we allow the user to edit.
     */
    private function is_user_limited() {
        $current_user = wp_get_current_user();
        return ( $current_user->ID == $this->user_id );
    }
    private function is_page_allowed( $post_id ) {
        return in_array( $post_id, $this->allowed );
    }

    /**
     * Removes the edit link from the front-end as needed.
     */
    public function remove_edit_link( $link, $post_id, $test ) {
        /**
         * If...
         * - The limited user is logged in
         * - The page the edit link is being created for is not in the allowed list
         * ...return an empty $link. This also causes edit_post_link() to show nothing.
         *
         * Otherwise, return link as normal.
         */
        if ( $this->is_user_limited() && !$this->is_page_allowed( $post_id ) ) {
            return '';
        }
        return $link;
    }

    /**
     * Removes the edit link from WP Admin Bar
     */
    public function remove_wp_admin_edit_link( $wp_admin_bar ) {
        /**
         *  If:
         *  - We're on a single page
         *  - The limited user is logged in
         *  - The page is not in the allowed list
         *  ...Remove the edit link from the WP Admin Bar
         */
        if ( 
            is_page() &&
            $this->is_user_limited() &&
            !$this->is_page_allowed( get_post()->ID )
        ) {
            $wp_admin_bar->remove_node( 'edit' );
        }
    }

    /**
     * Removes the edit link from WP Admin's edit.php
     */
    public function remove_page_list_edit_link( $actions, $post ) {
        /**
         * If:
         * -The limited user is logged in
         * -The page is not in the allowed list
         * ...Remove the "Edit", "Quick Edit", and "Trash" quick links.
         */
        if ( 
            $this->is_user_limited() &&
            !$this->is_page_allowed( $post->ID )
        ) {
            unset( $actions['edit'] );
            unset( $actions['inline hide-if-no-js']);
            unset( $actions['trash'] );
        }
        return $actions;
    }
}

위의 코드는 다음과 같이 작동하거나 필요에 따라 표시되지 않도록합니다.

  1. get_edit_post_link
  2. Edit Page 페이지에 나타나는 WP 관리 막대의 링크
  3. Edit, Quick Edit,와 Trash페이지 수의 아래에 표시 빠른 링크/wp-admin/edit.php?post_type=page

이것은 내 로컬 WordPress 4.7 설치에서 작동했습니다. 사이트의 페이지가 자주 변경되지 않는다고 가정하면 페이지의 ID와 해당 하위 페이지를 하드 코딩 WP_Query하고 __construct메소드 내부를 제거하는 것이 좋습니다. 이렇게하면 데이터베이스 호출을 많이 절약 할 수 있습니다.


@Ben

그래, gmazzap의 답변을 보았을 때 나는 "이제 왜 그렇게 생각하지 않습니까?"
ricotheque

5

플러그인을 멀리하고 싶다면 functions.php 파일 또는 사용자 정의 플러그인에서 아래 코드를 변형 할 수 있습니다.

이 코드에는 2 개의 개별 파트가 있습니다.이 코드 중 하나만 사용하면되지만 요구 사항의 복잡성에 따라 달라집니다.

1 부는 단일 사용자를 지정하고 특정 게시물로 제한합니다.

Part 2를 사용하면 사용자 및 게시물 ID의지도를 작성하고 여러 게시물을 작성할 수 있습니다

아래 코드는 페이지 전용이지만 게시물 또는 사용자 정의 게시물 유형으로 변경하려면 문자열을 $screen->id == 'page'다른 것으로 변경해야합니다 .

여기 에서 wp-admin 주위의 화면 ID에 대한 참조를 찾을 수 있습니다.

function my_pre_get_posts( $query ){

    $screen = get_current_screen();
    $current_user = wp_get_current_user();

    /**
     * Specify a single user and restrict to a single page
     */
    $restricted_user_id = 10; //User ID of the restricted user
    $allowed_post_id = 1234; //Post ID of the allowed post

    $current_post_id = isset( $_GET['post'] ) ? (int)$_GET['post'] : false ;

    //Only affecting a specific user
    if( $current_user->ID !== $restricted_user_id ){
        return;
    }

    //Only Affecting EDIT page.
    if( ! $current_post_id ){
        return;
    }

    if( $screen->id == 'page' && $current_post_id !== $allowed_post_id ){
        wp_redirect( admin_url( ) );
        exit;
    }

    /**
     * Specify a map of user_id => $allowed_posts
     */
    $restrictions_map = [
        10 => [ 123 ], //Allow user ID to edit Page ID 123
        11 => [ 152, 186 ] //Allow user ID to edit Page ID 123 and 186
    ];

    if( array_key_exists( $current_user->ID, $restrictions_map ) ){

        $allowed_posts = $restrictions_map[$current_user->ID];

        if( $screen->id == 'page' && ! in_array( $current_user->ID, $allowed_posts ) ){
            wp_redirect( admin_url( ) );
            exit;
        }

    }

}
add_action( 'pre_get_posts', 'my_pre_get_posts' );

1
하나는 핵심 기능을 수행하는 일을 할 수 있지만 여전히 페이지 출력되는 경우에도 사용자에게 편집에 대한 링크를 떠날 때 그 수 나쁜 UI하게하지 편집 그들
마크 Kaplun

-4

User Role Editor몇 번 사용 했는데 꽤 좋습니다. 어쩌면 당신을 도울 수도 있습니다. 사용자 역할 편집기 링크는 다음과 같습니다.


견고한 플러그인 인 것 같지만 특정 페이지를 편집하도록 사용자를 제한하는 방법을 찾을 수 없습니다.
naf

이 방법으로 제한하려는 사용자에게 작성자 수준 사용자 만들기 "edit_pages"기능을 작성자 사용자 수준에 추가 (사용자 역할 편집기 사용) 페이지의 작성자를 편집 권한을 부여 할 사용자에게 설정하십시오. edit_pages 기능이있는 작성자 레벨 사용자는 대시 보드에서 페이지 목록을 볼 수 있지만 작성자 인 페이지를 제외하고 편집 할 수있는 옵션이 없습니다.
user2319361

4
고마워, 그것은 어느 정도 작동합니다. 특정 시점에서 여러 사용자가 특정 페이지를 수정하도록 제한해야 할 수도 있으므로 여러 작성자를 한 페이지로 설정하는 방법이 필요합니다.
naf

사용자를 특정 페이지로 제한하려면 Pro versoin을 구매해야합니다. 나는 똑같은 것을 찾고 그것을 발견했다. wordpress.stackexchange.com/questions/191658/…
Ricardo Andres

1
특정 플러그인은 현재 확실한 기능이지만 플러그인이 제공하는 모든 옵션을 사용하는 것보다 코드를 작성하는 것이 더 쉽습니다. (OP가 요구하는 것을 할 수 있다면)
Mark Kaplun
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.