Uzyskaj $ image_id po przesłaniu za pomocą media_sideload_image ()

10

Chcę załadować obraz i ustawić go jako wyróżniony obraz w poście. Próbowałem tego:

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

Ale media_sideload_image()nie zwraca image_id, ale renderuje obraz HTML. Jak mogę uzyskać image_id?

Xavin
źródło

Odpowiedzi:

28

Oto przykład tego, jak ominąć to ograniczenie za pomocą akcji / haków:

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

Chodzi o to, że po media_sideload_imageuruchomieniu:

  • pobiera obraz
  • dodaje go jako załącznik (post typu attachment)
  • następnie dołącza ten załącznik do posta, którego identyfikator podałeś ($ post_id)

Problem polega na tym, że nie zapewnia on nowo utworzonego identyfikatora wpisów w załączniku.

Ale po utworzeniu załącznika uruchamiana jest akcja zawierająca jego identyfikator. Możemy się do tego przyczepić przed utworzeniem załącznika i zapisać wyróżnioną miniaturę z podanym nam identyfikatorem posta, a następnie odczepić.

Tom J Nowell
źródło
1
Znakomity! To bardzo pomogło.
m-torin
2
Jeśli to odpowiada na twoje pytanie, czy możesz je oznaczyć jako prawidłowe?
Tom J Nowell
Nie mogę przeczytać twojego angielskiego. Czy ktoś może edytować ten post?
HiDd3N,
2
@ HiDd3N Upraszczam niektóre z używanych angielskich, powinny mieć bardziej popularne słowa z niższym wiekiem czytelniczym
Tom J Nowell
6

Zbudowałem funkcję, aby uzyskać identyfikator z DB, wyszukiwanie według adresu 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;
}

Możesz uzyskać adres URL (zamiast kodu HTML) z czwartym paramentem ustawionym na 'src' Codex: media_sideload_image ()

$src = media_sideload_image($url, $item_id, $desc,'src');
get_attachment_id_from_src($src);
yondemon
źródło
4

Odpowiedź @ Toma J Nowella jest natychmiastowa. Znalazłem inną alternatywę (przy użyciu różnych funkcji) wyjaśnioną tutaj, ale podoba mi się jeszcze jedna.

W moim przypadku mam tablicę $ postów ze wszystkimi postami, które chcę wstawić oraz osobne $ media (takie same klucze $ nid jak $ posts) z mediami. Mój kod jest tym samym rozwiązaniem, co Tom, ale został ponownie użyty w celu użycia anonimowej funkcji:

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

W moim przypadku zakładam, że pierwszy element w każdym $ media [$ nid] powinien być wyróżnionym obrazem jego postu.

WordPress powinien zdecydowanie zmienić media_sideload_image (), aby zwracał $ id. W rzeczywistości funkcja ma to pod ręką, patrz źródło tutaj . W rzeczywistości istnieje bilet na to, a oni mają nawet łatki, aby zastosować to do twojego rdzenia w międzyczasie, jeśli chcesz.

Jorge Orpinel
źródło
Wygląda na to, że łata ma zostać załatana w 4,8
Tom Auger
3

Szukałem rozwiązania i postanowiłem przyjrzeć się kodowi, media_sideload_image()który był bardzo prosty. Używa, media_handle_sideload()co daje nam przywiązanie id.

Zmodyfikowałem go, aby zwracał załącznik idzamiast źródła html obrazu, a nawet dodałem sposób, aby wysłać mu nową nazwę pliku.

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;
}
Dario Zadro
źródło