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


46

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

Ecco la mia soluzione per il momento ... sto facendo una semplice query WP, quindi un ciclo nella 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);

1
Se hai trovato una risposta al tuo problema, è meglio aggiungerla come risposta di seguito, non nella domanda stessa. Questo è meglio in linea con il sistema e possiamo votare la tua risposta, che migliorerà la tua reputazione su questo sito.
Jan Fabry,


Devo davvero secondare il plug-in 'Visualizza solo i tuoi post multimediali', ha funzionato perfettamente per me dopo aver cercato ovunque una soluzione jquery o php / html / css.
Waffl,

Risposte:


37

Puoi sempre filtrare l'elenco dei media utilizzando un pre_get_postsfiltro che determina prima la pagina e le capacità dell'utente e imposta il parametro dell'autore 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 usato il limite delle pagine di eliminazione come condizione in modo che amministratori e redattori vedano ancora l'elenco completo dei media.

C'è un piccolo effetto collaterale, per il quale non riesco a vedere alcun hook, e questo è con il conteggio degli allegati mostrato sopra l'elenco dei media (che mostrerà comunque il conteggio totale degli elementi multimediali, non quello dell'utente specificato - considera questo un problema minore però).

Pensavo di pubblicarlo lo stesso, potrebbe essere utile ..;)


Ho consentito il caricamento di file per utenti di livello abbonato. provato a usare il tuo codice ma non funziona.
Sisir,

1
"Non funziona" non è molto da fare.
t31os,

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

Quindi il tuo codice deve solo essere modificato per qualsiasi pagina riempia la scheda "Libreria multimediale" della finestra di caricamento. Sto cercando questo ora.
Sparky

Se ricordo correttamente (e si verificano errori), al momento della stesura di questa risposta non erano presenti ganci appropriati, analogamente a come non esistevano ganci per correggere il conteggio dei media. Ci sono state ben 3 nuove versioni di WordPress dal momento della stesura, quindi ora le soluzioni potrebbero essere possibili.
t31os,

32

A partire da WP 3.7 c'è un modo molto migliore tramite il ajax_query_attachments_argsfiltro, come indicato 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;
}

19

Ecco una soluzione completa per post e contenuti multimediali (questo codice è specifico per gli autori, ma puoi modificarlo per qualsiasi ruolo utente). Questo risolve anche il conteggio post / media senza compromettere i file core.

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

grande frammento ma se non ci sono elementi nella libreria multimediale, sputa errori, Attenzione: array_sum () si aspetta che il parametro 1 sia array, null dato e Avvertenza: array_keys () si aspetta che il parametro 1 sia array, null dato
chrismccoy

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

4
Il codice in questa risposta funziona ma rimuove anche tutti i campi personalizzati creati dal plug-in Campi personalizzati avanzati.
Sparky


5

Questa è una versione modificata della risposta accettata . Poiché la risposta accettata ha come target solo la voce di menu Media a sinistra, gli utenti possono comunque vedere l'intera libreria multimediale all'interno della casella modale durante il caricamento di una foto in un post. Questo codice leggermente modificato risolve tale situazione. Gli utenti target vedranno i propri elementi multimediali solo dalla scheda Libreria multimediale della casella modale che viene visualizzata all'interno di un post.

Questo è il codice della risposta accettata con un commento che segna la linea 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 ) // <-- let's work on this line
        return;

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

    return;
}

Per consentire agli utenti di visualizzare i propri contenuti multimediali solo dal menu Media E dalla scheda Libreria multimediale del modulo di caricamento, sostituire la riga indicata con questa ...

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

( interruzioni di riga e spaziatura inserite solo per leggibilità qui )

Quanto segue è uguale a quello sopra ma limita anche a vedere i propri post dalla voce di menu Post.

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

( interruzioni di riga e spaziatura inserite solo per leggibilità qui )

Note : come nella risposta accettata, i post e i contatori dei media saranno errati. Tuttavia, ci sono soluzioni per questo in alcune altre risposte in questa pagina. Non li ho incorporati semplicemente perché non li avevo testati.


2

Codice di lavoro completo. L'unico problema è che il conteggio errato delle immagini nella libreria multimediale nella pagina Aggiungi post.

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
Non dovresti usare i livelli utente, sono ancora in WordPress principalmente per la retrocompatibilità (prima del WP 2.0), non sono affidabili per determinare le capacità degli utenti nei moderni WordPress (poiché probabilmente scompariranno dal core quando quella compatibilità non è più richiesta ). Utilizzare una capacità effettiva per determinare i diritti dell'utente.
t31os,

Nonostante contenga media-upload.php, il tuo codice non funziona dal modale di caricamento generato dalla pagina Post Edit. È ancora possibile visualizzare tutti gli elementi della libreria.
Sparky

2

t31os ha un'ottima soluzione lassù. L'unica cosa è che il numero di tutti i post viene ancora visualizzato.

Ho trovato un modo per evitare che il conteggio dei numeri venisse visualizzato usando jQuery.

Basta aggiungere questo al 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 per me!


1

Ho risolto il mio problema con una soluzione piuttosto approssimativa, ma praticabile.

1) Ho installato il plugin WP Hide Dashboard, quindi l'utente vedrebbe solo un link al suo modulo di modifica del profilo.

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

3) Quindi, per gli utenti che hanno effettuato l'accesso, ho visualizzato un collegamento diretto alla pagina di caricamento "wp-admin / media-new.php"

4) Il prossimo numero che ho notato, è stato dopo aver caricato la foto, li avrebbe reindirizzati su upload.php ... e avrebbero potuto vedere tutte le altre foto. Non ho trovato un gancio nella pagina media-new.php, quindi ho finito per hackerare il core "media-upload.php" e reindirizzarli alla loro pagina del profilo:

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

Quindi sostituito wp_redirect( admin_url($location) );conwp_redirect($userredirect);

Un paio di problemi, però. Innanzitutto, l'utente che ha effettuato l'accesso può comunque andare su "upload.php", se sa che esiste. Non possono fare altro che GUARDARE i file e il 99% delle persone non lo saprà nemmeno, ma non è ancora ottimale. In secondo luogo, reindirizza anche l'amministratore alla pagina del profilo dopo il caricamento. Questi possono avere una soluzione abbastanza semplice controllando i ruoli degli utenti e reindirizzando solo i Sottoscrittori.

Se qualcuno ha idee su come collegarsi alla pagina Media senza andare nei file core, lo apprezzerei. Grazie!


2
C'è un admin_inithook che gira su ogni richiesta di amministrazione. Nel caso in cui un utente richieda upload.php e desideri impedire che tu possa bloccare quella richiesta (es. wp_die('Access Denied')) O reindirizzare verso un posto valido per 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' );
?>

Salva il codice sopra come manage_your_media_only.php, comprimilo, carica come plugin sul tuo WP e attivalo, tutto qui.


1

Un modo per farlo è usare il plugin Role Scoper , è ottimo anche per la gestione di ruoli e capacità molto specifici. Puoi effettivamente bloccare l'accesso alle immagini nel Catalogo multimediale solo a quelle caricate da ciascun utente. Lo sto usando per un progetto a cui sto lavorando al momento e funziona bene.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.