terrymatula
  • 0
Новичок

Разрешить пользователям просматривать только те элементы медиатеки, которые они загрузили?

  • 0

Я хочу, чтобы пользователи могли загружать фотографии с помощью 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);
Share
  1. Если вы нашли ответ на свою проблему, вам лучше добавить его как ответ ниже, а не в самом вопросе. Это лучше соответствует системе, и мы можем проголосовать за ваш ответ, что улучшит вашу репутацию на этом сайте.

    • 0
  2. Вы всегда можете отфильтровать список медиа, используя 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;
    }
    

    Я использовал ограничение на удаление страниц в качестве условия, чтобы администраторы и редакторы по-прежнему видели полный список медиафайлов.

    Есть один небольшой побочный эффект, для которого я не вижу никаких зацепок, и это связано с количеством вложений, показанным над списком мультимедиа (который по-прежнему будет показывать общее количество элементов мультимедиа, а не для данного пользователя — я бы считайте это незначительной проблемой, хотя).

    Решил все же выложить, может пригодится.. 😉

    • 0
  3. Начиная с 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;
    }
    
    • 0
  4. Вот полное решение как для постов, так и для медиа (этот код предназначен специально для авторов, но вы можете изменить его для любой роли пользователя). Это также исправляет количество постов/медиафайлов без взлома основных файлов.

    // 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;
    }
    
    • 0
  5. Это модифицированная версия принятого ответа. Поскольку принятый ответ нацелен только на элемент меню «Медиа» слева, пользователи по-прежнему могут видеть всю медиатеку в модальном окне при загрузке фотографии в сообщение. Этот слегка измененный код исправляет эту ситуацию. Целевые пользователи будут видеть только свои собственные элементы мультимедиа на вкладке «Библиотека мультимедиа» модального окна, которое появляется в сообщении.

    Это код из принятого ответа с комментарием, помечающим строку для редактирования…

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

    Чтобы пользователи могли просматривать только свои собственные медиафайлы из меню «Медиа» И на вкладке «Медиатека» модального окна загрузки, замените указанную строку на эту…

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

    ( разрывы строк и интервалы вставлены здесь только для удобочитаемости )

    Примечания : как и в принятом ответе, счетчики сообщений и медиа будут неправильными. Однако в некоторых других ответах на этой странице есть решения для этого. Я не включал их просто потому, что не тестировал их.

    • 0
  6. Полный рабочий код. Единственная проблема заключается в неправильном количестве изображений в медиатеке на странице «Добавить сообщение».

    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' );
    
    • 0
  7. У 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');
    

    Это работает для меня!

    • 0
  8. Я решил свою проблему довольно грубым, но работоспособным решением.

    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% людей даже не узнают об этом, но это все равно не оптимально. Во-вторых, он также перенаправляет администратора на страницу профиля после загрузки. Их можно довольно просто исправить, проверив роли пользователей и перенаправив только подписчиков.

    Если у кого-то есть идеи о том, как подключиться к странице Media, не заходя в основные файлы, я был бы признателен. Спасибо!

    • 0
  9. <?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 и активируйте его, вот и все.

    • 0
  10. Один из способов сделать это — использовать плагин Role Scoper, он также отлично подходит для управления очень специфическими ролями и возможностями. Фактически вы можете заблокировать доступ к изображениям в медиатеке только для тех, которые загружены каждым пользователем. Я использовал его для проекта, над которым я работаю в данный момент, и он работает хорошо.

    • 0

Оставить ответ

You must login to add an answer.