Restringindo os usuários a visualizar apenas os itens da biblioteca de mídia que eles carregaram?


46

Desejo que os usuários possam fazer upload de 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 só podem ver as imagens que eles enviados?

Aqui está 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);

1
Se você encontrou uma resposta para seu próprio problema, é melhor adicioná-la como resposta abaixo, não na pergunta em si. Isso está melhor de acordo com o sistema, e podemos votar novamente em sua resposta, o que melhorará sua reputação neste site.
Jan Fabry


Eu realmente tenho que secundar o plugin 'View Own Posts Media Only', funcionou perfeitamente para mim depois de procurar em todos os lugares uma solução de jquery ou php / html / css.
waffl

Respostas:


37

Você sempre pode filtrar a lista de mídia usando um pre_get_postsfiltro que primeiro determine a página e os recursos do usuário e defina o parâmetro author quando determinadas condições forem 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;
}

Usei o limite de exclusão de páginas como uma condição para que administradores e editores ainda vejam a lista completa de mídias.

Há um pequeno efeito colateral, pelo 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 considere isso uma questão menor).

Pensei em publicá-lo da mesma forma, pode ser útil ..;)


Permiti o upload de arquivos para usuários no nível do assinante. tentou usar seu código, mas não está funcionando.
Sisir

1
"Não está funcionando" não é muito para continuar.
T31os

Eu posso confirmar a mesma observação. Para mim, "não está funcionando" significa que a função de "colaborador" ainda pode ver todos os itens de mídia quando ele faz o upload de um jpg. No entanto, quando ele acessa a biblioteca de mídia no menu, ele está vazio. ( O meu papel "contribuinte" já tem a capacidade extra para fazer upload de arquivos e que está trabalhando. )
Sparky

Portanto, seu código precisa ser ajustado para qualquer página que preencha a guia "Biblioteca de mídia" da janela de upload. Estou pesquisando isso agora.
Sparky

Se bem me lembro (e erros acontecem), não havia ganchos apropriados no momento em que escrevi esta resposta, da mesma forma que não havia ganchos para corrigir a contagem de mídias. No entanto, existem boas 3 novas versões do WordPress desde o momento em que escrevemos, portanto, soluções podem agora ser possíveis.
T31os

32

No WP 3.7, existe uma maneira muito melhor via ajax_query_attachments_argsfiltro, 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;
}

19

Aqui está uma solução completa para postagens 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 post / 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;
}

snippet excelente, mas se nenhum item estiver na biblioteca de mídia, ele gera erros; Aviso: array_sum () espera que o parâmetro 1 seja array, nulo fornecido, e Aviso: array_keys () espera que o parâmetro 1 seja array, nulo fornecido
chrismccoy

Você apenas precisa definir $ _num_posts como uma matriz na função fix_media_counts (). $_num_posts = array();
Paul

4
O código nesta resposta funciona, mas também remove todos os campos personalizados criados pelo plug-in Advanced Custom Fields.
Sparky


5

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 dentro da caixa modal ao carregar uma foto em uma postagem. Esse código ligeiramente modificado corrige essa situação. Os usuários direcionados verão apenas seus próprios itens de mídia na guia Biblioteca de mídia da caixa modal exibida 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 sua própria mídia no menu Mídia E guia 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' ) ) )

( quebras de linha e espaçamento inseridos apenas para facilitar a leitura 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' ) ) )

( quebras de linha e espaçamento inseridos apenas para facilitar a leitura aqui )

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


2

Código de trabalho completo. O único problema é obter uma 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' );

2
Você não deve usar os níveis de usuário, eles ainda estão no WordPress principalmente para compatibilidade com versões anteriores (anteriores ao WP 2.0), não são confiáveis ​​para determinar os recursos do usuário no WordPress moderno (pois provavelmente desaparecerão do núcleo quando a compatibilidade não for mais necessária) ) Use um recurso real para determinar os direitos do usuário.
T31os

Apesar de conter media-upload.php, seu código não está funcionando no modal de upload gerado pela página Pós-edição. Ainda pode ver todos os itens da biblioteca.
Sparky

2

O 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 impedir 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!


1

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

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

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

3) Em seguida, para usuários logados, eu exibi um link direto para a página Upload "wp-admin / media-new.php"

4) O próximo problema que notei foi que depois que eles carregavam a foto, eles os redirecionavam para upload.php ... e eles podiam ver todas as outras fotos. Como não encontrei um gancho na página media-new.php, acabei invadindo o núcleo "media-upload.php" e redirecionando-o para a página de perfil:

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

Em seguida, substituído wp_redirect( admin_url($location) );porwp_redirect($userredirect);

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

Se alguém tiver idéias sobre como conectar-se à página Mídia sem acessar os arquivos principais, eu agradeceria. Obrigado!


2
Há um admin_initgancho que é executado em todas as solicitações de administrador. Caso um usuário solicite upload.php e você queira impedir que você possa bloquear essa solicitação (por exemplo wp_die('Access Denied')) ou redirecionar para algum local válido por gancho.
hakre 11/09/10

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, feche-o, faça o upload como plug-in no seu WP e ative-o, é tudo.


1

Uma maneira de fazer isso é usar o plug-in Role Scoper , que também é ótimo para gerenciar funções e recursos muito específicos. Na verdade, você pode bloquear o acesso às imagens na Biblioteca de mídia apenas para aquelas enviadas por cada usuário. Eu tenho usado para um projeto no qual estou trabalhando no momento e funciona bem.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.