Restringir usuários a ver somente os itens da biblioteca de mídia que eles carregaram?

45

Eu quero que os usuários possam enviar fotos usando add_cap('upload_files') , mas em sua página de perfil, a Biblioteca de mídia mostra todas as imagens que foram enviadas. Como posso filtrar isso para que eles possam ver apenas as imagens que eles enviaram?

Aqui está a minha solução no momento ... Estou fazendo uma consulta WP simples, depois um loop na página "Perfil" do usuário

$querystr = " SELECT wposts.post_date,wposts.post_content,wposts.post_title, guid 
FROM $wpdb->posts wposts
WHERE wposts.post_author = $author 
AND wposts.post_type = 'attachment' 
ORDER BY wposts.post_date DESC";

$pageposts = $wpdb->get_results($querystr, OBJECT);
    
por TerryMatula 07.09.2010 / 19:51
fonte

9 respostas

36

Você sempre pode filtrar a lista de mídia usando um filtro pre_get_posts que determina primeiro a página e os recursos do usuário e define o parâmetro do autor quando determinadas condições são atendidas.

Exemplo

add_action('pre_get_posts','users_own_attachments');
function users_own_attachments( $wp_query_obj ) {

    global $current_user, $pagenow;

    $is_attachment_request = ($wp_query_obj->get('post_type')=='attachment');

    if( !$is_attachment_request )
        return;

    if( !is_a( $current_user, 'WP_User') )
        return;

    if( !in_array( $pagenow, array( 'upload.php', 'admin-ajax.php' ) ) )
        return;

    if( !current_user_can('delete_pages') )
        $wp_query_obj->set('author', $current_user->ID );

    return;
}

Eu usei o limite de páginas de exclusão como condição para que os administradores e editores continuem vendo a listagem completa de mídia.

Há um pequeno efeito colateral, ao qual não consigo ver nenhum gancho, e isso é com as contagens de anexos mostradas acima da lista de mídia (que ainda mostrará a contagem total de itens de mídia, não a de um determinado usuário - Eu consideraria isso um problema menor embora).

Pensei em colocar tudo do mesmo jeito, pode ser útil ...;)

    
por t31os 20.11.2010 / 14:11
fonte
30

A partir do WP 3.7, existe uma maneira muito melhor através do filtro ajax_query_attachments_args , conforme fornecido na documentação :

add_filter( 'ajax_query_attachments_args', 'show_current_user_attachments' );

function show_current_user_attachments( $query ) {
    $user_id = get_current_user_id();
    if ( $user_id ) {
        $query['author'] = $user_id;
    }
    return $query;
}
    
por David 21.02.2015 / 01:46
fonte
19

Aqui está uma solução completa para posts e mídia (esse código é especificamente para autores, mas você pode alterá-lo para qualquer função de usuário). Isso também corrige a contagem de postagem / mídia sem invadir os arquivos principais.

// 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="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('All')
        );
        elseif( $type['status'] == 'publish' ):
            $class = ($wp_query->query_vars['post_status'] == 'publish') ? ' class="current"' : '';
            $views['publish'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Publish')
        );
        elseif( $type['status'] == 'draft' ):
            $class = ($wp_query->query_vars['post_status'] == 'draft') ? ' class="current"' : '';
            $views['draft'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Draft')
        );
        elseif( $type['status'] == 'pending' ):
            $class = ($wp_query->query_vars['post_status'] == 'pending') ? ' class="current"' : '';
            $views['pending'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Pending')
        );
        elseif( $type['status'] == 'trash' ):
            $class = ($wp_query->query_vars['post_status'] == 'trash') ? ' class="current"' : '';
            $views['trash'] = sprintf(
            '<a href="%1$s"%2$s>%4$s <span class="count">(%3$d)</span></a>',
            admin_url('edit.php?post_type=post'),
            $class,
            $result->found_posts,
            __('Trash')
        );
        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;
}
    
por Paul 27.11.2011 / 21:00
fonte
4

Esta é uma versão modificada da resposta aceita . Como a resposta aceita apenas segmenta o item de menu Mídia à esquerda, os usuários ainda podem ver toda a biblioteca de mídia na caixa modal ao fazer upload de uma foto para uma postagem. Este código ligeiramente modificado corrige essa situação. Os usuários segmentados só verão seus próprios itens de mídia na guia Biblioteca de mídias da caixa modal que aparece em uma postagem.

Este é o código da resposta aceita com um comentário marcando a linha para editar ...

add_action('pre_get_posts','users_own_attachments');
function users_own_attachments( $wp_query_obj ) {

    global $current_user, $pagenow;

    if( !is_a( $current_user, 'WP_User') )
        return;

    if( 'upload.php' != $pagenow ) // <-- let's work on this line
        return;

    if( !current_user_can('delete_pages') )
        $wp_query_obj->set('author', $current_user->id );

    return;
}

Para que os usuários visualizem apenas suas próprias mídias a partir da guia Mídia menu E Biblioteca de mídia do modal de upload, substitua a linha indicada por esta ...

if( (   'upload.php' != $pagenow ) &&
    ( ( 'admin-ajax.php' != $pagenow ) || ( $_REQUEST['action'] != 'query-attachments' ) ) )

( quebra de linha e espaçamento apenas inseridos para legibilidade aqui )

O seguinte é o mesmo que acima, mas também os restringe a ver suas próprias postagens no item de menu "Postagens".

if( (   'edit.php' != $pagenow ) &&
    (   'upload.php' != $pagenow ) &&
    ( ( 'admin-ajax.php' != $pagenow ) || ( $_REQUEST['action'] != 'query-attachments' ) ) )

( quebra de linha e espaçamento apenas inseridos para legibilidade aqui )

Notas : como na resposta aceita, os posts e os contadores de mídia estarão errados. No entanto, existem soluções para isso em algumas outras respostas nesta página. Eu não incorporei aqueles simplesmente porque não os testei.

    
por Sparky 03.02.2014 / 23:03
fonte
2

Conclua o código de trabalho. O único problema é obter a contagem incorreta de imagens na biblioteca de mídia na página Adicionar postagem.

function my_files_only( $wp_query ) {
if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/upload.php' ) !== false ) {
    if ( !current_user_can( 'level_5' ) ) {
        global $current_user;
        $wp_query->set( 'author', $current_user->id );
    }
}
else if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/media-upload.php' ) !== false ) {
    if ( !current_user_can( 'level_5' ) ) {
        global $current_user;
        $wp_query->set( 'author', $current_user->id );
    }
}
}
add_filter('parse_query', 'my_files_only' );
    
por Nitin 26.11.2011 / 19:46
fonte
2

t31os tem uma ótima solução lá em cima. A única coisa é que o número de todas as postagens ainda aparece.

Eu descobri uma maneira de evitar que a contagem de números aparecesse usando o jQuery.

Basta adicionar isso ao seu arquivo de função.

    function jquery_remove_counts()
{
    ?>
    <script type="text/javascript">
    jQuery(function(){
        jQuery("ul.subsubsub").find("span.count").remove();
    });
    </script>
    <?php
}
add_action('admin_head', 'jquery_remove_counts');

Está funcionando para mim!

    
por user15182 14.04.2012 / 00:18
fonte
1

Eu resolvi meu problema com uma solução bastante difícil, mas viável.

1) Instalei o plug-in do WP Hide Dashboard, para que o usuário veja apenas um link para o formulário de edição do perfil.

2) No arquivo de modelo author.php, inseri o código que usei acima.

3) Então, para usuários logados, eu mostrei um link direto para a página Upload "wp-admin / media-new.php"

4) A próxima edição que notei, foi depois que eles fizeram o upload da foto, ela os redirecionaria para upload.php ... e eles poderiam ver todas as outras fotos. Eu não encontrei um gancho para a página media-new.php, então acabei invadindo o núcleo "media-upload.php" e redirecionando-os para sua página de perfil:

    global $current_user;
    get_currentuserinfo();
    $userredirect =  get_bloginfo('home') . "/author/" .$current_user->user_nicename;

Em seguida, substituiu wp_redirect( admin_url($location) ); por wp_redirect($userredirect);

Algumas questões, no entanto. Primeiro, o usuário logado ainda pode ir para "upload.php", se eles souberem que ele existe. Eles não podem fazer nada, exceto verificar os arquivos, e 99% das pessoas nem sabem disso, mas ainda não é o ideal. Em segundo lugar, também redireciona o Admin para a página de perfil após o upload. Eles podem ter uma correção bastante simples, verificando as funções do usuário e redirecionando apenas os Assinantes.

Se alguém tiver idéias sobre como se conectar à página Mídia sem entrar nos arquivos principais, agradeço. Obrigado!

    
por TerryMatula 10.09.2010 / 16:56
fonte
1
<?php
/*
Plugin Name: Manage Your Media Only
Version: 0.1
*/

//Manage Your Media Only
function mymo_parse_query_useronly( $wp_query ) {
    if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/upload.php' ) !== false ) {
        if ( !current_user_can( 'level_5' ) ) {
            global $current_user;
            $wp_query->set( 'author', $current_user->id );
        }
    }
}

add_filter('parse_query', 'mymo_parse_query_useronly' );
?>

Salve o código acima como manage_your_media_only.php, zip-o, faça upload como plug-in para o seu WP e ative-o, isso é tudo.

    
por Philip Borisov 08.12.2010 / 12:29
fonte
1

Uma maneira de fazer isso é usar o plug-in do Scop da função , ele é ótimo para gerenciar funções muito específicas e capacidades também. Você pode, na verdade, bloquear o acesso a imagens na Biblioteca de mídia somente àquelas enviadas por cada usuário. Eu tenho usado para um projeto que estou trabalhando no momento e funciona bem.

    
por Rick Curran 11.01.2011 / 12:01
fonte

Tags