จำกัด ผู้ใช้ให้ดูเฉพาะรายการไลบรารีสื่อที่พวกเขาอัปโหลดหรือไม่


46

ฉันต้องการให้ผู้ใช้สามารถอัปโหลดรูปภาพที่ใช้add_cap('upload_files')แต่ในหน้าโปรไฟล์ของพวกเขาไลบรารีสื่อจะแสดงทุกรูปภาพที่ถูกอัปโหลด ฉันจะกรองเพื่อให้สามารถดูเฉพาะภาพที่พวกเขาอัปโหลดได้อย่างไร

นี่เป็นวิธีแก้ปัญหาของฉันในขณะนี้ ... ฉันกำลังทำแบบสอบถาม WP อย่างง่ายจากนั้นวนซ้ำในหน้า "โปรไฟล์" ของผู้ใช้

$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
หากคุณพบคำตอบสำหรับปัญหาของคุณเองคุณควรเพิ่มไว้เป็นคำตอบด้านล่างไม่ใช่ในคำถาม สิ่งนี้ดีกว่าตามระบบและเราสามารถโหวตคำตอบของคุณได้ซึ่งจะปรับปรุงชื่อเสียงของคุณในเว็บไซต์นี้
Jan Fabry


ฉันต้องทำอย่างที่สอง 'ดูด้วยตัวเองโพสต์สื่อเท่านั้น' ปลั๊กอินมันทำงานได้อย่างสมบูรณ์แบบสำหรับฉันหลังจากมองทุกที่เพื่อหา jquery หรือ php / html / css
วาฟเฟิล

คำตอบ:


37

คุณสามารถกรองรายการสื่อโดยใช้pre_get_postsตัวกรองที่กำหนดหน้าแรกและความสามารถของผู้ใช้และตั้งค่าพารามิเตอร์ผู้เขียนเมื่อตรงตามเงื่อนไขบางประการ

ตัวอย่าง

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

ฉันใช้ขีด จำกัด การลบหน้าเป็นเงื่อนไขเพื่อให้ผู้ดูแลระบบและบรรณาธิการยังคงเห็นรายการสื่อเต็มรูปแบบ

มีผลข้างเคียงเล็ก ๆ น้อย ๆ หนึ่งซึ่งฉันไม่เห็น hooks สำหรับและนั่นคือด้วยการนับสิ่งที่แนบมาแสดงเหนือรายการสื่อ (ซึ่งจะยังคงแสดงจำนวนรวมของรายการสื่อไม่ใช่ของผู้ใช้ที่ได้รับ - คิดว่านี่เป็นปัญหาเล็กน้อย)

คิดว่าฉันจะโพสต์ไว้เหมือนกันทั้งหมดอาจเป็นประโยชน์ .. ;)


ฉันอนุญาตให้อัปโหลดไฟล์ไปยังผู้ใช้ระดับสมาชิก พยายามใช้รหัสของคุณ แต่ไม่ทำงาน
Sisir

1
"ไม่ทำงาน" ไม่มากไป
t31os

ฉันสามารถยืนยันการสังเกตเดียวกัน สำหรับฉัน "ไม่ทำงาน" หมายความว่าบทบาท "ผู้มีส่วนร่วม" ยังคงสามารถดูรายการสื่อทั้งหมดเมื่อเขาไปอัปโหลด jpg อย่างไรก็ตามเมื่อเขาไปที่ไลบรารีสื่อจากเมนูมันว่างเปล่า ( บทบาท "ผู้มีส่วนร่วมของฉัน" มีความสามารถพิเศษในการอัปโหลดไฟล์แล้วและใช้งานได้ )
Sparky

ดังนั้นโค้ดของคุณจำเป็นต้องได้รับการ tweaked สำหรับหน้าใดก็ตามเติมแท็บ "Media Library" ของหน้าต่างอัปโหลด ฉันกำลังค้นคว้าสิ่งนี้อยู่ตอนนี้
ปาร์

หากฉันจำได้อย่างถูกต้อง (และมีข้อผิดพลาดเกิดขึ้น) ไม่มี hooks ที่เหมาะสมในขณะที่เขียนคำตอบนี้คล้ายกับว่าไม่มี hooks ในการแก้ไขจำนวนสื่อบันทึก WordPress มี 3 เวอร์ชั่นใหม่ที่ดีมาตั้งแต่ตอนที่เขียนดังนั้นวิธีการแก้ปัญหาอาจเป็นไปได้
t31os

32

ในฐานะของ WP 3.7 มีวิธีที่ดีกว่ามากผ่านajax_query_attachments_argsตัวกรองตามที่ระบุไว้ในเอกสารประกอบ :

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

นี่คือโซลูชันที่สมบูรณ์แบบสำหรับทั้งโพสต์และสื่อ (รหัสนี้ใช้สำหรับผู้เขียนโดยเฉพาะ แต่คุณสามารถเปลี่ยนได้สำหรับบทบาทผู้ใช้ใด ๆ ) สิ่งนี้จะแก้ไขการนับจำนวนโพสต์ / สื่อโดยไม่แฮ็คไฟล์หลัก

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

ตัวอย่างข้อมูลที่ดี แต่ถ้าไม่มีรายการอยู่ในห้องสมุดสื่อก็ถ่มน้ำลายออกข้อผิดพลาดคำเตือน: array_sum () คาดว่า 1 พารามิเตอร์ที่จะอาร์เรย์ null รับและคำเตือน: array_keys () คาดว่า 1 พารามิเตอร์ที่จะอาร์เรย์ null รับ
chrismccoy

คุณเพียงแค่ต้องกำหนด $ _num_posts เป็นอาร์เรย์ในฟังก์ชัน fix_media_counts () $_num_posts = array();
พอล

4
รหัสในคำตอบนี้ใช้งานได้ แต่มันจะลบฟิลด์ที่กำหนดเองใด ๆ ที่สร้างขึ้นโดยปลั๊กอินฟิลด์ที่กำหนดเองขั้นสูง
ปาร์

1
เกี่ยวข้องกันมาก: wordpress.stackexchange.com/questions/178236/…
cregox

5

นี้เป็นรุ่นที่แก้ไขของคำตอบที่ได้รับการยอมรับ เนื่องจากคำตอบที่ได้รับการยอมรับมีเป้าหมายที่รายการเมนูสื่อทางด้านซ้ายผู้ใช้ยังคงสามารถดูคลังสื่อทั้งหมดภายในกล่องโมดอลเมื่ออัปโหลดภาพถ่ายไปยังโพสต์ รหัสที่แก้ไขเล็กน้อยนี้จะแก้ไขสถานการณ์นั้น ผู้ใช้เป้าหมายจะเห็นเฉพาะรายการสื่อของตัวเองจากแท็บ Media Library ของกล่อง modal ที่ปรากฏขึ้นภายในโพสต์

นี่คือรหัสจากคำตอบที่ยอมรับพร้อมกับความคิดเห็นที่ทำเครื่องหมายบรรทัดเพื่อแก้ไข ...

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

เพื่อให้ผู้ใช้ดูเฉพาะสื่อของตนเองจากเมนูสื่อและแท็บไลบรารีสื่อของ modal อัพโหลดให้แทนที่บรรทัดที่ระบุด้วยสิ่งนี้ ...

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

( แทรกตัวแบ่งบรรทัดและเว้นวรรคเพื่อความสะดวกในการอ่านที่นี่ )

ต่อไปนี้เป็นแบบเดียวกับด้านบน แต่ยัง จำกัด ให้เห็นโพสต์ของตนเองจากรายการเมนูโพสต์

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

( แทรกตัวแบ่งบรรทัดและเว้นวรรคเพื่อความสะดวกในการอ่านที่นี่ )

หมายเหตุ : ในคำตอบที่ยอมรับโพสต์และตัวนับสื่อจะผิด อย่างไรก็ตามมีคำตอบสำหรับคำตอบอื่น ๆ ในหน้านี้ ฉันไม่ได้รวมสิ่งเหล่านั้นเพียงเพราะฉันไม่ได้ทดสอบ


2

รหัสการทำงานเสร็จสมบูรณ์ .. ปัญหาเท่านั้นคือการนับจำนวนรูปภาพในไลบรารีสื่อผิดพลาดในหน้าเพิ่มโพสต์

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
คุณไม่ควรใช้ระดับผู้ใช้พวกเขาอยู่ใน WordPress เป็นหลักเพื่อความเข้ากันได้ย้อนหลัง (ก่อน WP 2.0) พวกเขาไม่น่าเชื่อถือสำหรับการกำหนดความสามารถของผู้ใช้ในวันที่ทันสมัย ​​WordPress (เพราะพวกเขาจะหายไปจากแกนกลาง ) ใช้ความสามารถที่แท้จริงเพื่อกำหนดสิทธิ์ของผู้ใช้
t31os

แม้จะมีmedia-upload.phpรหัสของคุณไม่ทำงานจาก modal การอัปโหลดที่สร้างขึ้นโดยหน้าแก้ไขการโพสต์ ยังสามารถดูรายการไลบรารีทั้งหมดได้
ปาร์

2

t31os มีทางออกที่ยอดเยี่ยมอยู่ที่นั่น สิ่งเดียวคือจำนวนโพสต์ทั้งหมดยังคงปรากฏขึ้น

ฉันหาวิธีที่จะป้องกันไม่ให้จำนวนนับแสดงโดยใช้ jQuery

เพียงเพิ่มไฟล์นี้ลงในไฟล์ฟังก์ชั่นของคุณ

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

มันใช้งานได้สำหรับฉัน!


1

ฉันแก้ไขปัญหาด้วยวิธีแก้ปัญหาที่ค่อนข้างหยาบ แต่ใช้การได้

1) ฉันติดตั้งปลั๊กอิน WP Hide Dashboard ดังนั้นผู้ใช้จะเห็นลิงค์ไปยังแบบฟอร์มแก้ไขโปรไฟล์ของพวกเขาเท่านั้น

2) ในไฟล์เทมเพลต author.php ฉันใส่รหัสที่ฉันใช้ด้านบน

3) จากนั้นสำหรับผู้ใช้ที่เข้าสู่ระบบฉันแสดงลิงค์โดยตรงไปยังหน้าอัปโหลด "wp-admin / media-new.php"

4) ปัญหาต่อไปที่ฉันสังเกตเห็นคือหลังจากที่พวกเขาอัปโหลดรูปภาพมันจะเปลี่ยนเส้นทางพวกเขาไปยัง upload.php ... และพวกเขาสามารถเห็นภาพอื่น ๆ ทั้งหมด ฉันไม่พบตะขอลงในหน้า media-new.php ดังนั้นฉันจึงแฮ็คข้อมูลหลัก "media-upload.php" และเปลี่ยนเส้นทางไปยังหน้าโปรไฟล์:

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

แล้วแทนที่wp_redirect( admin_url($location) );ด้วยwp_redirect($userredirect);

แม้ว่าสองประเด็น ก่อนอื่นผู้ใช้ที่เข้าสู่ระบบสามารถไปที่ "upload.php" ได้หากพวกเขารู้ว่ามีอยู่จริง พวกเขาไม่สามารถทำอะไรได้นอกจากดูที่ไฟล์และ 99% ของคนไม่รู้ด้วยซ้ำ แต่มันก็ยังไม่เหมาะสม ประการที่สองมันยังเปลี่ยนเส้นทางผู้ดูแลไปที่หน้าโปรไฟล์หลังจากอัปโหลด สิ่งเหล่านี้สามารถแก้ไขได้ค่อนข้างง่ายโดยตรวจสอบบทบาทของผู้ใช้และเปลี่ยนเส้นทางผู้สมัครสมาชิกเท่านั้น

หากใครมีความคิดเกี่ยวกับการเชื่อมโยงไปยังหน้าสื่อโดยไม่ต้องเข้าไปในไฟล์หลักผมก็ขอขอบคุณ ขอบคุณ!


2
มีadmin_initตะขอที่ทำงานกับทุกคำขอของผู้ดูแลระบบ ในกรณีที่ผู้ใช้ร้องขอ upload.php และคุณต้องการป้องกันไม่ให้คุณสามารถบล็อกคำขอนั้น (เช่นwp_die('Access Denied')) หรือเปลี่ยนเส้นทางไปยังสถานที่ที่ถูกต้องต่อเบ็ด
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' );
?>

บันทึกรหัสข้างต้นเป็น Manage_your_media_only.php, ซิปมัน, อัปโหลดเป็นปลั๊กอินไปยัง WP ของคุณและเปิดใช้งานมันคือทั้งหมดที่


1

วิธีหนึ่งในการทำเช่นนี้คือการใช้ปลั๊กอิน Role Scoperมันยอดเยี่ยมสำหรับการจัดการบทบาทและความสามารถที่เฉพาะเจาะจงเช่นกัน คุณสามารถล็อคการเข้าถึงภาพใน Media Library ได้เฉพาะกับภาพที่อัพโหลดโดยผู้ใช้แต่ละคน ฉันใช้มันสำหรับโครงการที่ฉันทำงานอยู่ในขณะนี้และใช้งานได้ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.