Restricționarea utilizatorilor pentru a vedea doar elementele din biblioteca media pe care le-au încărcat

7 sept. 2010, 20:51:44
Vizualizări: 41.8K
Voturi: 49

Vreau ca utilizatorii să poată încărca fotografii folosind add_cap('upload_files') dar în pagina lor de profil, Biblioteca Media afișează fiecare imagine care a fost încărcată. Cum pot filtra astfel încât ei să poată vedea doar imaginile pe care le-au încărcat ei?

Iată soluția mea pentru moment... Fac o interogare WP simplă, apoi o iterare pe pagina de "Profil" a utilizatorului

$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
Comentarii

Dacă ai găsit un răspuns la propria ta problemă, e mai bine să-l adaugi ca răspuns mai jos, nu în întrebarea în sine. Acest lucru se aliniază mai bine cu sistemul și putem vota în sus răspunsul tău, ceea ce îți va îmbunătăți reputația pe acest site.

Jan Fabry Jan Fabry
9 sept. 2010 21:18:47

Trebuie să susțin și eu plugin-ul 'View Own Posts Media Only', a funcționat perfect pentru mine după ce am căutat peste tot o soluție în jQuery sau PHP/HTML/CSS.

waffl waffl
4 mar. 2014 15:56:38
Toate răspunsurile la întrebare 9
11
46

Puteți filtra întotdeauna lista de fișiere media folosind un filtru pre_get_posts care determină mai întâi pagina și capabilitățile utilizatorului, apoi setează parametrul autor atunci când sunt îndeplinite anumite condiții..

Exemplu

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

Am folosit capabilitatea 'delete_pages' ca condiție, astfel încât Administratorii și Editorii să vadă în continuare întreaga listă de fișiere media.

Există un mic efect secundar, pentru care nu văd vreun hook disponibil, și anume numărul de fișiere afișat deasupra listei de media (care va arăta în continuare numărul total de fișiere media, nu doar cele ale utilizatorului curent - consider însă că aceasta este o problemă minoră).

Am considerat totuși util să împărtășesc această soluție, poate fi de folos.. ;)

20 nov. 2010 15:11:40
Comentarii

Am permis încărcarea de fișiere pentru utilizatorii cu nivel de abonat. Am încercat să folosesc codul tău, dar nu funcționează.

Sisir Sisir
6 mai 2012 20:52:08

"Nu funcționează" nu este suficient pentru a înțelege problema.

t31os t31os
9 aug. 2013 01:03:13

Pot confirma aceeași observație. Pentru mine "nu funcționează" înseamnă că rolul de "contributor" poate vedea toate elementele media când încarcă un fișier jpg. Totuși, când accesează biblioteca media din meniu, aceasta este goală. (Rolul meu de "contributor" are deja capacitatea suplimentară de a încărca fișiere și asta funcționează.)

Sparky Sparky
3 feb. 2014 21:27:25

Deci codul tău trebuie doar ajustat pentru orice pagină umple fila "Bibliotecă Media" din fereastra de încărcare. Fac cercetări acum pe această temă.

Sparky Sparky
3 feb. 2014 21:30:25

Dacă îmi amintesc corect (și greșelile se întâmplă), nu existau niciun fel de hook-uri adecvate la momentul scrierii acestui răspuns, similar cu modul în care nu existau hook-uri pentru a repara numărul de fișiere media. Au trecut vreo 3 versiuni noi de WordPress de atunci, așa că soluții pot fi acum posibile.

t31os t31os
3 feb. 2014 21:33:47

În plus, ar putea fi doar o problemă de actualizare a condiției de verificare $pagenow, deoarece acesta vizează specific interogarea pentru pagina principală de media, care nu este una și aceeași cu fila de media din popup-ul de încărcare.

t31os t31os
3 feb. 2014 21:35:01

Nu-mi pasă dacă numărătoarea este greșită. În rest, codul tău funcționează din elementul Media din meniu (WP v3.8.1). Încerc să fac asta să funcționeze din fereastra de încărcare care apare în pagina "Postare nouă". Da, sunt de acord... Încerc să găsesc pagina corectă pentru verificarea $pagenow.

Sparky Sparky
3 feb. 2014 21:45:46

Iată soluția: 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' ) Această linie din codul tău lipsește o paranteză de închidere ), Ar trebui să fie trei ), dar codul tău are doar două.

Ibrahim Ibrahim
10 dec. 2016 08:52:15

Aceasta pare să se aplice doar la vizualizarea grilă. Aveți recomandări despre cum să realizăm acest lucru și pentru vizualizarea listă?

Dedering Dedering
8 nov. 2017 22:17:31

Soluție la întrebarea mea de mai sus: if( ('upload.php' != $pagenow ) && ( 'admin-ajax.php' != $pagenow || $_REQUEST['action'] != 'query-attachments' ) )

Dedering Dedering
9 nov. 2017 00:01:36
Arată celelalte 6 comentarii
0
39

Începând cu WP 3.7 există o metodă mult mai bună prin intermediul filtrului ajax_query_attachments_args, așa cum este prezentat în documentație:

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

Iată o soluție completă pentru ambele tipuri de conținut - postări și fișiere media (acest cod este conceput special pentru autori, dar îl poți adapta pentru orice rol de utilizator). Această soluție rezolvă și problema numărării postărilor/fișierelor fără a modifica fișierele de bază ale WordPress.

// Afișează doar postările și fișierele media asociate autorului logat
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');
    }
}

// Corectează numărul de postări
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,
            __('Toate')
        );
        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,
            __('Publicate')
        );
        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,
            __('Ciorne')
        );
        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,
            __('În așteptare')
        );
        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,
            __('Coș de gunoi')
        );
        endif;
    }
    return $views;
}

// Corectează numărul de fișiere 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( __('Toate <span class="count">(%s)</span>', 'fișiere încărcate'), 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( __( 'Neatașate <span class="count">(%s)</span>', 'fișiere detașate'), $total_orphans ) . '</a>';
    return $views;
}
27 nov. 2011 22:00:09
Comentarii

fragment excelent, dar dacă nu există elemente în biblioteca media, afișează erori, Warning: array_sum() expects parameter 1 to be array, null given, și Warning: array_keys() expects parameter 1 to be array, null given

chrismccoy chrismccoy
25 feb. 2012 02:40:55

Trebuie doar să definești $_num_posts ca un array în funcția fix_media_counts(). $_num_posts = array();

Paul Paul
9 sept. 2012 02:37:33

Codul din acest răspuns funcționează, dar elimină și orice câmpuri personalizate create de plugin-ul Advanced Custom Fields.

Sparky Sparky
3 feb. 2014 22:26:02
0

Aceasta este o versiune modificată a răspunsului acceptat. Deoarece răspunsul acceptat se adresează doar elementului de meniu Media din stânga, utilizatorii puteau vedea întreaga bibliotecă de media în caseta modală la încărcarea unei fotografii într-un articol. Acest cod ușor modificat rezolvă această situație. Utilizatorii vizate vor vedea doar propriile elemente media din fila Biblioteca Media a casetei modale care apare în interiorul unui articol.

Acesta este codul din răspunsul acceptat, cu un comentariu care marchează linia de editat...

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 ) // <-- să lucrăm la această linie
        return;

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

    return;
}

Pentru ca utilizatorii să vadă doar propriile media atât din meniul Media, cât și din fila Biblioteca Media a casetei modale de încărcare, înlocuiți linia indicată cu aceasta...

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

(întreruperi de linie și spațiere adăugate doar pentru lizibilitate aici)

Următorul cod este la fel ca cel de mai sus, dar restricționează și vizualizarea propriilor articole din elementul de meniu Articole.

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

(întreruperi de linie și spațiere adăugate doar pentru lizibilitate aici)

Note: ca și în răspunsul acceptat, contoarele pentru articole și media vor fi greșite. Cu toate acestea, există soluții pentru aceasta în alte răspunsuri de pe această pagină. Nu le-am încorporat pur și simplu pentru că nu le-am testat.

4 feb. 2014 00:03:00
2

Cod funcțional complet.. Singura problemă este că se afișează numărul greșit de imagini în biblioteca media pe pagina de Adăugare Postare.

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
Comentarii

Nu ar trebui să folosești niveluri de utilizator, acestea sunt încă în WordPress în principal pentru compatibilitate retroactivă (anterior WP 2.0), nu sunt fiabile pentru determinarea capacităților utilizatorilor în WordPressul modern (deoarece vor dispărea probabil din nucleu când acea compatibilitate nu va mai fi necesară). Folosește o capabilitate reală pentru a determina drepturile utilizatorului.

t31os t31os
28 ian. 2014 15:56:29

În ciuda faptului că conține media-upload.php, codul tău nu funcționează din fereastra modală de încărcare generată de pagina de Editare Postare. Pot fi văzute în continuare toate elementele din bibliotecă.

Sparky Sparky
3 feb. 2014 21:58:34
0

t31os are o soluție excelentă mai sus. Singurul lucru este că numărul total de articole încă apare.

Am găsit o modalitate de a preveni afișarea numărului de articole folosind jQuery.

Adaugă acest cod în fișierul tău de funcții.

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

Funcționează perfect pentru mine!

14 apr. 2012 01:18:26
1

Am rezolvat problema mea cu o soluție destul de dură, dar funcțională.

1) Am instalat plugin-ul WP Hide Dashboard, astfel încât utilizatorul să vadă doar un link către formularul de editare a profilului său.

2) În fișierul șablon author.php, am inserat codul pe care l-am folosit mai sus.

3) Apoi, pentru utilizatorii autentificați, am afișat un link direct către pagina de încărcare "wp-admin/media-new.php"

4) Următoarea problemă pe care am observat-o a fost că după ce încărcau fotografia, erau redirecționați către upload.php... și puteau vedea toate celelalte imagini. Nu am găsit un hook în pagina media-new.php, așa că am ajuns să modific fișierul core "media-upload.php" și să-i redirecționez către pagina lor de profil:

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

Apoi am înlocuit wp_redirect( admin_url($location) ); cu wp_redirect($userredirect);

Câteva probleme, totuși. În primul rând, utilizatorul autentificat poate încă accesa "upload.php", dacă știe că există. Nu pot face altceva decât să VADĂ fișierele, iar 99% dintre oameni nici măcar nu vor ști despre asta, dar totuși nu este optim. În al doilea rând, redirecționează și Administratorul către pagina de profil după încărcare. Acestea pot fi rezolvate destul de simplu prin verificarea rolurilor utilizatorilor și redirecționarea doar a Abonaților.

Dacă cineva are idei despre cum să folosească un hook în pagina Media fără a modifica fișierele core, aș aprecia. Mulțumesc!

10 sept. 2010 17:56:23
Comentarii

Există un hook admin_init care rulează la fiecare solicitare în administrare. În cazul în care un utilizator solicită upload.php și doriți să împiedicați acest lucru, puteți fie să blocați acea solicitare (de exemplu, wp_die('Acces interzis')), fie să redirecționați către un loc valid prin intermediul hook-ului.

hakre hakre
11 sept. 2010 03:49:09
0
<?php
/*
Plugin Name: Gestionează Doar Media Ta
Version: 0.1
*/

//Gestionează Doar Media Ta
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' );
?>

Salvează codul de mai sus ca manage_your_media_only.php, arhivează-l în format zip, încarcă-l ca plugin în WordPress și activează-l, asta e tot.

8 dec. 2010 13:29:52
0

O modalitate de a face acest lucru este să folosești plugin-ul Role Scoper, care este excelent pentru gestionarea rolurilor și capabilităților foarte specifice. De fapt, poți restricționa accesul la imaginile din Biblioteca Media doar pentru cele încărcate de fiecare utilizator. Eu l-am folosit pentru un proiect la care lucrez în prezent și funcționează foarte bine.

11 ian. 2011 13:01:20