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

46

Je veux que les utilisateurs puissent télécharger des photos en utilisant, add_cap('upload_files')mais dans leur page de profil, la médiathèque montre chaque image téléchargée. Comment puis-je filtrer cela pour 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);
TerryMatula
la source
1
Si vous avez trouvé une réponse à votre propre problème, vous devriez l'ajouter comme réponse ci-dessous, pas dans la question elle-même. Cela correspond mieux au système et nous pourrons voter contre votre réponse, ce qui améliorera votre réputation sur ce site.
Jan Fabry
Je dois vraiment seconder le plug-in «Afficher les messages personnels uniquement sur les médias», il a parfaitement fonctionné après avoir cherché partout une solution jquery ou php / html / css.
gaufres

Réponses:

37

Vous pouvez toujours filtrer la liste de supports à l'aide d'un pre_get_postsfiltre 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é - i considérez ceci comme un problème mineur cependant).

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

t31os
la source
J'ai autorisé le téléchargement de fichiers à des utilisateurs de niveau abonné. essayé d'utiliser votre code mais ne fonctionne pas.
Sisir
1
"Ne pas travailler", ce n'est pas grave.
t31os
Je peux confirmer la même observation. Pour moi, "ne pas travailler" signifie que le rôle "contributeur" peut toujours voir tous les éléments multimédias lorsqu'il télécharge un fichier jpg. Cependant, quand il va à la médiathèque à partir du menu, c'est vide. ( Mon rôle de "contributeur" a déjà la capacité supplémentaire de télécharger des fichiers et cela fonctionne. )
Sparky
Ainsi, votre code doit simplement être modifié pour chaque page remplissant l'onglet "Médiathèque" de la fenêtre de téléchargement. Je recherche cela maintenant.
Sparky
Si je me souviens bien (et que des erreurs se produisent), il n'y avait pas de crochets appropriés en place au moment d'écrire cette réponse, de la même manière qu'il n'y avait pas de crochets pour corriger le nombre de supports. Il y a eu trois bonnes nouvelles versions de WordPress depuis le moment de la rédaction, alors des solutions sont maintenant possibles.
T31os
32

A partir de WP 3.7, le ajax_query_attachments_argsfiltre offre un moyen bien meilleur , 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;
}
David
la source
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;
}
Paul
la source
grand extrait mais si aucun élément se trouvent dans la bibliothèque de médias, il recrache erreurs, Attention: array_sum () attend le paramètre 1 pour être ensemble, null donnée et Warning: array_keys () attend le paramètre 1 pour être ensemble, null donnée
chrismccoy
Vous devez simplement définir $ _num_posts en tant que tableau dans la fonction fix_media_counts (). $_num_posts = array();
Paul
4
Le code de cette réponse fonctionne, mais il supprime également les champs personnalisés créés par le plug-in Advanced Custom Fields.
Sparky
5

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 situé à 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 à 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 sur cette page. Je ne les ai pas incorporés simplement parce que je ne les avais pas testés.

Sparky
la source
2

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' );
Nitin
la source
2
Vous ne devez pas utiliser les niveaux d’utilisateur, ils sont dans WordPress toujours principalement pour la compatibilité descendante (avant WP 2.0), ils ne sont pas fiables pour déterminer les capacités de l’utilisateur dans WordPress moderne (car elles vont probablement disparaître du noyau lorsque cette compatibilité n’est plus requise). ). Utilisez une capacité réelle pour déterminer les droits de l'utilisateur.
t31os
Bien que contenant media-upload.php, votre code ne fonctionne pas à partir du mode de téléchargement généré par la page Post Edit. Peut toujours voir tous les éléments de la bibliothèque.
Sparky
2

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!

utilisateur15182
la source
1

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 voit 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) );parwp_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!

TerryMatula
la source
2
Il y a un admin_inithook qui s'exécute sur chaque requête de l'administrateur. Dans le cas où un utilisateur demande upload.php et que vous souhaitez empêcher que vous puissiez bloquer cette demande (par exemple wp_die('Access Denied')) ou rediriger vers un emplacement valide par hook.
hakre
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.


la source
1

Une façon de procéder consiste à utiliser le plugin Role Scoper , 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.

Rick Curran
la source