web-dev-qa-db-fra.com

Restreindre les utilisateurs à afficher uniquement les éléments de la bibliothèque multimédia qu'ils ont téléchargés?

Je souhaite que les utilisateurs puissent télécharger des photos à l'aide de add_cap('upload_files'), mais dans leur page de profil, la médiathèque montre toutes les images téléchargées. Comment puis-je filtrer cela pour qu'ils ne puissent voir que les images ils téléchargés?

Voici ma solution pour le moment… Je fais une simple requête WP, puis une boucle sur la page "Profil" de l'utilisateur.

$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

Vous pouvez toujours filtrer la liste de supports à l'aide d'un filtre pre_get_posts qui détermine d'abord la page et les fonctionnalités de l'utilisateur, puis définit le paramètre author lorsque certaines conditions sont remplies.

Exemple

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

J'ai utilisé le capuchon de suppression de pages comme condition pour que les administrateurs et les rédacteurs voient toujours la liste complète des supports.

Il y a un petit effet secondaire, pour lequel je ne vois pas de crochets, et qui correspond au nombre de pièces jointes affiché au-dessus de la liste de médias (qui indiquera toujours le nombre total d'éléments multimédias, et non celui de l'utilisateur donné - je considérez ceci comme un problème mineur cependant).

Je pensais que je le posterais tout de même, pourrait être utile ..;)

37
t31os

A partir de WP 3.7, le filtre ajax_query_attachments_args offre une bien meilleure méthode, comme indiqué dans le fichier documentation :

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

Voici une solution complète pour les publications et les médias (ce code est spécifiquement destiné aux auteurs, mais vous pouvez le changer pour n’importe quel rôle d’utilisateur). Cela corrige également le nombre de publications/médias sans pirater les fichiers principaux.

// 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

Ceci est une version modifiée de la réponse acceptée . Étant donné que la réponse acceptée ne cible que l'élément de menu Multimédia à gauche, les utilisateurs pouvaient toujours voir la totalité de la médiathèque dans la boîte modale lors du téléchargement d'une photo dans un message. Ce code légèrement modifié corrige cette situation. Les utilisateurs ciblés ne verront que leurs propres éléments multimédias à partir de l'onglet Médiathèque de la boîte modale qui apparaît dans une publication.

Ceci est le code de la réponse acceptée avec un commentaire marquant la ligne à modifier ...

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

Pour que les utilisateurs ne voient que leurs propres médias à partir du menu Médias ET de l'onglet Médiathèque du mode de téléchargement, remplacez la ligne indiquée par ceci ...

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

(sauts de ligne et espacement insérés ici uniquement pour la lisibilité}

Ce qui suit est le même que ci-dessus mais les empêche également de voir leurs propres publications à partir de l'élément de menu Messages.

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

(sauts de ligne et espacement insérés ici uniquement pour la lisibilité}

Notes: comme dans la réponse acceptée, les compteurs de messages et de médias seront faux. Cependant, il existe des solutions à cela dans d'autres réponses de cette page. incorporer ceux-ci simplement parce que je ne les avais pas testés.

5
Sparky

t31os a une excellente solution là-haut. La seule chose est que le nombre de tous les messages apparaît encore.

J'ai trouvé un moyen d'empêcher le nombre de figurer à l'aide de jQuery.

Ajoutez simplement ceci à votre fichier de fonction.

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

Cela fonctionne pour moi!

2
user15182

Code de travail complet. Le seul problème est d'obtenir un nombre d'images incorrect dans la bibliothèque multimédia sur la page Ajouter une publication.

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

Une façon de procéder consiste à utiliser le plugin Role Scoper , ce qui est également très utile pour gérer des rôles et des fonctionnalités très spécifiques. En fait, vous pouvez verrouiller l'accès aux images de la bibliothèque multimédia uniquement aux images téléchargées par chaque utilisateur. Je l'utilise pour un projet sur lequel je travaille en ce moment et cela fonctionne bien.

1
Rick Curran

J'ai résolu mon problème avec une solution assez rugueuse, mais réalisable.

1) J'ai installé le plug-in WP Hide Dashboard, afin que l'utilisateur ne puisse voir qu'un lien vers son formulaire de modification de profil.

2) Dans le fichier modèle author.php, j’ai inséré le code que j’ai utilisé ci-dessus.

3) Ensuite, pour les utilisateurs connectés, j'ai affiché un lien direct vers la page de téléchargement "wp-admin/media-new.php"

4) Le numéro suivant que j'ai remarqué était après le téléchargement de la photo, il les redirigeait vers upload.php ... et ils pouvaient voir toutes les autres photos. Je n'ai pas trouvé de lien dans la page media-new.php, alors j'ai fini par pirater le noyau "media-upload.php" et les rediriger vers leur page de profil:

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

Puis remplacé wp_redirect( admin_url($location) ); par wp_redirect($userredirect);

Quelques problèmes cependant. Premièrement, l'utilisateur connecté peut toujours aller à "upload.php", s'il sait qu'il existe. Ils ne peuvent rien faire à part regarder les fichiers, et 99% des gens ne le savent même pas, mais ce n'est toujours pas optimal. Deuxièmement, il redirige également l’administrateur vers la page de profil après le téléchargement. Ceux-ci peuvent avoir un correctif assez simple en vérifiant les rôles des utilisateurs et en redirigeant uniquement les abonnés.

Si quelqu'un a des idées sur la connexion à la page Media sans aller dans les fichiers de base, je l'apprécierais. Merci!

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

Enregistrez le code ci-dessus sous le nom manage_your_media_only.php, compressez-le, envoyez-le sous forme de plug-in sur votre WP et activez-le, c'est tout.

1
Philip Borisov