ซ่อนโพสต์ของผู้ใช้คนอื่นในแผงผู้ดูแลระบบ


10

ฉันตั้งใจจะใช้เว็บไซต์ผู้เขียนหลายคนฉันไม่ต้องการให้โพสต์จากผู้เขียนรายอื่นปรากฏใน/wp-admin/edit.phpหน้าเว็บ

ฉันจัดการแก้ปัญหานี้ด้วยรหัสจากกระทู้นี้ รหัสเป็นดังนี้:

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

รหัสใช้งานได้ดีมันซ่อนโพสต์จากผู้เขียนคนอื่น ๆ ที่จะแสดงที่นี่ แต่ฉันจะพบปัญหาอื่น - เมนูที่ด้านบนของหน้าไม่เปลี่ยนจำนวนโพสต์ที่เกี่ยวข้องโดยผู้เขียนมันแสดงจำนวนโพสต์ทั้งหมดในเว็บไซต์ของฉัน

เมนูที่ฉันหมายถึงเป็นแบบนี้:

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

วิธีการเปลี่ยนหมายเลขใน()เพื่อให้สะท้อนถึงตัวเลขที่เกี่ยวข้องกับผู้แต่งเท่านั้น?


ฉันแค่คิดออกมาดัง ๆ เพราะฉัน / กำลังพิจารณาที่จะทำสิ่งเดียวกัน เว็บไซต์ของฉันเป็นเว็บไซต์เบสบอลที่มีผู้เขียนประมาณ 10 คน ฉันจะย้อนกลับไปเรื่อย ๆ ว่าจะซ่อนร่างผู้เขียนคนอื่นจากผู้เขียนที่ลงชื่อเข้าใช้ในปัจจุบันหรือไม่ ด้านหนึ่งฉันคิดว่าพวกเขาไม่จำเป็นต้องรู้บทความของผู้เขียนคนอื่นจนกว่าพวกเขาจะเผยแพร่ อีกด้านหนึ่งฉันไม่ต้องการให้ผู้เขียน 2 คนตีพิมพ์บทความที่เหมือนกันเกือบ 2 ฉบับในเวลาเดียวกัน
เทรวิส Pflanz

ในที่สุดฉันก็พบวิธีแก้ปัญหาสำหรับปัญหาของฉัน ... wordpress.org/support/topic/ ... สิ่งนี้สามารถช่วยได้
dev-jim

คำตอบ:


11

นี่คือสิ่งที่ฉันใช้:

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

แหล่ง


1
ฉันถามคำถามสองข้อนี้ในฐานะมือใหม่ WordPress: (1) ทำไมไม่ใช้อาร์เรย์มากขึ้นและน้อยลงelseif? (2) และทำไมต้องใช้การแปลโดย__()รวมhrefแทนที่จะAllเป็นตัวอย่าง?
cregox

3

วิธีการแก้ปัญหาที่สั้นขึ้นอยู่กับคำตอบhttps://wordpress.stackexchange.com/a/49200/83038

หมายเหตุ: มีให้ตั้งแต่ WordPress 3.7.0

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

วิธีที่ดีที่สุด

คำตอบทั้งหมดที่นี่มีความกังวล

วิธีที่ดีที่สุดคือการเพิ่มความสามารถที่กำหนดเองและจัดการโพสต์ ฯลฯ ตามความสามารถ


วิธีง่ายๆ

โซลูชันของ Artem น่าจะดีกว่าเพราะ WP ไม่ได้อ้างถึงจำนวนการโพสต์เฉพาะในหน้าจอแก้ไขโพสต์ แต่ยังอยู่ในวิดเจ็ตแดชบอร์ดการตอบสนองอาแจ็กซ์ ฯลฯ

เพื่อการแก้ปัญหาที่ดีขึ้นโดยอ้างอิงจาก Artem

  1. ล้างโพสต์เริ่มต้นนับแคช
    ทำไม: wp_count_postsก่อนหน้านี้ส่งคืนโพสต์ที่แคชไว้นับเมื่อผลลัพธ์ถูกแคชไว้ก่อนหน้า
  2. แคชผลลัพธ์ของการนับโพสต์ที่กำหนดเอง
    ทำไม: แคชเพิ่มประสิทธิภาพ
  3. เคารพ$permพารามิเตอร์ที่ 3 ของwp_count_postsเบ็ด
    ทำไม: การนับโพสต์ควรมีการโพสต์ส่วนตัวของผู้ใช้ตามใบreadableอนุญาต
  4. ใช้ตัวกรองเป็นตัวกรองลำดับความสำคัญสูง
    ทำไม: ตัวกรองอาจถูกแทนที่โดยตัวกรองอื่น ๆ
  5. ลบ (หรือแก้ไข) จำนวนโพสต์เหนียว
    เหตุผล: โพสเหนียวนับรวมถึงการโพสต์อื่น ๆ WP_Posts_List_Tableและพวกเขาจะนับและแยกจาก
  6. ใช้ความสามารถที่เหมาะสมสำหรับ Custom Post Type
    ทำไม: read_others_postsสามารถปรับเปลี่ยนความสามารถได้

คุณอาจต้องการปรับแต่งเพิ่มเติม

  • ความคิดเห็นกรองคนอื่นโพสต์โดยการตั้งค่าpost_authorvar WP_Comment_Queryแบบสอบถามไปยัง
  • ความคิดเห็น tweaks นับโดยwp_count_commentsเบ็ด
  • ป้องกันการเข้าถึงหน้าจอผู้ดูแลระบบที่ควรถูก จำกัด

ต่อไปนี้เป็นเวอร์ชั่นที่แก้ไขตามwp_post_counts()WP 4.8

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)

ปัญหาที่ทราบ: การนับโพสต์เหนียวที่ไม่ได้เป็นของผู้ใช้จะถูกนับ แก้ไขโดยการลบมุมมองโพสต์เหนียว


ขอบคุณนี่เหมาะสำหรับสิ่งที่ฉันใช้และกำลังทำอยู่ เพิ่งเปลี่ยน 'โพสต์' ทั้งหมดเป็นชื่อความสามารถที่กำหนดเองของฉัน
Shawn Rebelo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.