Добавление изображения в медиатеку из URL в директории uploads

6 сент. 2012 г., 04:05:09
Просмотры: 16.8K
Голосов: 2

Плагин "Video Embed & Thumbnail Generator" отлично генерирует миниатюры из видео. Он сохраняет URL миниатюры как метаданные вложения. Миниатюра добавляется в директорию uploads. Есть ли способ добавить это изображение в медиатеку, чтобы я мог пропустить его через функцию image_downsize для создания миниатюры другого размера?

Функция wp_insert_attachment, похоже, требует путь к файлу, а не URL, или я ошибаюсь? Как я могу добавить URL в медиатеку?

Возможно, это дубликат вопроса Как получить изображение из директории uploads и добавить его в медиатеку?, но на него не было получено ответов.

0
Все ответы на вопрос 2
6

Если изображение находится в исходном коде контента, вы можете извлечь его и использовать media_sideload_image(); для импорта в медиатеку.

Этот пример кода взят из моего плагина Media Tools, который выполняет эту операцию через административную страницу с использованием AJAX. Он также устанавливает извлеченное изображение как миниатюру записи. ID записи передается в эту функцию через AJAX. Чтобы увидеть полный код, перейдите по ссылке: http://plugins.trac.wordpress.org/browser/media-tools/trunk/media-tools.php?rev=581988

   function process_image( $post_id ) {
        $response = '';
        $error = 0;
        $post = get_post( $post_id );
        $img = $this->extract_image( $post );
        if( empty( $img ) ) {
            $response .=  'Изображения не найдены <br>';
            die( sprintf( $response . '<br>Инструмент Media Tools завершил работу (ID записи %1$s) за %2$s секунд. Ошибок: %3$d', esc_html( $post->ID ), timer_stop(), $error = $error  > 0 ? $error : 'нет' ) );
         }
        /** @var $file string or WP_Error of image attached to the post  */
        $file = media_sideload_image( $img, (int)$post->ID );
        if ( is_wp_error( $file ) ) {
            $response .= '<span style="color:red">Ошибка загрузки: Не удалось загрузить изображение. Проверьте URL в атрибуте src тега img</span><br>';
            $error++;
        } else {

         $atts = $this->get_attach( $post->ID );
         foreach ( $atts as $a ) {
             $img = set_post_thumbnail( $post->ID, $a['ID'] );
             if ( $img ) {
                  $thumb = wp_get_attachment_thumb_url( $a['ID'] );
                  $response .= '<img src="'.esc_url( $thumb ).'" /><br>';
                  $response .= '<a href="'.wp_nonce_url( get_edit_post_link( $a['ID'], true ) ).'" >'.get_the_title( $a['ID'] ).'</a>  Установлено как миниатюра записи</p><br>';
                        }
                    }
                    unset( $atts );
                    unset( $a );
                }
            die( sprintf( $response.'<br>Инструмент Media Tools завершил работу (ID записи %1$s) за %2$s секунд. Ошибок: %3$d', esc_html( $post->ID ), timer_stop(), $error = $error > 0 ? $error : 'нет' ) );
    }


    /**
     * Извлекает первое изображение из содержимого записи
     * @param object $post объект записи
     * @return bool|string false если изображений нет или src изображения
     */
    function extract_image( $post ) {
        $html = $post->post_content;
        if ( stripos( $html, '<img' ) !== false ) {
            $regex = '#<\s*img [^\>]*src\s*=\s*(["\'])(.*?)\1#im';
            preg_match( $regex, $html, $matches );
            unset( $regex );
            unset( $html );
            if ( is_array( $matches ) && ! empty( $matches ) ) {
                return  $matches[2];

            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * Ищет прикрепленные изображения
     * @param int $post_id ID записи для проверки наличия вложений
     * @return array|bool Первое вложение при успехе или false если вложений нет
     */
    function get_attach( $post_id ) {
        return get_children( array (
                'post_parent'    => $post_id,
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
                'posts_per_page'  => (int)1
            ), ARRAY_A );
    }
6 сент. 2012 г. 06:08:37
Комментарии

Функция media_sideload_image() выглядит перспективно, но как получить ID вложения для загруженного изображения?

helgatheviking helgatheviking
6 сент. 2012 г. 21:41:15

Посмотрите на функцию get_attach. Она выполняется после media_sideload_image.

Chris_O Chris_O
6 сент. 2012 г. 22:00:08

Вы имеете в виду get_attachment? Для неё нужен ID, которого у меня пока нет. Я собираюсь изучить media_handle_sideload()

helgatheviking helgatheviking
6 сент. 2012 г. 22:32:31

также media sideload не совсем подходит, потому что дублирует изображения, которые уже есть в папке wp-uploads (куда их добавляет плагин video embedder)

helgatheviking helgatheviking
6 сент. 2012 г. 22:58:21

На самом деле video embedder должен добавлять их в вашу медиатеку, а не просто сбрасывать в папку uploads.

Chris_O Chris_O
7 сент. 2012 г. 00:11:41

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

helgatheviking helgatheviking
7 сент. 2012 г. 16:25:09
Показать остальные 1 комментариев
4

Вот соответствующие части, которые я изменил в функции kg_video_attachment_fields_to_save(), которая фильтрует attachment_fields_to_save:

    $thumb_url = $attachment['kgflashmediaplayer-poster'];

    //вставляем $thumb_url в медиатеку, если он еще не существует
    if ( ! ($thumb_id = get_attachment_id_from_src( $thumb_url ) ) ) {

        $post_id = $post['ID'];
        $desc = $attachment['post_title'] . ' миниатюра';

        //находится ли изображение в директории загрузок?
        $upload_dir = wp_upload_dir();

        if ( FALSE !== strpos( $url, $upload_dir['baseurl'] ) ) {
            $wp_filetype = wp_check_filetype(basename($thumb_url), null );
            $filename = preg_replace('/\.[^.]+$/', '', basename($thumb_url));

            $attachment = array(
               'guid' => $thumb_url, 
               'post_mime_type' => $wp_filetype['type'],
               'post_title' => $desc,
               'post_content' => '',
               'post_status' => 'inherit'
            );
            $thumb_id = wp_insert_attachment( $attachment, basename($thumb_url), $post_id );
            // сначала необходимо подключить файл image.php
            // для работы функции wp_generate_attachment_metadata()
            require_once(ABSPATH . 'wp-admin/includes/image.php');
            $attach_data = wp_generate_attachment_metadata( $thumb_id, basename($thumb_url) );
            wp_update_attachment_metadata( $thumb_id, $attach_data );
        } else { //не в загрузках, поэтому нужно загрузить через sideload
            $tmp = download_url( $thumb_url );

            // Устанавливаем переменные для хранения
            // исправляем имя файла для query strings
            preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $thumb_url, $matches);
            $file_array['name'] = basename($matches[0]);
            $file_array['tmp_name'] = $tmp;

            // Если ошибка временного хранения, удаляем
            if ( is_wp_error( $tmp ) ) {
                @unlink($file_array['tmp_name']);
                $file_array['tmp_name'] = '';
            }

            // выполняем проверку и загрузку
            $thumb_id = media_handle_sideload( $file_array, $post_id, $desc );

            // Если ошибка постоянного хранения, удаляем
            if ( is_wp_error($thumb_id) ) {
                @unlink($file_array['tmp_name']);
                return $thumb_id;
            }

            if ( $local_src = wp_get_attachment_url( $thumb_id ) ) {
                update_post_meta($post['ID'], '_kgflashmediaplayer-poster', $local_src);
            }

        } //конец sideload

    } //конец get_attachment_id_from_src

    if(!is_wp_error($thumb_id)) {
        $thumb_id = intval( $thumb_id );
        update_post_meta($post['ID'], '_kgflashmediaplayer-poster-id', $thumb_id);
    } 

Теперь ID пользовательской миниатюры видео хранится в метаполе: _kgflashmediaplayer-poster-id

function get_attachment_id_from_src ($image_src) {
    global $wpdb;

    $query = "SELECT ID FROM {$wpdb->posts} WHERE guid='$image_src'";
    $id = $wpdb->get_var($query);
    return $id;

}

Мне не очень нравится функция get_attachment_id_from_src(), но встроенного способа сделать это нет. Я должен добавить проверку, чтобы если текущий src совпадает со старым, этот запрос не выполнялся. Плагин для встраивания создает множество потенциальных миниатюр для каждого видео, и нет необходимости вставлять их все в медиатеку... Этот код срабатывает при сохранении вложения и должен обрабатывать изображения, которые уже есть в медиатеке, изображения в директории загрузок, но не в медиатеке, и изображения на других серверах (которые загружаются через sideload, и их URL изменяется на локальный).

7 сент. 2012 г. 16:35:50
Комментарии

Отличная функция... потребовалось немного доработок, но отлично сработало для моих нужд ;)

Sagive Sagive
29 сент. 2015 г. 02:22:12

Так как этому уже 3 года, предполагаю, что сейчас есть гораздо лучший способ сделать это.

helgatheviking helgatheviking
29 сент. 2015 г. 12:17:39

все равно сработало для меня - а это все, что мне было нужно ;) - быстрый, готовый к использованию детализированный код. спасибо.

Sagive Sagive
1 окт. 2015 г. 07:55:36

Отличная функция get_attachment_id_from_src, не самая элегантная, но действительно эффективная!

Magico Magico
5 янв. 2017 г. 12:59:18