在管理面板中隐藏其他用户的帖子

时间:2012-04-16 作者:dev-jim

我打算运行一个多作者网站,我不希望其他作者的帖子显示在/wp-admin/edit.php

我设法通过以下代码解决了这个问题this thread. 代码如下:

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 ()
如何更改() 要反映仅与作者关联的数字?

3 个回复
SO网友:Bainternet

以下是我使用的:

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

Source

SO网友:Whizark

The Best Way

ALL THESE ANSWERS HERE HAVE SECURITY CONCERNS.

最好的方法是通过这些功能添加自定义功能和管理帖子等。

<小时>

An easy way

Artem的解决方案似乎更好,因为WP不仅在post edit屏幕上引用帖子计数,而且在Dashboard小部件、Ajax响应等中也引用帖子计数。

在Artem的基础上寻求更好的解决方案。

  1. clear the default post counts cache.
    原因:wp_count_posts 当结果之前已缓存时,earlierly返回缓存的post计数
  2. cache the result of custom post counts.<原因:缓存提高了性能
  3. respect the 3rd $perm parameter of wp_count_posts hook.
    原因:帖子数量应包括用户自己的私人帖子,基于readable 烫发
  4. apply filters as high priority filters.
    原因:这些筛选器可能会被其他筛选器覆盖
  5. remove (or modify) sticky posts count.<为什么:粘滞帖子数包括其他人的帖子,它们分别按WP_Posts_List_Table.
  6. use proper capability for Custom Post Type
    原因:read_others_posts 可以修改功能
You might want to additional tweaks

通过设置筛选其他帖子的评论post_author 查询var到WP_Comment_Query.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( $current_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)

Known Issue: 统计不属于用户的粘性帖子通过删除粘滞帖子视图修复。

SO网友:Artem Frolov

基于答案的简短解决方案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 );

结束

相关推荐

使用phpMyAdmin移动数据库

我有一个wordpress网站的远程(网站)版本,它比我的本地(计算机)版本获得了更多的最新信息。我想使用phpMyAdmin将数据移动到本地,最好的方法是什么?我应该只导出整个数据库,导入它并将我的wordpress站点重新链接到配置文件中的“新”(更新)数据库吗?