Limitare gli utenti a visualizzare solo gli elementi della libreria multimediale che hanno caricato

7 set 2010, 20:51:44
Visualizzazioni: 41.8K
Voti: 49

Voglio che gli utenti possano caricare foto usando add_cap('upload_files') ma nella loro pagina del profilo, la Libreria Multimediale mostra tutte le immagini che sono state caricate. Come posso filtrare in modo che possano vedere solo le immagini che hanno caricato loro?

Ecco la mia soluzione per il momento... Sto facendo una semplice query WP, poi un ciclo sulla pagina "Profilo" dell'utente

$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);
3
Commenti

Se hai trovato una soluzione al tuo problema, sarebbe meglio aggiungerla come risposta qui sotto, non nella domanda stessa. Questo è più in linea con il sistema e possiamo votare la tua risposta, il che migliorerà la tua reputazione su questo sito.

Jan Fabry Jan Fabry
9 set 2010 21:18:47

Devo davvero appoggiare il plugin 'View Own Posts Media Only', ha funzionato perfettamente per me dopo aver cercato ovunque una soluzione in jQuery, PHP/HTML/CSS.

waffl waffl
4 mar 2014 15:56:38
Tutte le risposte alla domanda 9
11
46

Puoi sempre filtrare l'elenco dei media utilizzando un filtro pre_get_posts che prima determina la pagina e le capacità dell'utente, e imposta il parametro author quando vengono soddisfatte determinate condizioni..

Esempio

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

Ho utilizzato la capacità delete_pages come condizione in modo che gli Amministratori e gli Editori continuino a vedere l'elenco completo dei media.

C'è un piccolo effetto collaterale, per il quale non vedo alcun hook disponibile, ed è con i conteggi degli allegati mostrati sopra l'elenco dei media (che mostreranno ancora il conteggio totale degli elementi multimediali, non quello dell'utente specifico - considererei comunque questo un problema minore).

Ho pensato di pubblicarlo comunque, potrebbe essere utile.. ;)

20 nov 2010 15:11:40
Commenti

Ho permesso il caricamento di file agli utenti con livello subscriber. Ho provato a usare il tuo codice ma non funziona.

Sisir Sisir
6 mag 2012 20:52:08

"Non funziona" non è molto utile per capire il problema.

t31os t31os
9 ago 2013 01:03:13

Posso confermare la stessa osservazione. Per me "non funziona" significa che il ruolo "contributor" può ancora vedere tutti gli elementi multimediali quando va a caricare un jpg. Tuttavia, quando accede alla libreria multimediale dal menu, è vuota. (Il mio ruolo "contributor" ha già la capacità aggiuntiva di caricare file e quello funziona.)

Sparky Sparky
3 feb 2014 21:27:25

Quindi il tuo codice ha solo bisogno di essere modificato per qualunque pagina riempia la scheda "Libreria Media" della finestra di caricamento. Sto facendo ricerche su questo ora.

Sparky Sparky
3 feb 2014 21:30:25

Se ricordo correttamente (e gli errori possono capitare), al momento della stesura di questa risposta non c'erano hook appropriati disponibili, in modo simile a come non c'erano hook per sistemare il conteggio dei media. Sono passate almeno 3 nuove versioni di WordPress da allora, quindi ora potrebbero esserci soluzioni possibili.

t31os t31os
3 feb 2014 21:33:47

Inoltre, potrebbe essere semplicemente una questione di aggiornare il controllo condizionale $pagenow, dato che questo punta a indirizzare la query specificamente per la pagina principale dei media, che non è la stessa cosa della scheda media nel popup di caricamento.

t31os t31os
3 feb 2014 21:35:01

Non mi interessa se i conteggi sono sbagliati. A parte questo, il tuo codice funziona dalla voce Media nel menu (WP v3.8.1). Sto cercando di farlo funzionare dalla finestra di upload che si apre all'interno della pagina "Nuovo articolo". Sì, sono d'accordo... sto cercando di trovare la pagina corretta per il controllo $pagenow.

Sparky Sparky
3 feb 2014 21:45:46

Ecco la soluzione: http://wordpress.stackexchange.com/a/132319/11092

Sparky Sparky
4 feb 2014 00:03:38

if( !in_array( $pagenow, array( 'upload.php', 'admin-ajax.php' ) Questa riga nel tuo codice manca di una parentesi di chiusura ), dovrebbero esserci tre ), ma il tuo codice ne ha solo due.

Ibrahim Ibrahim
10 dic 2016 08:52:15

Questo sembra applicarsi solo alla vista griglia. Qualche consiglio su come realizzarlo anche per la vista elenco?

Dedering Dedering
8 nov 2017 22:17:31

Soluzione alla mia domanda sopra: if( ('upload.php' != $pagenow ) && ( 'admin-ajax.php' != $pagenow || $_REQUEST['action'] != 'query-attachments' ) )

Dedering Dedering
9 nov 2017 00:01:36
Mostra i restanti 6 commenti
0
39

A partire da WP 3.7 esiste un metodo molto migliore tramite il filtro ajax_query_attachments_args, come fornito nella documentazione:

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;
}
21 feb 2015 02:46:42
4
19

Ecco una soluzione completa sia per i post che per i media (questo codice è specifico per gli autori, ma puoi modificarlo per qualsiasi ruolo utente). Questo sistema corregge anche il conteggio dei post/media senza modificare i file core.

// Mostra solo post e media relativi all'autore loggato
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');
    }
}

// Corregge il conteggio dei post
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,
            __('Tutti')
        );
        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,
            __('Pubblicati')
        );
        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,
            __('Bozze')
        );
        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,
            __('In attesa')
        );
        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,
            __('Cestino')
        );
        endif;
    }
    return $views;
}

// Corregge il conteggio dei media
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( __('Tutti <span class="count">(%s)</span>', 'file caricati' ), 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( __( 'Non collegati <span class="count">(%s)</span>', 'file scollegati' ), $total_orphans ) . '</a>';
    return $views;
}
27 nov 2011 22:00:09
Commenti

ottimo snippet ma se non ci sono elementi nella libreria multimediale, restituisce errori, Warning: array_sum() expects parameter 1 to be array, null given, e Warning: array_keys() expects parameter 1 to be array, null given

chrismccoy chrismccoy
25 feb 2012 02:40:55

Devi solo definire $_num_posts come un array nella funzione fix_media_counts(). $_num_posts = array();

Paul Paul
9 set 2012 02:37:33

Il codice in questa risposta funziona ma rimuove anche tutti i campi personalizzati creati dal plugin Advanced Custom Fields.

Sparky Sparky
3 feb 2014 22:26:02
0

Questa è una versione modificata della risposta accettata. Poiché la risposta accettata si concentra solo sulla voce Media nel menu a sinistra, gli utenti potevano comunque vedere l'intera libreria multimediale all'interno della finestra modale durante il caricamento di una foto in un articolo. Questo codice leggermente modificato risolve quella situazione. Gli utenti mirati vedranno solo i propri elementi multimediali dalla scheda Libreria multimediale della finestra modale che appare all'interno di un articolo.

Questo è il codice della risposta accettata con un commento che segna la riga da modificare...

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 ) // <-- lavoriamo su questa riga
        return;

    if( !current_user_can('delete_pages') )
        $wp_query_obj->set('author', $current_user->id );

    return;
}

Affinché gli utenti vedano solo i propri media dal menu Media E dalla scheda Libreria multimediale della finestra modale di caricamento, sostituire la riga indicata con questa...

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

(a capo e spaziatura inseriti solo per migliorare la leggibilità qui)

Quello che segue è lo stesso codice di sopra ma restringe anche la visualizzazione dei propri articoli dalla voce di menu Articoli.

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

(a capo e spaziatura inseriti solo per migliorare la leggibilità qui)

Note: come nella risposta accettata, i contatori di articoli e media saranno errati. Tuttavia, ci sono soluzioni per questo in alcune altre risposte in questa pagina. Non le ho incorporate semplicemente perché non le avevo testate.

4 feb 2014 00:03:00
2

Codice funzionante completo.. L'unico problema è che ottiene un conteggio errato delle immagini nella libreria multimediale nella pagina Aggiungi articolo.

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' );
26 nov 2011 20:46:32
Commenti

Non dovresti utilizzare i livelli utente, sono ancora presenti in WordPress principalmente per compatibilità con le versioni precedenti (antecedenti a WP 2.0), non sono affidabili per determinare le capacità degli utenti nella versione moderna di WordPress (poiché probabilmente scompariranno dal core quando tale compatibilità non sarà più necessaria). Utilizza una capability effettiva per determinare i diritti degli utenti.

t31os t31os
28 gen 2014 15:56:29

Nonostante contenga media-upload.php, il tuo codice non funziona dalla modale di upload generata dalla pagina di modifica articolo. Si possono ancora vedere tutti gli elementi della libreria.

Sparky Sparky
3 feb 2014 21:58:34
0

t31os ha una soluzione eccellente lì sopra. L'unica cosa è che il numero totale dei post continua a essere visualizzato.

Ho trovato un modo per evitare che il conteggio dei numeri venga mostrato utilizzando jQuery.

Aggiungi semplicemente questo al tuo file delle funzioni.

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

Funziona perfettamente per me!

14 apr 2012 01:18:26
1

Ho risolto il mio problema con una soluzione un po' grezza ma funzionante.

1) Ho installato il plugin WP Hide Dashboard, in modo che l'utente visualizzi solo un link alla pagina di modifica del proprio profilo.

2) Nel file template author.php, ho inserito il codice che ho usato sopra.

3) Poi, per gli utenti loggati, ho mostrato un link diretto alla pagina di Upload "wp-admin/media-new.php"

4) Il problema successivo che ho notato è che dopo aver caricato la foto, venivano reindirizzati a upload.php... e potevano vedere tutte le altre immagini. Non avendo trovato un hook nella pagina media-new.php, alla fine ho modificato il core "media-upload.php" reindirizzandoli alla loro pagina profilo:

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

Poi ho sostituito wp_redirect( admin_url($location) ); con wp_redirect($userredirect);

Un paio di problemi però. Primo, l'utente loggato può ancora accedere a "upload.php", se sa che esiste. Non può fare altro che VEDERE i file, e il 99% delle persone non lo saprà mai, ma comunque non è ottimale. Secondo, reindirizza anche l'Admin alla pagina profilo dopo il caricamento. Questi problemi possono essere risolti abbastanza facilmente verificando i ruoli utente e reindirizzando solo gli Iscritti (Subscribers).

Se qualcuno ha idee su come agganciarsi alla pagina Media senza modificare i file core, lo apprezzerei. Grazie!

10 set 2010 17:56:23
Commenti

Esiste un hook admin_init che viene eseguito ad ogni richiesta di amministrazione. Nel caso in cui un utente richieda upload.php e tu voglia impedirlo, puoi bloccare la richiesta (ad esempio wp_die('Accesso Negato')) oppure reindirizzare a una pagina valida tramite l'hook.

hakre hakre
11 set 2010 03:49:09
0
<?php
/*
Plugin Name: Gestisci Solo i Tuoi Media
Version: 0.1
*/

//Gestisci Solo i Tuoi Media
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' );
?>

Salva il codice sopra come manage_your_media_only.php, zippalo, caricalo come plugin nel tuo WordPress e attivalo, questo è tutto.

8 dic 2010 13:29:52
0

Un modo per farlo è utilizzare il plugin Role Scoper, che è ottimo anche per gestire ruoli e capacità molto specifici. Puoi effettivamente bloccare l'accesso alle immagini nella Libreria multimediale solo a quelle caricate da ciascun utente. Lo sto usando per un progetto su cui sto lavorando al momento e funziona bene.

11 gen 2011 13:01:20