Как установить изображение записи (миниатюру) по URL изображения при использовании wp_insert_post()?

26 янв. 2012 г., 23:56:46
Просмотры: 139K
Голосов: 71

Просматривая справочник функций для wp_insert_post(), я заметил, что в массиве параметров нет опции, которая позволила бы установить 'Изображение записи', отображаемое как миниатюра записи в моей теме.

Я изучил такие функции как set_post_thumbnail(), как предложил Mr. Bennett, но это относительно новое дополнение к WordPress и документации WordPress. Поэтому я не могу найти источники, которые объясняют, как получить и передать параметр $thumbnail_id. Если это действительно та функция, которую нужно использовать, каким образом я могу предоставить ей корректный параметр $thumbnail_id, когда у меня есть только URL изображения?

Заранее спасибо!

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

Вы можете установить изображение в качестве миниатюры записи (поста), если оно находится в вашей медиатеке. Чтобы добавить изображение в медиатеку, вам нужно загрузить его на сервер. WordPress уже имеет функцию для добавления изображений в медиатеку, вам нужен только скрипт для загрузки файла.

Использование:

Generate_Featured_Image( '../wp-content/my_image.jpg', $post_id );

// $post_id - это числовой ID... Вы также можете получить ID с помощью:
wp_insert_post()

Функция:

function Generate_Featured_Image( $image_url, $post_id  ){
    $upload_dir = wp_upload_dir();
    $image_data = file_get_contents($image_url);
    $filename = basename($image_url);
    if(wp_mkdir_p($upload_dir['path']))
      $file = $upload_dir['path'] . '/' . $filename;
    else
      $file = $upload_dir['basedir'] . '/' . $filename;
    file_put_contents($file, $image_data);

    $wp_filetype = wp_check_filetype($filename, null );
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => sanitize_file_name($filename),
        'post_content' => '',
        'post_status' => 'inherit'
    );
    $attach_id = wp_insert_attachment( $attachment, $file, $post_id );
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
    $res1= wp_update_attachment_metadata( $attach_id, $attach_data );
    $res2= set_post_thumbnail( $post_id, $attach_id );
}

http://codex.wordpress.org/Function_Reference/wp_upload_dir

http://codex.wordpress.org/Function_Reference/wp_insert_attachment


ИЗМЕНЕНИЕ: Добавлено создание пути

http://codex.wordpress.org/Function_Reference/wp_mkdir_p

6 февр. 2012 г. 00:07:36
Комментарии

Спасибо за ваши усилия! Это работает только при использовании $upload_dir['basedir'] (а не path), потому что когда я проверяю вложение через интерфейс редактирования записи, оно ссылается на .../uploads/ИМЯ_ФАЙЛА.РАСШИРЕНИЕ, тогда как $upload_dir['path'] сохранил бы его в что-то вроде .../uploads/2012/02/ИМЯ_ФАЙЛА.РАСШИРЕНИЕ.

Возможно, было бы еще лучше как-то изменить способ ссылки на файл, но я не знаю как.

Chris Chris
6 февр. 2012 г. 20:02:03

Добавил создание пути в своем ответе.

Rob Vermeer Rob Vermeer
6 февр. 2012 г. 20:47:16

Ценю ваш быстрый ответ :). Однако я все равно получаю тот же результат, вот скриншот, демонстрирующий мою проблему: http://i.imgur.com/iKTNs.png. Верхняя секция - результат размещения echo в вашем условии, просто чтобы посмотреть, что происходит.

Chris Chris
6 февр. 2012 г. 22:17:22

Снова изменил, не передавал полный путь в wp_insert_attachment и wp_generate_attachment_metadata. Надеюсь, это решит проблему.

Rob Vermeer Rob Vermeer
6 февр. 2012 г. 22:28:38

Работает безупречно, огромное спасибо! Это также исправило проблему с размерами, которая, по-видимому, была вызвана некорректными путями (хотя изображение и отображалось). Лучше и быть не может!

Chris Chris
6 февр. 2012 г. 22:56:26

Спасибо за ваш отличный код. Потребовалась всего одна правка, чтобы заставить его работать с моим CSV-импортом — добавление ID поста к имени файла, чтобы гарантировать уникальность файлов изображений.

Dave Hilditch Dave Hilditch
7 дек. 2012 г. 19:46:25

Позвольте и мне присоединиться к похвалам. Обожаю этот фрагмент кода. Спасибо, что сэкономили мне часы!

bkwdesign bkwdesign
11 февр. 2013 г. 04:47:47

Просто интересно: это безопасно? Есть ли риск, что кто-то замаскирует изображение, или функция wp_check_filetype() позаботится об этом?

LOLapalooza LOLapalooza
14 февр. 2015 г. 06:20:56

Я использовал приведенный выше код и немного изменил его, чтобы получать изображения записи, названные как slug поста (что довольно трудоемко, если у вас тысячи записей): code <?php $slug = basename(get_permalink());
$featuredimageurl = '[ВАШ ПУТЬ]/wp-content/uploads/featuredimages/' . $slug . '.png'; Generate_Featured_Image( $featuredimageurl, $post_id ); ?>

Traveler Traveler
19 янв. 2017 г. 10:45:49

использование file_get_contents с URL не будет работать, если allow_url_fopen отключен в php.ini - wp_remote_get будет более совместимым в разных средах WordPress

highvolt highvolt
24 февр. 2017 г. 16:39:44

Предупреждение: Этот ответ перезаписывает файл, если у него такое же имя, будьте осторожны. Следует генерировать имена с использованием $post_id или хотя бы uniqid()

Ivan Castellanos Ivan Castellanos
1 июн. 2017 г. 00:59:37

Когда я использую этот код, создаваемые изображения в папке "uploads" имеют нулевой размер файла.

Jay Brunet Jay Brunet
23 мар. 2018 г. 02:57:04

Для URL-адресов, содержащих пробелы, используйте следующий код для $image_data: $image_data = file_get_contents(str_replace(' ', '%20', $image_url));

user45288 user45288
8 дек. 2020 г. 05:39:50
Показать остальные 8 комментариев
4
23

Я хочу улучшить ответ Rob, используя основные функции WordPress download_url и media_handle_sideload

<?php
/**
* Загружает изображение по указанному URL и прикрепляет его к записи в качестве миниатюры.
*
* @param string $file    URL изображения для загрузки.
* @param int    $post_id ID записи, к которой будет прикреплено изображение.
* @param string $desc    Опционально. Описание изображения.
* @return string|WP_Error ID вложения или объект WP_Error в случае ошибки.
*/
function Generate_Featured_Image( $file, $post_id, $desc ){
    // Устанавливаем переменные для хранения, исправляем имя файла для строк запроса.
    preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
    if ( ! $matches ) {
         return new WP_Error( 'image_sideload_failed', __( 'Неверный URL изображения' ) );
    }

    $file_array = array();
    $file_array['name'] = basename( $matches[0] );

    // Загружаем файл во временное местоположение.
    $file_array['tmp_name'] = download_url( $file );

    // Если произошла ошибка при временном сохранении, возвращаем ошибку.
    if ( is_wp_error( $file_array['tmp_name'] ) ) {
        return $file_array['tmp_name'];
    }

    // Выполняем проверку и сохранение.
    $id = media_handle_sideload( $file_array, $post_id, $desc );

    // Если произошла ошибка при постоянном сохранении, удаляем временный файл.
    if ( is_wp_error( $id ) ) {
        @unlink( $file_array['tmp_name'] );
        return $id;
    }
    return set_post_thumbnail( $post_id, $id );

}
2 мар. 2016 г. 09:23:22
Комментарии

Использование нативных функций WordPress является лучшей практикой. Спасибо.

Mostafa Soufi Mostafa Soufi
15 сент. 2018 г. 18:39:56

По какой-то причине эта версия выдавала мне ошибки с сообщением "Не предоставлен действительный URL", в то время как ответ Роба Вермеера сработал.

Flimm Flimm
28 авг. 2019 г. 20:09:19

Могу подтвердить, что модифицированный код не работает, что очень жаль, так как загрузка по URL была бы отличной возможностью!

Zach Nicodemous Zach Nicodemous
10 нояб. 2020 г. 01:16:01

Этот код отлично работает для меня, несмотря на то, что у меня были проблемы с оригинальным ответом.

Jsilvermist Jsilvermist
19 нояб. 2020 г. 00:47:39
5
10

Попробуйте использовать функцию set_post_thumbnail().

Редакция от Otto: Вы уточнили свой вопрос, поэтому я уточню ответ, который дал Chip.

По сути, вам также нужно создать 'вложение' (attachment) для записи. Когда изображение загружается в медиабиблиотеку WordPress, для него создается специальная запись с типом post_type 'attachment'. Это вложение связано с определенной записью через идентификатор post_parent.

Так что, если вам известен ID вложения, то вызов set_post_thumbnail с объектом записи или его ID и ID вложения просто установит флаг миниатюры записи.

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

Просто загруженный и прикрепленный к записи файл сам по себе ничего не делает. Это просто механизм категоризации. Например, механизм галереи использует прикрепленные изображения записи для построения [gallery] для этой записи. Миниатюра записи — это одно из прикрепленных изображений, которое было установлено в качестве миниатюры.

Подробнее о том, как использовать wp_insert_attachment, можно узнать в Кодексе (ссылка выше).

27 янв. 2012 г. 00:08:09
Комментарии

Спасибо за ответ! Но как мне получить ID миниатюры? Я начинаю с URL изображения, поэтому, наверное, мне нужно сначала добавить изображение в медиатеку WordPress с помощью другой функции?

Chris Chris
27 янв. 2012 г. 19:44:57

Раз уж вы уже вставляете запись, я предположил, что вы уже прикрепляете изображения к этой записи. Разве это неверное предположение?

Chip Bennett Chip Bennett
27 янв. 2012 г. 20:15:28

Извините, но я пока не разобрался, как именно прикреплять изображения к записи по URL. Кроме того, мне не нужно, чтобы изображение фактически отображалось в самой записи. Сейчас я ищу функцию, которая вернет $thumbnail_id, и думал, что может подойдет wp_insert_attachment(), пока не заметил, что она требует, чтобы вложение уже было в директории загрузок. Я не знаю, как загрузить файл изображения туда по его URL, и не уверен, что это вообще та функция, которая мне нужна. Спасибо за помощь!

Chris Chris
27 янв. 2012 г. 22:59:37

Не могли бы вы переформулировать ваш вопрос с учетом этой информации, чтобы точнее описать, чего вы пытаетесь достичь? (Или оставьте этот вопрос как есть и создайте новый, чтобы спросить, как получить ID вложения при добавлении записи?)

Chip Bennett Chip Bennett
27 янв. 2012 г. 23:03:35

Исходный вопрос был отредактирован и частично перефразирован, пожалуйста, проверьте :).

Chris Chris
27 янв. 2012 г. 23:38:45
0

Только что нашел это и сделал намного проще, работает, но я не специалист по безопасности

if(!empty($_FILES)){
    require_once( ABSPATH . 'wp-admin/includes/post.php' );
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    require_once( ABSPATH . 'wp-admin/includes/media.php' );

    $post_ID = "ваш ID записи!";

    $attachment_id = media_handle_upload( 'file', $post_ID );
    set_post_thumbnail( $post_ID, $attachment_id );
}

Просто или как? После подключения нужных файлов WordPress сам обработает медиафайл, загрузит его и установит как миниатюру.

21 февр. 2015 г. 01:45:56
0

set_post_thumbnail() — это лучшая функция для данной задачи.

Думаю, вы можете найти ID вложения с помощью get_children() или get_posts(). Результат представляет собой массив, внутри которого находится ID. Вот пример для тестирования; я надеюсь, он сработает; написан без тестов, набросок.

Для вашей задачи важно заменить get_the_ID() на ваш post-ID; функция возвращает ID вложения, который можно использовать в set_post_thumbnail().

$attachments = get_children( 
    array(
        'post_parent' => get_the_ID(), 
        'post_type' => 'attachment', 
        'post_mime_type' => 'image'
    )
);
foreach ( $attachments as $attachment_id => $attachment ) {
    echo wp_get_attachment_image($attachment_id);
}
6 февр. 2012 г. 17:14:25
0

Вам потребуются основные библиотеки, чтобы упростить задачу.

function attach_image_from_url_to_post($image_url, $post_id) {
    // Проверяем, существует ли функция (она находится в media.php)
    if (!function_exists('media_sideload_image')) {
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');
    }

    // Загружаем и добавляем изображение
    $image = media_sideload_image($image_url, $post_id, null, 'id');

    // Если произошла ошибка, возвращаем её
    if (is_wp_error($image)) {
        return $image;
    }

    // Устанавливаем изображение как миниатюру записи
    set_post_thumbnail($post_id, $image);

    return true;
}
15 мар. 2025 г. 23:00:39