it-swarm-es.com

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

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 ellos subidas?

Aquí está mi solución por el momento ... Estoy haciendo una simple WP consulta, 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);
45
TerryMatula

Siempre se 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 eliminación de 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 gancho, y eso es con los recuentos de adjuntos que se muestran arriba de la lista de medios (que aún mostrarán el recuento total de elementos de medios, no el del usuario dado. considera esto como un problema menor sin embargo).

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

37
t31os

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

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 hackear 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;
}
19
Paul

Esta es una versión modificada de la respuesta aceptada . Dado que la respuesta aceptada solo se dirige al elemento de 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 dentro de 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 este ...

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

(saltos de línea y espacio sólo 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' ) ) )

(saltos de línea y espacio sólo 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.

5
Sparky

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

2
user15182

Complete el código de trabajo. El único problema es obtener una cantidad incorrecta 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' );
2
Nitin

Una forma de hacerlo es usar el complemento Role Scoper , que es excelente para administrar funciones y capacidades muy específicas 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.

1
Rick Curran

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

1) Instalé el WP Ocultar el complemento de 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 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, así 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);

Un par de problemas, sin embargo. 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 aún no es ó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!

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

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

1
Philip Borisov