Yönetici panelinde diğer kullanıcıların yayınlarını gizle


10

Çok yazarlı bir site çalıştırmayı amaçladım, diğer yazarlardan gelen gönderilerin /wp-admin/edit.phpsayfada gösterilmesini istemiyorum .

Ben bu iş parçacığı kodları ile bu sorunu çözmek başardı . Kod şöyle:

function posts_for_current_author($query) {
    global $pagenow;

    if( 'edit.php' != $pagenow || !$query->is_admin )
        return $query;

    if( !current_user_can( 'manage_options' ) ) {
        global $user_ID;
        $query->set('author', $user_ID );
    }
    return $query;
}
add_filter('pre_get_posts', 'posts_for_current_author');

Kodlar harika çalışıyor, burada gösterilecek diğer yazarların gönderilerini gizliyor. Ama başka bir sorun buluyorum - sayfanın üst kısmındaki menü yazarın ilişkili yazı sayısını değiştirmez, sitemdeki tüm yazıların sayısını gösterir.

Demek istediğim menü şöyle:

Mine () | All () | Published () | Draft () | Trash ()

()Yalnızca yazarla ilişkilendirilmiş sayıyı yansıtacak şekilde sayı nasıl değiştirilir ?


Sadece yüksek sesle düşünüyorum, çünkü aynı şeyi yapmayı düşünüyorum. Web sitem yaklaşık 10 yazarlı bir beyzbol sitesidir. Şu anda oturum açmış olan yazardan diğer yazarların taslaklarını gizleyip gizlememe konusunda ileri ve geri gidiyorum. Bir tarafı, diğer yazarların makalelerini yayımlayana kadar bilmelerine gerek olmadığını düşünüyorum. Diğer tarafta, 2 yazarın aynı anda neredeyse aynı 2 makaleyi yayınlamasını istemiyorum.
Travis Pflanz

Sonunda benim sorunum için bir çözüm buldum ... wordpress.org/support/topic/… bu yardımcı olabilir
dev-jim

Yanıtlar:


11

İşte ne kullanıyorum:

// Show only posts and media related to logged in author
add_action('pre_get_posts', 'query_set_only_author' );
function query_set_only_author( $wp_query ) {
    global $current_user;
    if( is_admin() && !current_user_can('edit_others_posts') ) {
        $wp_query->set( 'author', $current_user->ID );
        add_filter('views_edit-post', 'fix_post_counts');
        add_filter('views_upload', 'fix_media_counts');
    }
}

// Fix post counts
function fix_post_counts($views) {
    global $current_user, $wp_query;
    unset($views['mine']);
    $types = array(
        array( 'status' =>  NULL ),
        array( 'status' => 'publish' ),
        array( 'status' => 'draft' ),
        array( 'status' => 'pending' ),
        array( 'status' => 'trash' )
    );
    foreach( $types as $type ) {
        $query = array(
            'author'      => $current_user->ID,
            'post_type'   => 'post',
            'post_status' => $type['status']
        );
        $result = new WP_Query($query);
        if( $type['status'] == NULL ):
            $class = ($wp_query->query_vars['post_status'] == NULL) ? ' class="current"' : '';
            $views['all'] = sprintf(__('<a href="%s"'. $class .'>All <span class="count">(%d)</span></a>', 'all'),
                admin_url('edit.php?post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'publish' ):
            $class = ($wp_query->query_vars['post_status'] == 'publish') ? ' class="current"' : '';
            $views['publish'] = sprintf(__('<a href="%s"'. $class .'>Published <span class="count">(%d)</span></a>', 'publish'),
                admin_url('edit.php?post_status=publish&post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'draft' ):
            $class = ($wp_query->query_vars['post_status'] == 'draft') ? ' class="current"' : '';
            $views['draft'] = sprintf(__('<a href="%s"'. $class .'>Draft'. ((sizeof($result->posts) > 1) ? "s" : "") .' <span class="count">(%d)</span></a>', 'draft'),
                admin_url('edit.php?post_status=draft&post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'pending' ):
            $class = ($wp_query->query_vars['post_status'] == 'pending') ? ' class="current"' : '';
            $views['pending'] = sprintf(__('<a href="%s"'. $class .'>Pending <span class="count">(%d)</span></a>', 'pending'),
                admin_url('edit.php?post_status=pending&post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'trash' ):
            $class = ($wp_query->query_vars['post_status'] == 'trash') ? ' class="current"' : '';
            $views['trash'] = sprintf(__('<a href="%s"'. $class .'>Trash <span class="count">(%d)</span></a>', 'trash'),
                admin_url('edit.php?post_status=trash&post_type=post'),
                $result->found_posts);
        endif;
    }
    return $views;
}

// Fix media counts
function fix_media_counts($views) {
    global $wpdb, $current_user, $post_mime_types, $avail_post_mime_types;
    $views = array();
    $count = $wpdb->get_results( "
        SELECT post_mime_type, COUNT( * ) AS num_posts 
        FROM $wpdb->posts 
        WHERE post_type = 'attachment' 
        AND post_author = $current_user->ID 
        AND post_status != 'trash' 
        GROUP BY post_mime_type
    ", ARRAY_A );
    foreach( $count as $row )
        $_num_posts[$row['post_mime_type']] = $row['num_posts'];
    $_total_posts = array_sum($_num_posts);
    $detached = isset( $_REQUEST['detached'] ) || isset( $_REQUEST['find_detached'] );
    if ( !isset( $total_orphans ) )
        $total_orphans = $wpdb->get_var("
            SELECT COUNT( * ) 
            FROM $wpdb->posts 
            WHERE post_type = 'attachment' 
            AND post_author = $current_user->ID 
            AND post_status != 'trash' 
            AND post_parent < 1
        ");
    $matches = wp_match_mime_types(array_keys($post_mime_types), array_keys($_num_posts));
    foreach ( $matches as $type => $reals )
        foreach ( $reals as $real )
            $num_posts[$type] = ( isset( $num_posts[$type] ) ) ? $num_posts[$type] + $_num_posts[$real] : $_num_posts[$real];
    $class = ( empty($_GET['post_mime_type']) && !$detached && !isset($_GET['status']) ) ? ' class="current"' : '';
    $views['all'] = "<a href='upload.php'$class>" . sprintf( __('All <span class="count">(%s)</span>', 'uploaded files' ), number_format_i18n( $_total_posts )) . '</a>';
    foreach ( $post_mime_types as $mime_type => $label ) {
        $class = '';
        if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) )
            continue;
        if ( !empty($_GET['post_mime_type']) && wp_match_mime_types($mime_type, $_GET['post_mime_type']) )
            $class = ' class="current"';
        if ( !empty( $num_posts[$mime_type] ) )
            $views[$mime_type] = "<a href='upload.php?post_mime_type=$mime_type'$class>" . sprintf( translate_nooped_plural( $label[2], $num_posts[$mime_type] ), $num_posts[$mime_type] ) . '</a>';
    }
    $views['detached'] = '<a href="upload.php?detached=1"' . ( $detached ? ' class="current"' : '' ) . '>' . sprintf( __( 'Unattached <span class="count">(%s)</span>', 'detached files' ), $total_orphans ) . '</a>';
    return $views;
}

Kaynak


1
Bu iki soruyu wordpress acemi olarak soruyorum: (1) Neden daha fazla dizi ve daha az kullanmıyorsunuz elseif? (2) Ve neden çevirisini kullanarak __()tüm üzerinde hrefyerine sadece üzerinde Allörneğin?
cregox

3

Https://wordpress.stackexchange.com/a/49200/83038 yanıtını temel alan daha kısa çözüm .

Not: WordPress 3.7.0 beri kullanılabilir.

function fix_count_orders( $counts, $type ) {
    global $wpdb;

    $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
    $query .= $wpdb->prepare( " AND post_author = %d", get_current_user_id() );
    $query .= ' GROUP BY post_status';

    $results = (array) $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
    $counts = array_fill_keys( get_post_stati(), 0 );

    foreach ( $results as $row ) {
        $counts[ $row['post_status'] ] = $row['num_posts'];
    }

    return (object) $counts;
}


function query_set_only_author( $wp_query ) {
    global $current_user;

    // Add here post types for which you want to fix counts ('post' added for example).
    $allowed_types = array( 'post' );
    $current_type = get_query_var( 'post_type' ) ? get_query_var( 'post_type' ) : '';

    if( is_admin() && ! current_user_can( 'edit_others_posts' ) && in_array( $current_type, $allowed_types ) ) {
        $wp_query->set( 'author', $current_user->ID );
        add_filter( 'wp_count_posts', 'fix_count_orders' );
    }
}

add_action( 'pre_get_posts', 'query_set_only_author', 10, 2 );

2

En iyi yol

BURADA TÜM BU CEVAPLAR GÜVENLİK KONULARINA SAHİPTİR.

En iyi yol, özel yetenekler eklemek ve gönderileri vb. Yeteneklerle yönetmektir.


Kolay bir yol

Artem'ın çözümü daha iyi görünüyor çünkü WP yalnızca sayı düzenleme ekranında yayın sayılarını değil, aynı zamanda Gösterge Tablosu widget'ında, Ajax yanıtı vb.

Artem'in çözümüne dayanan daha iyi çözüm için.

  1. varsayılan yazı sayısı önbelleğini temizle.
    neden: wp_count_postssonuç daha önce önbelleğe alındığında daha önce önbelleğe alınan yayın sayısını döndürür.
  2. özel yazı sayımlarının sonucunu önbelleğe al.
    neden: önbellek performansı artırır.
  3. Kancanın 3. $permparametresine wp_count_postsuyun.
    Nedeni: Gönderi sayıları, izin verilen kullanıcının kendi özel gönderilerini içermelidir readable.
  4. filtreleri yüksek öncelikli filtreler olarak uygular.
    neden: filtreler diğer filtreler tarafından geçersiz kılınabilir.
  5. yapışkan yazı sayısını kaldırın (veya değiştirin).
    neden: yapışkan yazı sayısı diğer yayınları içerir ve ayrı ayrı sayılır WP_Posts_List_Table.
  6. Özel Gönderi Türü için uygun yeteneği kullanın
    : neden: read_others_postsyetenek değiştirilebilir.

Ek ayarlamalar yapmak isteyebilirsiniz

  • post_authorsorgu var değerini ayarlayarak diğer yayınların yorumlarını filtreleyin WP_Comment_Query.
  • tweak yorumları wp_count_commentskanca ile sayılır .
  • kısıtlanması gereken yönetici ekranlarına erişimi önleyin.

Aşağıdaki wp_post_counts()WP 4.8 tabanlı değiştirilmiş bir sürümüdür .

function clear_cache() {
    // deletes the default cache for normal Post. (1)
    $cache_key = _count_posts_cache_key( 'post' , 'readable' );

    wp_cache_delete( $cache_key, 'counts' );
}

add_action( 'admin_init', 'clear_cache' );    // you might use other hooks.

function fix_count_orders( $counts, $type, $perm ) {
    global $wpdb;

    if ( ! post_type_exists( $type ) ) {
        return new stdClass();
    }

    $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";

    $post_type_object = get_post_type_object( $type );

    // adds condition to respect `$perm`. (3)
    if ( $perm === 'readable' && is_user_logged_in() ) {
        if ( ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
            $query .= $wpdb->prepare(
                " AND (post_status != 'private' OR ( post_author = %d AND post_status = 'private' ))",
                get_current_user_id()
            );
        }
    }

    // limits only author's own posts. (6)
    if ( is_admin() && ! current_user_can ( $post_type_object->cap->edit_others_posts ) ) {
        $query .= $wpdb->prepare( ' AND post_author = %d', get_current_user_id() );
    }

    $query .= ' GROUP BY post_status';

    $results = (array) $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
    $counts  = array_fill_keys( get_post_stati(), 0 );

    foreach ( $results as $row ) {
        $counts[ $row['post_status'] ] = $row['num_posts'];
    }

    $counts    = (object) $counts;
    $cache_key = _count_posts_cache_key( $type, 'readable' );

    // caches the result. (2)
    // although this is not so efficient because the cache is almost always deleted.
    wp_cache_set( $cache_key, $counts, 'counts' );

    return $counts;
}

function query_set_only_author( $wp_query ) {
    if ( ! is_admin() ) {
        return;
    }

    $allowed_types = [ 'post' ];
    $current_type  = get_query_var( 'post_type', 'post' );

    if ( in_array( $current_type, $allowed_types, true ) ) {
        $post_type_object = get_post_type_object( $type );

        if (! current_user_can( $post_type_object->cap->edit_others_posts ) ) {    // (6)
            $wp_query->set( 'author', get_current_user_id() );

            add_filter( 'wp_count_posts', 'fix_count_orders', PHP_INT_MAX, 3 );    // (4)
        }
    }
}

add_action( 'pre_get_posts', 'query_set_only_author', PHP_INT_MAX );    // (4)

function fix_views( $views ) {
    // For normal Post.
    // USE PROPER CAPABILITY IF YOU WANT TO RISTRICT THE READABILITY FOR CUSTOM POST TYPE (6).
    if ( current_user_can( 'edit_others_posts' ) ) {
        return;
    }

    unset( $views[ 'sticky' ] );

    return $views;
}

add_filter( 'views_edit-post', 'fix_views', PHP_INT_MAX );     // (5)

Bilinen Sorun: Kullanıcıya ait olmayan yapışkan yayınlar sayılır. yapışkan yazılar görünümü kaldırılarak düzeltildi.


Teşekkürler, kullandığım ve yaptığım şeyler için mükemmeldi. Tüm "yayınları" özel yetenek adımla değiştirdim.
Shawn Rebelo
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.