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

45

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

Voici ma solution pour le moment… Je fais une requête WP simple, 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);
    
posée TerryMatula 07.09.2010 - 19:51

9 réponses

36

Vous pouvez toujours filtrer la liste de médias en utilisant 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 médias.

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 supports (qui affiche toujours le nombre total d'éléments multimédias, et non celui de l'utilisateur donné - Je considérerais cela comme un problème mineur cependant).

Je pense que je pourrais tout de même le poster, ça pourrait être utile ..;)

    
réponse donnée t31os 20.11.2010 - 14:11
30

À partir de WP 3.7, le filtre ajax_query_attachments_args constitue une bien meilleure solution, comme indiqué dans la 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;
}
    
réponse donnée David 21.02.2015 - 01:46
19

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;
}
    
réponse donnée Paul 27.11.2011 - 21:00
4

Il s'agit d'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 l'intégralité 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 dans l'onglet Médiathèque de la boîte de dialogue modale qui apparaît dans une publication.

Il s'agit du code de la réponse acceptée avec un commentaire indiquant 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 publications et de médias seront erronés. Cependant, il existe des solutions à cela dans d'autres réponses sur cette page. Je ne les ai pas incorporés simplement parce que je ne les avais pas testés.

    
réponse donnée Sparky 03.02.2014 - 23:03
2

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

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' );
    
réponse donnée Nitin 26.11.2011 - 19:46
2

t31os a une excellente solution là-haut. Le seul problème est que le nombre de tous les articles est toujours affiché.

J’ai trouvé un moyen d’empêcher le nombre d’apparaître à 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!

    
réponse donnée user15182 14.04.2012 - 00:18
1

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

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

2) Dans le fichier de 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 prochain problème que j'ai remarqué était après le téléchargement de la photo. Il était alors redirigé 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. Tout d'abord, l'utilisateur connecté peut toujours accéder à "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 une solution 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 entrer dans les fichiers principaux, je l'apprécierais. Merci!

    
réponse donnée 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' );
?>

Enregistrez le code ci-dessus sous le nom manage_your_media_only.php, zippez-le, envoyez-le en tant que plug-in sur votre WP et activez-le, c'est tout.

    
réponse donnée Philip Borisov 08.12.2010 - 12:29
1

L’une des méthodes consiste à utiliser le plug-in Role Scoper , idéal pour la gestion de rôles très spécifiques. et les capacités aussi. 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.

    
réponse donnée Rick Curran 11.01.2011 - 12:01

Lire d'autres questions sur les étiquettes