Membatasi pengguna untuk hanya melihat item perpustakaan media yang telah mereka unggah?

46

Saya ingin pengguna dapat mengunggah foto menggunakan add_cap('upload_files')tetapi di halaman profil mereka, Perpustakaan Media menunjukkan setiap gambar yang telah diunggah. Bagaimana saya bisa memfilternya sehingga mereka hanya bisa melihat gambar yang mereka unggah?

Inilah solusi saya untuk saat ini ... Saya sedang melakukan permintaan WP sederhana, kemudian loop pada halaman "Profil" pengguna

$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
sumber
1
Jika Anda menemukan jawaban untuk masalah Anda sendiri, Anda sebaiknya menambahkannya sebagai jawaban di bawah, bukan di pertanyaan itu sendiri. Ini lebih baik sesuai dengan sistem, dan kami dapat memperbarui jawaban Anda, yang akan meningkatkan reputasi Anda di situs ini.
Jan Fabry
Saya benar-benar harus menambahkan plugin 'Lihat Tulisan Sendiri Media Saja', itu berfungsi dengan baik bagi saya setelah mencari solusi jquery atau php / html / css di mana-mana.
waffl

Jawaban:

37

Anda selalu bisa memfilter daftar media menggunakan pre_get_postsfilter yang pertama menentukan halaman, dan kemampuan pengguna, dan menetapkan parameter penulis ketika kondisi tertentu terpenuhi ..

Contoh

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

Saya menggunakan topi hapus halaman sebagai syarat sehingga Admin dan Editor masih melihat daftar media lengkap.

Ada satu efek samping kecil, yang saya tidak dapat melihat kaitannya, dan itu dengan jumlah lampiran yang ditunjukkan di atas daftar media (yang masih akan menunjukkan jumlah total item media, bukan jumlah pengguna yang diberikan - saya akan anggap ini masalah kecil).

Kupikir aku akan memposting semuanya, mungkin berguna ..;)

t31os
sumber
Saya telah mengizinkan unggahan file ke pengguna tingkat pelanggan. mencoba menggunakan kode Anda tetapi tidak berfungsi.
Sisir
1
"Tidak berfungsi" tidak banyak artinya.
t31os
Saya bisa mengkonfirmasi pengamatan yang sama. Bagi saya "tidak berfungsi" berarti bahwa peran "kontributor" masih dapat melihat semua item media saat ia hendak mengunggah jpg. Namun, ketika dia pergi ke perpustakaan media dari menu, itu kosong. ( Peran "kontributor" saya sudah memiliki kemampuan ekstra untuk mengunggah file dan itu berfungsi. )
Sparky
Jadi kode Anda hanya perlu di-tweak untuk halaman apa pun yang mengisi tab "Media Library" di jendela unggah. Saya sedang meneliti ini sekarang.
Sparky
Jika saya ingat dengan benar (dan kesalahan bisa terjadi), tidak ada kait yang tepat pada saat menulis jawaban ini, sama seperti bagaimana tidak ada kait di tempat untuk memperbaiki jumlah media. Namun ada 3 versi baru WordPress yang baik sejak saat penulisan, jadi solusi sekarang mungkin.
t31os
32

Pada WP 3.7 ada cara yang jauh lebih baik melalui ajax_query_attachments_argsfilter, seperti yang disediakan dalam dokumentasi :

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
sumber
19

Inilah solusi lengkap untuk posting dan media (kode ini khusus untuk penulis, tetapi Anda dapat mengubahnya untuk peran pengguna apa pun). Ini juga memperbaiki jumlah post / media tanpa meretas file inti.

// 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
sumber
cuplikan hebat tetapi jika tidak ada item di perpustakaan media, ia memuntahkan kesalahan, Peringatan: array_sum () mengharapkan parameter 1 menjadi array, null diberikan, dan Peringatan: array_keys () mengharapkan parameter 1 menjadi array, null diberikan
chrismccoy
Anda hanya perlu mendefinisikan $ _num_posts sebagai array dalam fungsi fix_media_counts (). $_num_posts = array();
Paul
4
Kode dalam jawaban ini berfungsi tetapi juga menghapus bidang khusus apa pun yang dibuat oleh plugin Bidang Khusus Lanjutan.
Sparky
5

Ini adalah versi modifikasi dari jawaban yang diterima . Karena jawaban yang diterima hanya menargetkan item menu Media di sebelah kiri, pengguna masih dapat melihat seluruh perpustakaan media dalam kotak modal ketika mengunggah foto ke sebuah posting. Kode yang sedikit dimodifikasi ini memperbaiki situasi itu. Pengguna yang ditargetkan hanya akan melihat item media mereka sendiri dari tab Media Library di kotak modal yang muncul di dalam sebuah posting.

Ini adalah kode dari jawaban yang diterima dengan komentar yang menandai baris yang akan diedit ...

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

Bagi pengguna untuk hanya melihat medianya sendiri dari menu Media DAN tab Perpustakaan Media dari modal unggah, ganti baris yang ditunjukkan dengan ini ...

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

( garis-jeda & spasi hanya disisipkan untuk dibaca di sini )

Berikut ini sama dengan di atas tetapi juga membatasi mereka untuk melihat posting mereka sendiri dari item menu Posts.

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

( garis-jeda & spasi hanya disisipkan untuk dibaca di sini )

Catatan : seperti pada jawaban yang diterima, kiriman dan penghitung media akan salah. Namun, ada solusi untuk ini dalam beberapa jawaban lain di halaman ini. Saya tidak memasukkannya hanya karena saya belum mengujinya.

Sparky
sumber
2

Kode kerja lengkap .. Satu-satunya masalah adalah, salah menghitung gambar di perpustakaan media di halaman Tambahkan Posting.

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
sumber
2
Anda tidak boleh menggunakan level pengguna, mereka berada di WordPress masih terutama untuk kompatibilitas mundur (sebelum WP 2.0), mereka tidak dapat diandalkan untuk menentukan kemampuan pengguna di WordPress modern (karena mereka kemungkinan akan menghilang dari inti ketika kompatibilitas itu tidak lagi diperlukan) ). Gunakan kemampuan aktual untuk menentukan hak pengguna.
t31os
Meskipun mengandung media-upload.php, kode Anda tidak berfungsi dari modal unggah yang dihasilkan oleh halaman Edit Posting. Masih bisa melihat semua item perpustakaan.
Sparky
2

t31os memiliki solusi hebat di sana. Satu-satunya hal adalah bahwa jumlah semua posting masih muncul.

Saya menemukan cara agar jumlah hitungan tidak muncul menggunakan jQuery.

Cukup tambahkan ini ke file fungsi Anda.

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

Ini bekerja untuk saya!

pengguna15182
sumber
1

Saya memecahkan masalah saya dengan solusi yang cukup kasar, tetapi bisa diterapkan.

1) Saya menginstal plugin WP Hide Dashboard, sehingga Pengguna hanya akan melihat tautan ke formulir edit profil mereka.

2) Dalam file template author.php, saya memasukkan kode yang saya gunakan di atas.

3) Kemudian, untuk pengguna yang masuk, saya menampilkan tautan langsung ke halaman Unggah "wp-admin / media-new.php"

4) Masalah berikutnya yang saya perhatikan, adalah setelah mereka mengunggah foto, itu akan mengarahkan mereka untuk mengunggah.php ... dan mereka bisa melihat semua gambar lainnya. Saya belum menemukan kait ke halaman media-new.php, jadi saya akhirnya meretas inti "media-upload.php" dan mengarahkan mereka ke halaman profil mereka:

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

Lalu diganti wp_redirect( admin_url($location) );denganwp_redirect($userredirect);

Beberapa masalah. Pertama, pengguna yang masuk masih bisa masuk ke "upload.php", jika mereka tahu itu ada. Mereka tidak dapat melakukan apa pun kecuali MELIHAT file, dan 99% orang bahkan tidak akan tahu tentang hal itu, tetapi masih belum optimal. Kedua, itu juga mengarahkan Admin ke halaman profil setelah mengunggah. Ini dapat memiliki perbaikan yang cukup sederhana dengan memeriksa peran pengguna, dan hanya mengarahkan Pelanggan.

Jika ada yang punya ide tentang menghubungkan ke halaman Media tanpa masuk ke file inti, saya akan menghargainya. Terima kasih!

TerryMatula
sumber
2
Ada admin_initkait yang berjalan di setiap permintaan admin. Seandainya pengguna meminta upload.php dan Anda ingin mencegahnya, Anda bisa memblokir permintaan itu (mis. wp_die('Access Denied')) Atau mengalihkan ke beberapa tempat yang sah per kait.
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' );
?>

Simpan kode di atas sebagai manage_your_media_only.php, zip, unggah sebagai plugin ke WP Anda dan aktifkan, itu saja.


sumber
1

Salah satu cara untuk melakukan ini adalah dengan menggunakan plugin Role Scoper , ini sangat bagus untuk mengelola peran dan kemampuan yang sangat spesifik. Anda sebenarnya dapat mengunci akses ke gambar di Perpustakaan Media hanya untuk yang diunggah oleh setiap pengguna. Saya telah menggunakannya untuk proyek yang sedang saya kerjakan saat ini dan berfungsi dengan baik.

Rick Curran
sumber