Hạn chế người dùng chỉ xem các mục thư viện phương tiện mà họ đã tải lên?


46

Tôi muốn người dùng có thể tải lên ảnh bằng cách sử dụng add_cap('upload_files')nhưng trong trang hồ sơ của họ, Thư viện phương tiện hiển thị mọi hình ảnh được tải lên. Làm cách nào tôi có thể lọc để họ chỉ có thể xem hình ảnh họ đã tải lên?

Đây là giải pháp của tôi cho thời điểm hiện tại Tôi đang thực hiện một truy vấn WP đơn giản, sau đó là một vòng lặp trên trang "Hồ sơ" của người dùng

$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
Nếu bạn tìm thấy câu trả lời cho vấn đề của riêng mình, tốt nhất bạn nên thêm nó dưới dạng câu trả lời bên dưới, chứ không phải trong chính câu hỏi. Điều này tốt hơn phù hợp với hệ thống và chúng tôi có thể bỏ phiếu cho câu trả lời của bạn, điều này sẽ cải thiện danh tiếng của bạn trên trang web này.
Jan Fabry


Tôi thực sự phải sử dụng plugin 'Xem riêng bài viết phương tiện truyền thông', nó hoạt động hoàn hảo với tôi sau khi tìm kiếm mọi giải pháp jquery hoặc php / html / css.
waffl

Câu trả lời:


37

Bạn luôn có thể lọc danh sách phương tiện bằng pre_get_postsbộ lọc xác định trang đầu tiên và khả năng của người dùng và đặt tham số tác giả khi đáp ứng một số điều kiện nhất định.

Thí dụ

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

Tôi đã sử dụng giới hạn xóa trang như một điều kiện để Quản trị viên và Biên tập viên vẫn thấy danh sách phương tiện đầy đủ.

Có một hiệu ứng phụ nhỏ mà tôi không thể thấy bất kỳ móc nối nào, và đó là với số lượng tệp đính kèm được hiển thị phía trên danh sách phương tiện (sẽ vẫn hiển thị tổng số mục phương tiện, không phải của người dùng cụ thể - tôi sẽ coi đây là một vấn đề nhỏ)

Nghĩ rằng tôi sẽ đăng nó lên như vậy, có thể hữu ích ..;)


Tôi đã cho phép tải lên tập tin cho người dùng cấp thuê bao. đã cố gắng sử dụng mã của bạn nhưng không hoạt động.
Sisir

1
"Không làm việc" không phải là nhiều để tiếp tục.
t31os

Tôi có thể xác nhận quan sát tương tự. Đối với tôi "không hoạt động" có nghĩa là vai trò "người đóng góp" vẫn có thể thấy tất cả các mục phương tiện khi anh ấy tải lên một jpg. Tuy nhiên, khi anh ta đến thư viện phương tiện từ menu, nó trống rỗng. ( Vai trò "cộng tác viên" của tôi đã có thêm khả năng tải lên các tệp và điều đó đang hoạt động. )
Sparky

Vì vậy, mã của bạn chỉ cần được điều chỉnh cho bất kỳ trang nào điền vào tab "Thư viện phương tiện" của cửa sổ tải lên. Tôi đang nghiên cứu điều này bây giờ.
Sparky

Nếu tôi nhớ lại một cách chính xác (và sai lầm xảy ra), không có bất kỳ móc thích hợp nào được đưa ra tại thời điểm viết câu trả lời này, tương tự như cách không có móc nối nào để sửa số lượng phương tiện. Tuy nhiên, đã có 3 phiên bản mới của WordPress kể từ thời điểm viết bài, vì vậy giờ đây các giải pháp có thể khả thi.
t31os

32

Kể từ WP 3.7, có một cách tốt hơn nhiều thông qua ajax_query_attachments_argsbộ lọc, như được cung cấp trong tài liệu :

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

Đây là một giải pháp hoàn chỉnh cho cả bài đăng và phương tiện (mã này dành riêng cho tác giả, nhưng bạn có thể thay đổi nó cho bất kỳ vai trò người dùng nào). Điều này cũng sửa lỗi số lượng bài / phương tiện mà không hack các tập tin cốt lõi.

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

đoạn trích tuyệt vời nhưng nếu không có mục nào trong thư viện phương tiện, nó sẽ phát sinh lỗi, Cảnh báo: Array_sum () dự kiến ​​tham số 1 là mảng, null được đưa ra và Cảnh báo: Array_keys () dự kiến ​​tham số 1 sẽ là mảng, null được đưa ra
chrismccoy

Bạn chỉ cần định nghĩa $ _num_posts là một mảng trong hàm fix_media_counts (). $_num_posts = array();
Paul

4
Mã trong câu trả lời này hoạt động nhưng nó cũng loại bỏ bất kỳ trường tùy chỉnh nào được tạo bởi plugin Trường tùy chỉnh nâng cao.
Sparky


5

Đây là một phiên bản sửa đổi của câu trả lời được chấp nhận . Vì câu trả lời được chấp nhận chỉ nhắm mục tiêu mục menu Media ở bên trái, người dùng vẫn có thể thấy toàn bộ thư viện phương tiện trong hộp phương thức khi tải ảnh lên bài đăng. Mã sửa đổi một chút này khắc phục tình trạng đó. Người dùng được nhắm mục tiêu sẽ chỉ nhìn thấy các mục phương tiện của riêng họ từ tab Thư viện phương tiện của hộp phương thức bật lên trong một bài đăng.

Đây là mã từ câu trả lời được chấp nhận với một bình luận đánh dấu dòng để chỉnh sửa ...

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

Để người dùng chỉ xem phương tiện của riêng họ từ menu Media VÀ tab Thư viện phương tiện của phương thức tải lên, thay thế dòng được chỉ định bằng ...

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

( ngắt dòng & khoảng cách chỉ được chèn để dễ đọc tại đây )

Dưới đây là giống như trên nhưng cũng hạn chế họ nhìn thấy bài viết của riêng họ từ mục menu Bài viết.

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

( ngắt dòng & khoảng cách chỉ được chèn để dễ đọc tại đây )

Lưu ý : như trong câu trả lời được chấp nhận, các bài đăng và quầy truyền thông sẽ sai. Tuy nhiên, có những giải pháp cho điều này trong một số câu trả lời khác trên trang này. Tôi đã không kết hợp những thứ đó đơn giản chỉ vì tôi đã không thử nghiệm chúng.


2

Hoàn thành mã làm việc .. Chỉ có vấn đề là, nhận sai số lượng hình ảnh trong thư viện phương tiện trên trang Thêm bài.

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
Bạn không nên sử dụng cấp độ người dùng, chúng vẫn ở WordPress chủ yếu để tương thích ngược (trước WP 2.0), chúng không đáng tin cậy để xác định khả năng của người dùng trong WordPress hiện đại (vì chúng có thể sẽ biến mất khỏi lõi khi không còn khả năng tương thích ). Sử dụng một khả năng thực tế để xác định quyền người dùng.
t31os

Mặc dù có chứa media-upload.php , mã của bạn không hoạt động từ phương thức tải lên được tạo bởi trang Chỉnh sửa bài. Vẫn có thể xem tất cả các mục thư viện.
Sparky

2

T31os có một giải pháp tuyệt vời trên đó. Điều duy nhất là số lượng của tất cả các bài viết vẫn hiển thị.

Tôi đã tìm ra một cách để giữ cho số đếm không hiển thị bằng jQuery.

Chỉ cần thêm nó vào tập tin chức năng của bạn.

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

Nó làm việc cho tôi!


1

Tôi đã giải quyết vấn đề của mình bằng một giải pháp khá thô, nhưng hoàn toàn khả thi.

1) Tôi đã cài đặt plugin WP Hide Dashboard, vì vậy Người dùng sẽ chỉ thấy một liên kết đến biểu mẫu chỉnh sửa hồ sơ của họ.

2) Trong tệp mẫu Author.php, tôi đã chèn mã tôi đã sử dụng ở trên.

3) Sau đó, đối với người dùng đã đăng nhập, tôi đã hiển thị một liên kết trực tiếp đến trang Tải lên "wp-admin / media-new.php"

4) Vấn đề tiếp theo tôi nhận thấy, là sau khi họ tải ảnh lên, nó sẽ chuyển hướng họ đến upload.php ... và họ có thể thấy tất cả các hình ảnh khác. Tôi đã không tìm thấy một cái móc vào trang media-new.php, vì vậy cuối cùng tôi đã hack vào "media-upload.php" cốt lõi và chuyển hướng chúng đến trang hồ sơ của họ:

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

Sau đó thay thế wp_redirect( admin_url($location) );bằngwp_redirect($userredirect);

Một vài vấn đề, mặc dù. Đầu tiên, người dùng đã đăng nhập vẫn có thể truy cập "upload.php", nếu họ biết nó tồn tại. Họ không thể làm bất cứ điều gì ngoại trừ LOOK tại các tệp và 99% mọi người thậm chí sẽ không biết về nó, nhưng nó vẫn không tối ưu. Thứ hai, nó cũng chuyển hướng Quản trị viên đến trang hồ sơ sau khi tải lên. Đây có thể có một sửa chữa khá đơn giản bằng cách kiểm tra vai trò của người dùng và chỉ chuyển hướng Người đăng ký.

Nếu bất cứ ai có ý tưởng về việc nối vào trang Media mà không đi vào các tệp cốt lõi, tôi sẽ đánh giá cao nó. Cảm ơn!


2
Có một admin_initcái móc chạy trên mọi yêu cầu quản trị. Trong trường hợp người dùng yêu cầu upload.php và bạn muốn ngăn chặn rằng bạn có thể chặn yêu cầu đó (ví dụ wp_die('Access Denied')) hoặc chuyển hướng đến một số vị trí hợp lệ trên mỗi 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' );
?>

Lưu mã ở trên dưới dạng Manage_your_media_only.php, nén mã, tải lên dưới dạng plugin vào WP của bạn và kích hoạt nó, chỉ vậy thôi.


1

Một cách để làm điều này là sử dụng plugin Role Scoper , nó cũng rất tuyệt để quản lý các vai trò và khả năng rất cụ thể. Bạn thực sự có thể khóa quyền truy cập vào hình ảnh trong Thư viện phương tiện để chỉ những người được tải lên bởi mỗi người dùng. Tôi đã sử dụng nó cho một dự án mà tôi đang làm việc tại thời điểm này và nó hoạt động tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.