Ocultar as postagens de outros usuários no painel de administração

9

Eu pretendia criar um site com vários autores, não quero que as postagens de outros autores sejam exibidas em /wp-admin/edit.php page.

Eu consegui resolver esse problema com os códigos de esta discussão . O código é assim:

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

Os códigos funcionam muito bem, escondem as postagens de outros autores para serem mostradas aqui. Mas eu acho outro problema - o menu no topo da página não altera o número associado de posts do autor, ele mostra o número de todos os posts no meu site.

O menu que quero dizer é assim:

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

Como alterar o número no () para refletir o número associado apenas ao autor?

    
por dev-jim 16.04.2012 / 12:00

3 respostas

11

Aqui está o que eu uso:

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

Fonte

    
por Bainternet 16.04.2012 / 19:48
3

Uma solução mais curta baseada na resposta enlace .

NOTA: Disponível desde o 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 );
    
por Artem Frolov 05.11.2015 / 10:03
2

A melhor maneira

TODAS ESTAS RESPOSTAS AQUI TÊM PREOCUPAÇÕES DE SEGURANÇA.

A melhor maneira é adicionar recursos personalizados e gerenciar postagens etc. pelos recursos.

Uma maneira fácil

A solução da Artem parece ser melhor porque o WP não se refere à contagem de postagens apenas na tela de pós-edição, mas também no widget do Dashboard, na resposta do Ajax, etc.

Para uma melhor solução baseada na de Artem.

  1. limpa o cache padrão de contagens de postagens.
    porque: wp_count_posts anteriormente retorna as contagens de post em cache quando o resultado foi armazenado em cache antes.
  2. armazena em cache o resultado das contagens de postagens personalizadas.
    porque: cache aumenta o desempenho.
  3. respeite o parâmetro 3rd $perm do wp_count_posts hook.
    por que: as contagens de postagens devem incluir postagens particulares do usuário com base em readable perm.
  4. aplica filtros como filtros de alta prioridade.
    por que: os filtros podem ser substituídos por outros filtros.
  5. remova (ou modifique) a contagem de postagens.
    por que: a contagem de postagens fixas inclui as postagens de outras pessoas e elas são contadas separadamente por WP_Posts_List_Table .
  6. use recursos adequados para o tipo de postagem personalizada
    porque: read_others_posts capacidade pode ser modificada.

Você pode querer ajustes adicionais

  • filtrar os comentários de outras postagens definindo post_author query var como WP_Comment_Query .
  • tweaks comentários contam por wp_count_comments hook.
  • impede o acesso a telas de administrador que devem ser restritas.

A seguir, uma versão modificada com base em wp_post_counts() do 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)

Problema conhecido: as postagens fixas que não pertencem ao usuário são contadas. corrigidas removendo a visualização de postagens fixas.

    
por Whizark 26.07.2017 / 21:39