Получите $ image_id после загрузки с помощью media_sideload_image ()

10

Я хочу загрузить изображение и установить его в качестве избранного изображения в сообщении. Что я попробовал, так это:

$image_id = media_sideload_image($image_url, $post_id, $post_id);
update_post_meta($post_id, '_thumbnail_id', $image_id);

Но media_sideload_image()не возвращает image_id, а рендер HTML-изображения. Как я могу получить image_id?

Xavin
источник

Ответы:

28

Вот пример того, как обойти это ограничение, используя action / hooks:

function new_attachment( $att_id ){
    // the post this was sideloaded into is the attachments parent!

    // fetch the attachment post
    $att = get_post( $att_id );

    // grab it's parent
    $post_id = $att->post_parent;

    // set the featured post
    set_post_thumbnail( $post_id, $att_id );
}

// add the function above to catch the attachments creation
add_action('add_attachment','new_attachment');

// load the attachment from the URL
media_sideload_image($image_url, $post_id, $post_id);

// we have the image now, and the function above will have fired too setting the thumbnail ID in the process, so lets remove the hook so we don't cause any more trouble 
remove_action('add_attachment','new_attachment');

Идея в том, что когда media_sideload_imageзапускается, это:

  • загружает изображение
  • добавляет его в качестве вложения (пост типа attachment)
  • затем прикрепляет это вложение к сообщению, чей ID вы указали ($ post_id)

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

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

Том Дж Новелл
источник
1
Brilliant! Это очень помогло.
м-торин
2
Если это отвечает на ваш вопрос, можете ли вы пометить его как правильный?
Том Дж. Новелл
Я не могу прочитать ваш английский. Кто-то может редактировать этот пост?
HiDd3N
2
@ HiDd3N Я упростила некоторые используемые английские слова, в них должно быть больше общих слов с более низким возрастом чтения
Том Дж. Новелл
6

Я построил функцию для получения идентификатора из БД, поиск по URL.

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

Вы можете получить URL (вставленный из HTML-кода) с четвертым параметром, установленным в 'src' Codex: media_sideload_image ()

$src = media_sideload_image($url, $item_id, $desc,'src');
get_attachment_id_from_src($src);
yondemon
источник
4

@ Tom J Nowell ответ на месте. Я нашел другую альтернативу (с использованием различных функций), объясненную здесь, но мне она нравится больше.

В моем случае у меня есть массив $ posts со всеми публикациями, которые я хочу вставить, и отдельный $ media (те же ключи $ nid, что и $ posts) со СМИ. Мой код такой же, как и у Тома, но с использованием анонимной функции:

foreach( $posts as $nid=>$post )
    $posts[$nid]['ID'] = wp_insert_post( $post );

foreach( $posts as $nid=>$post )
    foreach( $media[$nid] as $m=>$mitem ) {

        if( 0 == $m ) add_action( 'add_attachment',
            function( $att_id ) use ($posts, $nid, $mitem) {
                update_post_meta($posts[$nid]['ID'], '_thumbnail_id', $att_id);
                $posts[$nid]['media_urls'][] = $mitem['url'];
            }
        );
        media_sideload_image($mitem['url'], $post['ID']);
        remove_all_actions( 'add_attachment' );
    }

В моем случае я предполагаю, что 1-й элемент в каждом $ media [$ nid] должен быть изображением своего поста.

WordPress обязательно должен изменить media_sideload_image (), чтобы он возвращал $ id. Фактически у функции есть это под рукой, см. Источник здесь . На самом деле для этого есть путевой билет, и у них даже есть патчи, чтобы применить его к вашему ядру, если хотите.

Хорхе Орпинель
источник
Похоже, что это будет исправлено в 4.8
Том Ожер
3

Я искал решение и решил взглянуть на код, media_sideload_image()который был очень простым. Он использует, media_handle_sideload()что дает нам привязанность id.

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

function media_sideload_image_custom($file, $post_id, $desc = null, $file_name = null)
{
    if ( ! empty($file) ) {
        // Download file to temp location
        $tmp = download_url( $file );

        // fix file filename for query strings
        if( empty($file_name) ) { 
            preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $file, $matches);
            $file_array['name'] = basename($matches[0]);
        } else {
            $file_array['name'] = sanitize_file_name($file_name);
        }
        $file_array['tmp_name'] = $tmp;

        // If error storing temporarily, unlink
        if ( is_wp_error( $tmp ) ) {
            @unlink($file_array['tmp_name']);
            $file_array['tmp_name'] = '';
        }

        // do the validation and storage stuff
        $id = media_handle_sideload( $file_array, $post_id, $desc );

        // If error storing permanently, unlink
        if ( is_wp_error($id) ) {
            @unlink($file_array['tmp_name']);
        }
        return $id;
    }
    return null;
}
Дарио Задро
источник