Как установить изображение записи (миниатюру) по URL изображения при использовании wp_insert_post()?
Просматривая справочник функций для wp_insert_post(), я заметил, что в массиве параметров нет опции, которая позволила бы установить 'Изображение записи', отображаемое как миниатюра записи в моей теме.
Я изучил такие функции как set_post_thumbnail(), как предложил Mr. Bennett, но это относительно новое дополнение к WordPress и документации WordPress. Поэтому я не могу найти источники, которые объясняют, как получить и передать параметр $thumbnail_id. Если это действительно та функция, которую нужно использовать, каким образом я могу предоставить ей корректный параметр $thumbnail_id, когда у меня есть только URL изображения?
Заранее спасибо!
Вы можете установить изображение в качестве миниатюры записи (поста), если оно находится в вашей медиатеке. Чтобы добавить изображение в медиатеку, вам нужно загрузить его на сервер. 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
ИЗМЕНЕНИЕ: Добавлено создание пути
Спасибо за ваши усилия! Это работает только при использовании $upload_dir['basedir'] (а не path), потому что когда я проверяю вложение через интерфейс редактирования записи, оно ссылается на .../uploads/ИМЯ_ФАЙЛА.РАСШИРЕНИЕ, тогда как $upload_dir['path'] сохранил бы его в что-то вроде .../uploads/2012/02/ИМЯ_ФАЙЛА.РАСШИРЕНИЕ.
Возможно, было бы еще лучше как-то изменить способ ссылки на файл, но я не знаю как.
Chris
Ценю ваш быстрый ответ :). Однако я все равно получаю тот же результат, вот скриншот, демонстрирующий мою проблему: http://i.imgur.com/iKTNs.png. Верхняя секция - результат размещения echo в вашем условии, просто чтобы посмотреть, что происходит.
Chris
Снова изменил, не передавал полный путь в wp_insert_attachment и wp_generate_attachment_metadata. Надеюсь, это решит проблему.
Rob Vermeer
Работает безупречно, огромное спасибо! Это также исправило проблему с размерами, которая, по-видимому, была вызвана некорректными путями (хотя изображение и отображалось). Лучше и быть не может!
Chris
Спасибо за ваш отличный код. Потребовалась всего одна правка, чтобы заставить его работать с моим CSV-импортом — добавление ID поста к имени файла, чтобы гарантировать уникальность файлов изображений.
Dave Hilditch
Позвольте и мне присоединиться к похвалам. Обожаю этот фрагмент кода. Спасибо, что сэкономили мне часы!
bkwdesign
Просто интересно: это безопасно? Есть ли риск, что кто-то замаскирует изображение, или функция wp_check_filetype() позаботится об этом?
LOLapalooza
Я использовал приведенный выше код и немного изменил его, чтобы получать изображения записи, названные как slug поста (что довольно трудоемко, если у вас тысячи записей):
code
<?php
$slug = basename(get_permalink());
$featuredimageurl = '[ВАШ ПУТЬ]/wp-content/uploads/featuredimages/' . $slug . '.png';
Generate_Featured_Image( $featuredimageurl, $post_id );
?>
Traveler
использование file_get_contents с URL не будет работать, если allow_url_fopen отключен в php.ini - wp_remote_get будет более совместимым в разных средах WordPress
highvolt
Предупреждение: Этот ответ перезаписывает файл, если у него такое же имя, будьте осторожны. Следует генерировать имена с использованием $post_id или хотя бы uniqid()
Ivan Castellanos
Когда я использую этот код, создаваемые изображения в папке "uploads" имеют нулевой размер файла.
Jay Brunet
Я хочу улучшить ответ 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 );
}
Использование нативных функций WordPress является лучшей практикой. Спасибо.
Mostafa Soufi
По какой-то причине эта версия выдавала мне ошибки с сообщением "Не предоставлен действительный URL", в то время как ответ Роба Вермеера сработал.
Flimm
Могу подтвердить, что модифицированный код не работает, что очень жаль, так как загрузка по URL была бы отличной возможностью!
Zach Nicodemous
Попробуйте использовать функцию 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, можно узнать в Кодексе (ссылка выше).
Спасибо за ответ! Но как мне получить ID миниатюры? Я начинаю с URL изображения, поэтому, наверное, мне нужно сначала добавить изображение в медиатеку WordPress с помощью другой функции?
Chris
Раз уж вы уже вставляете запись, я предположил, что вы уже прикрепляете изображения к этой записи. Разве это неверное предположение?
Chip Bennett
Извините, но я пока не разобрался, как именно прикреплять изображения к записи по URL. Кроме того, мне не нужно, чтобы изображение фактически отображалось в самой записи. Сейчас я ищу функцию, которая вернет $thumbnail_id, и думал, что может подойдет wp_insert_attachment(), пока не заметил, что она требует, чтобы вложение уже было в директории загрузок. Я не знаю, как загрузить файл изображения туда по его URL, и не уверен, что это вообще та функция, которая мне нужна. Спасибо за помощь!
Chris
Не могли бы вы переформулировать ваш вопрос с учетом этой информации, чтобы точнее описать, чего вы пытаетесь достичь? (Или оставьте этот вопрос как есть и создайте новый, чтобы спросить, как получить ID вложения при добавлении записи?)
Chip Bennett
Только что нашел это и сделал намного проще, работает, но я не специалист по безопасности
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 сам обработает медиафайл, загрузит его и установит как миниатюру.
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);
}
Вам потребуются основные библиотеки, чтобы упростить задачу.
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;
}