Kullanıcının yalnızca belirli sayfaları düzenlemesine izin verme


16

Belirli bir kullanıcının yalnızca bir sayfayı ve alt sayfaları düzenlemesine izin vermek istiyorum. Bu nasıl mümkün olabilir? Eski Rol Scoper'ı denedim, ancak birçok sorun ve hata var gibi görünüyor.


2
Eklenti önerisi talebinizi konu dışı bıraktığım için kaldırdım. Evet, bu bir eklenti ile mümkün olmalı, ancak bu tür temel işlevselliği hacklemeyi gerektiren şeyleri yapmaya çalıştığımda yardımcı olamıyorum ama yanlış yaklaşımı kullandığınızı düşünüyorum. Projeyi daha ayrıntılı açıklayabilir misiniz?
s_ha_dum

Yanıtlar:


14

Böyle bir görevi uygulamak için yapılacak ilk şey, kullanıcının hangi sayfayı düzenleyebileceğini tanımaktır.

Bunu yapmanın farklı yolları var. Bir kullanıcı meta, bazı yapılandırma değeri olabilir ... Bu cevap uğruna, bunun bir fonksiyon lile olduğunu varsayacağım:

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

}

Artık bir kullanıcının bir sayfayı düzenleyip düzenleyemeyeceğini belirlemenin bir yolu var, WordPress'e, bir sayfayı düzenlemek için kullanıcı yeteneğini kontrol etmek için bu işlevi kullanmasını söylememiz gerekiyor.

Bu 'map_meta_cap'filtre ile yapılabilir .

Gibi bir şey:

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 );

Bu noktada, bir kullanıcıyı bir veya daha fazla sayfaya bağlamak için sadece bir yola ihtiyacımız var .

Kullanım durumuna bağlı olarak farklı çözümler olabilir.

Esnek bir çözüm, wp_dropdown_pageskullanıcı yönetici ekranına "kök" sayfaların (bkz. ) Açılır listesini eklemek ve seçilen sayfaları kullanıcı meta olarak kaydetmek olabilir.

'edit_user_profile'Sayfalar açılır alanını eklemek ve 'edit_user_profile_update'seçilen değeri kullanıcı metası olarak depolamak için kaldırabiliriz .

Bu web sitesinde bunun nasıl yapılacağı konusunda ayrıntılı rehberlik olduğundan eminim.

Sayfalar kullanıcı meta olarak depolandığında wpse_user_can_edit(), sayfa kimliğinin kullanıcı meta değerinin bir parçası olup olmadığını kontrol ederek yukarıdaki işlev tamamlanabilir.

Sayfayı düzenleme yeteneğini kaldırarak, WordPress gerisini halleder: arka uçtan ve ön uçtan herhangi bir düzenleme bağlantısını kaldıracak, doğrudan erişimi engelleyecektir ... vb.


3
Bu benim cevabımdan çok daha iyi. Kullanıcının kapasitesini değiştirip WordPress'in gerisini halletmesine izin verdiğinizde neden düzenleme bağlantılarını sınırlandırıyorsunuz?
ricotheque

uzun bir "u" ünsüz ile başlayan "yu" gibi ses çıkardığı için, "kullanıcı" sözcüğünden önce "a" kullanmamalısınız.
Philip

7

Genel değişkenlerden kaçınmak için bir PHP sınıfı kullansanız bile, bu özelliği uygulamak için az miktarda kod gerekir. Ayrıca, Gösterge Tablosu'nda kullanıcı için yasaklanmış sayfaları gizlemek istemedim. Sitede bulunan içeriği eklediyseler ne olurdu?

$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;
    }
}

Yukarıdaki kodun yaptığı, aşağıdakilerin gerektiği gibi çalışmasını veya görünmesini önlemektir:

  1. get_edit_post_link
  2. Edit Page için görünen WP Yönetici Çubuğundaki bağlantı
  3. Edit, Quick Editve Trashiçindeki Sayfaların altında görünen hızlı bağlantılar/wp-admin/edit.php?post_type=page

Bu, yerel WordPress 4.7 kurulumumda çalıştı. Sitedeki sayfaların sık sık değişmeyeceğini varsayarsak, sayfanın kimliklerini ve alt sayfalarını sabit olarak kodlamak WP_Queryve __constructyöntemin içini kaldırmak daha iyi olabilir . Bu veritabanı aramalarında çok tasarruf sağlayacaktır.


@ Ben'den daha eksiksiz cevap için +1 ancak bağlantıları ele almanın doğru yolu yetenekleri manipüle etmektir,
Mark Kaplun

Evet, gmazzap'ın cevabını görünce "Şimdi neden böyle düşünmedim?" Diye düşündüm.
ricotheque

5

Eklentilerden uzak durmak istiyorsanız, function.php dosyasında veya özel bir eklentide aşağıdaki kodun bir varyasyonunu kullanabilirsiniz.

Bu kod için 2 ayrı parça vardır, sadece 1 tanesini kullanmanız gerekir, ancak hangisinin gereksinimlerin karmaşıklığına bağlı olduğu.

Bölüm 1, tek bir kullanıcıyı belirtir ve belirli bir gönderiyle sınırlandırır.

Bölüm 2, kullanıcıların ve posta kimliklerinin bir haritasını oluşturmanıza izin verir ve birden fazla gönderiye izin verir

Aşağıdaki kod yalnızca bir sayfa içindir, ancak bunu bir gönderiye veya özel bir gönderi türüne değiştirmek istiyorsanız, dizeyi $screen->id == 'page'başka bir şeye değiştirmeniz gerekir .

Burada wp-admin etrafındaki ekran kimlikleriyle ilgili bir referans bulabilirsiniz.

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
Temel işlevselliği yapmak için çalışabildiği için +1, ancak bu yine de, sayfaları düzenleyemeyen kullanıcılara bile çıktıları düzenlemek için bağlantılar bırakıyor, bu da kötü bir kullanıcı arayüzü yapıyor
Mark Kaplun 19:17

-4

Kullandığım User Role Editorbirkaç kez ve oldukça iyidir. Belki de size yardımcı olabilir. İşte Kullanıcı Rol Editörü bağlantısı


Sağlam bir eklenti gibi görünüyor, ancak bir kullanıcının belirli sayfaları düzenlemesini kısıtlamanın bir yolunu bulamıyorum.
naf

Bu şekilde sınırlamak istediğiniz kullanıcıları yazar düzeyinde kullanıcılar yapın "edit_pages" özelliğini yazar kullanıcı düzeyine ekleyin (Kullanıcı Rolü Düzenleyicisi'ni kullanarak) Bir sayfanın yazarını, düzenleme ayrıcalığı vermek istediğiniz kullanıcıya ayarlayın. Edit_pages özelliği verilen yazar düzeyindeki bir kullanıcı, kontrol panelindeki sayfaların listesini görebilir, ancak yazar oldukları sayfalar dışında düzenleme seçeneğine sahip değildir.
user2319361

4
Teşekkürler, bu bir ölçüde işe yarıyor. Bir noktada, belirli bir sayfayı değiştirmek için birden fazla kullanıcının kısıtlanması gerekebilir, bu nedenle bir sayfaya birden fazla yazar ayarlamanın bir yolu olması gerekir.
naf

Kullanıcıları belirli sayfalarla sınırlandırmak için Pro versoin'i satın almanız gerekir. Aynı şeyi arıyorum ve bunu öğrendim. wordpress.stackexchange.com/questions/191658/…
Ricardo Andres

1
Bu eklenti şu anda sağlam bir şey olsa da, bunu yapmak için kod yazmak muhtemelen eklentinin sunduğu tüm seçeneklerde wade'den daha kolaydır. (OP'nin istediklerini yapmanıza izin veriyorsa)
Mark Kaplun
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.