¿Restringir a los usuarios para ver solo los elementos de la biblioteca de medios que han cargado?

45

Quiero que los usuarios puedan cargar fotos usando add_cap('upload_files') pero en su página de perfil, la Biblioteca de medios muestra cada imagen que se ha cargado. ¿Cómo puedo filtrar eso para que solo puedan ver las imágenes que subieron?

Aquí está mi solución por el momento ... Estoy haciendo una consulta WP simple, luego un bucle en la página "Perfil" del usuario

$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);
    
pregunta TerryMatula 07.09.2010 - 19:51

9 respuestas

36

Siempre puede filtrar la lista de medios utilizando un filtro pre_get_posts que primero determina la página y las capacidades del usuario, y establece el parámetro de autor cuando se cumplen ciertas condiciones ...

Ejemplo

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

Utilicé el límite de eliminar páginas como condición para que los administradores y editores sigan viendo la lista completa de medios.

Hay un pequeño efecto secundario, para el cual no puedo ver ningún enganche, y eso es con los conteos de adjuntos que se muestran arriba de la lista de medios (que aún mostrarán el conteo total de elementos de medios, no el del usuario dado: Sin embargo, consideraría esto como un problema menor).

Pensé que lo publicaría de todos modos, podría ser útil ...;)

    
respondido por el t31os 20.11.2010 - 14:11
30

A partir del WP 3.7, hay una forma mucho mejor a través del filtro ajax_query_attachments_args , como se indica en documentación :

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;
}
    
respondido por el David 21.02.2015 - 01:46
19

Aquí hay una solución completa para publicaciones y medios (este código es específicamente para autores, pero puede cambiarlo para cualquier rol de usuario). Esto también corrige el conteo de publicaciones / medios sin piratear los archivos principales.

// 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;
}
    
respondido por el Paul 27.11.2011 - 21:00
4

Esta es una versión modificada de la respuesta aceptada . Dado que la respuesta aceptada solo se dirige al elemento del menú de Medios a la izquierda, los usuarios aún pueden ver toda la biblioteca de medios dentro del cuadro modal al cargar una foto en una publicación. Este código ligeramente modificado corrige esa situación. Los usuarios seleccionados solo verán sus propios elementos multimedia en la pestaña Biblioteca de medios del cuadro modal que aparece en una publicación.

Este es el código de la respuesta aceptada con un comentario que marca la línea 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 los usuarios solo puedan ver sus propios medios desde el menú Medios Y la pestaña Biblioteca de medios del modo de carga, reemplace la línea indicada con esta ...

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

( los saltos de línea y el espaciado solo se insertan para facilitar la lectura aquí )

Lo siguiente es lo mismo que arriba pero también les restringe a ver sus propias publicaciones desde el elemento del menú Publicaciones.

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

( los saltos de línea y el espaciado solo se insertan para facilitar la lectura aquí )

Notas : como en la respuesta aceptada, las publicaciones y los contadores de medios estarán equivocados. Sin embargo, hay soluciones para esto en algunas otras respuestas en esta página. No los incorporé simplemente porque no los había probado.

    
respondido por el Sparky 03.02.2014 - 23:03
2

Código de trabajo completo. El único problema es que el recuento incorrecto de imágenes en la biblioteca de medios en la página Agregar publicación.

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' );
    
respondido por el Nitin 26.11.2011 - 19:46
2

t31os tiene una gran solución allí. Lo único es que el número de todas las publicaciones sigue apareciendo.

Descubrí una manera de evitar que el número de números se mostrara usando jQuery.

Solo agrega esto a tu archivo de función.

    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 mí!

    
respondido por el user15182 14.04.2012 - 00:18
1

Resolví mi problema con una solución bastante aproximada pero viable.

1) Instalé el complemento WP Hide Dashboard, por lo que el usuario solo vería un enlace a su formulario de edición de perfil.

2) En el archivo de plantilla author.php, inserté el código que usé anteriormente.

3) Luego, para los usuarios registrados, mostré un enlace directo a la página de carga "wp-admin / media-new.php"

4) El siguiente problema que noté, fue después de que subieron la foto, los redirigiría a upload.php ... y podrían ver todas las demás imágenes. No he encontrado un gancho en la página media-new.php, por lo que terminé hackeando el núcleo "media-upload.php" y redirigiéndolos a su página de perfil:

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

Luego reemplazó wp_redirect( admin_url($location) ); con wp_redirect($userredirect);

Sin embargo, un par de problemas. Primero, el usuario que ha iniciado sesión todavía puede ir a "upload.php", si saben que existe. No pueden hacer nada excepto MIRAR los archivos, y el 99% de las personas ni siquiera lo sabrán, pero todavía no es lo óptimo. En segundo lugar, también redirige al administrador a la página de perfil después de cargar. Estos pueden tener una solución bastante simple al verificar los roles de los usuarios y solo redirigir a los suscriptores.

Si alguien tiene ideas sobre cómo conectarse a la página de Medios sin entrar en los archivos principales, lo apreciaría. Gracias!

    
respondido por el TerryMatula 10.09.2010 - 16:56
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' );
?>

Guarde el código de arriba como manage_your_media_only.php, ciérrelo, cárguelo como complemento a su WP y actívelo, eso es todo.

    
respondido por el Philip Borisov 08.12.2010 - 12:29
1

Una forma de hacer esto es usar el plugin Role Scoper , es genial para administrar roles muy específicos y capacidades también. En realidad, puede bloquear el acceso a las imágenes en la Biblioteca de medios solo para las que cargue cada usuario. Lo he estado usando para un proyecto en el que estoy trabajando en este momento y funciona bien.

    
respondido por el Rick Curran 11.01.2011 - 12:01

Lea otras preguntas en las etiquetas