ti-enxame.com

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

Eu quero 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 possam ver apenas as imagens eles enviados?

Aqui está a minha solução para o momento ... Eu estou fazendo uma consulta simplesWP, em seguida, 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);
45
TerryMatula

Você sempre pode filtrar a lista de mídia usando um filtro pre_get_posts que primeiro determina a página e os recursos do usuário e define o parâmetro de 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;
}

Usei o limite de páginas de exclusão como uma condição para que os administradores e editores ainda visualizem a listagem completa de mídia.

Há um pequeno efeito colateral, que 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 do usuário fornecido - eu considere isso uma questão menor embora).

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

37
t31os

A partir de 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;
}
30
David

Aqui está uma solução completa para posts e mídia (este 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;
}
19
Paul

Esta é uma versão modificada de a 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ídia 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 inserido para legibilidade aqui)

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

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

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

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

5
Sparky

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

Eu descobri uma maneira de evitar que a contagem de números aparecesse usando 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!

2
user15182

Código de trabalho completo .. Só problema é, recebendo contagem errada de imagens na biblioteca de mídia na página Adicionar Post.

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
Nitin

Uma maneira de fazer isso é usar o plugin Role Scoper , é ótimo para gerenciar funções e capacidades muito específicas 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.

1
Rick Curran

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

1) Eu instalei o plugin 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, exibi 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);

Um par de 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 conectar-se à página Mídia sem entrar nos arquivos principais, agradeço. Obrigado!

1
TerryMatula
<?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, faça upload como plugin para seu WP e ative-o, isso é tudo.

1
Philip Borisov