Ottieni $ image_id dopo aver caricato con media_sideload_image ()


10

Voglio caricare un'immagine e impostarla come immagine in primo piano in un post. Quello che ho provato è stato questo:

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

Ma media_sideload_image()non restituisce il image_id, ma l'immagine di rendering HTML. Come posso ottenere image_id?

Risposte:


28

Ecco un esempio di come aggirare questa limitazione usando azioni / hook:

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

L'idea è che quando media_sideload_imageviene eseguito, esso:

  • scarica l'immagine
  • lo aggiunge come allegato (un post di tipo attachment)
  • quindi allega l'allegato al post di cui hai fornito l'ID ($ post_id)

Il problema è che non fornisce l'ID dei post degli allegati appena creato.

Ma quando viene creato un allegato, viene lanciata un'azione contenente il suo ID. Possiamo agganciarci prima di creare l'allegato e salvare la miniatura in primo piano con l'ID post che ci ha fornito, quindi sganciare in seguito.


1
Brillante! Questo ha aiutato molto.
m-torin,

2
Se questo risponde alla tua domanda potresti contrassegnarlo come corretto?
Tom J Nowell

non riesco a leggere il tuo inglese. qualcuno può modificare questo post?
HiDd3N,

2
@ HiDd3N Ho semplificato un po 'dell'inglese usato, dovrebbe avere parole più comuni con un'età di lettura più bassa
Tom J Nowell

6

Ho creato una funzione per ottenere l'ID dal DB, cercando per 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;
}

Puoi ottenere l'URL (istinto di codice html) con un quarto paramenter impostato su 'src' Codex: media_sideload_image ()

$src = media_sideload_image($url, $item_id, $desc,'src');
get_attachment_id_from_src($src);


4

@Tom J La risposta di Nowell è perfetta. Ho trovato un'altra alternativa (utilizzando diverse funzioni) spiegata qui, ma questa mi piace di più.

Nel mio caso ho un array di $ post con tutti i post che voglio inserire e un $ media separato (stesse chiavi $ nid di $ post) con il media. Il mio codice è la stessa soluzione di Tom ma refactored per utilizzare una funzione anonima:

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

Nel mio caso presumo che il primo elemento in ogni $ media [$ nid] sia l'immagine in primo piano del suo post.

WordPress shouold sicuramente cambia media_sideload_image () in modo da restituire $ id. In effetti la funzione ce l'ha a portata di mano, vedi la fonte qui . In realtà c'è un ticket per questo e hanno anche delle patch per applicarlo al tuo core nel frattempo, se vuoi.


Sembra che dovrebbe essere patchato in 4.8
Tom Auger

3

Stavo cercando una soluzione e ho deciso di esaminare il codice per il media_sideload_image()quale era molto semplice. Usa ciò media_handle_sideload()che ci dà l'allegato id.

L'ho modificato per restituire l'allegato idinvece della fonte html dell'immagine e ho anche aggiunto un modo per inviarlo nuovo nome file.

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.