Come impostare un'immagine in evidenza (miniatura) tramite URL dell'immagine quando si usa wp_insert_post()?
Esaminando la documentazione di riferimento per wp_insert_post(), ho notato che non c'è alcun parametro nell'array richiesto che permetta di impostare l'Immagine in Evidenza' per un post, visualizzata come miniatura del post nel mio tema.
Ho esaminato funzioni come set_post_thumbnail(), come suggerito da Mr. Bennett, ma questa sembra essere un'aggiunta relativamente recente a WordPress stesso e alla documentazione WordPress. Di conseguenza, non riesco a trovare fonti che spieghino come il parametro $thumbnail_id debba essere acquisito e fornito. Se questa è effettivamente la funzione da utilizzare, in che modo potrei fornirle un parametro $thumbnail_id valido quando tutto ciò che ho è l'URL di un'immagine?
Grazie in anticipo!

Puoi impostare un'immagine come miniatura del post quando si trova nella tua libreria multimediale. Per aggiungere un'immagine alla tua libreria multimediale, devi caricarla sul tuo server. WordPress ha già una funzione per inserire immagini nella tua libreria multimediale, ti serve solo uno script che carichi il tuo file.
Utilizzo:
Generate_Featured_Image( '../wp-content/my_image.jpg', $post_id );
// $post_id è un ID numerico... Puoi anche ottenere l'ID con:
wp_insert_post()
Funzione:
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
MODIFICA: Aggiunta creazione percorso

Grazie per il tuo impegno! Questo funziona solo quando si usa $upload_dir['basedir'] (invece di path) però, perché quando ispeziono l'allegato attraverso l'interfaccia di modifica del post viene referenziato come .../uploads/NOMEFILE.EXT mentre $upload_dir['path'] lo memorizzerebbe in qualcosa tipo .../uploads/2012/02/NOMEFILE.EXT.
Sarebbe ancora meglio cambiare il modo in cui il file viene referenziato, ma non so come fare.

Apprezzo la tua rapida risposta :). Tuttavia ottengo ancora lo stesso risultato, ecco uno screenshot che mostra il mio problema: http://i.imgur.com/iKTNs.png. La sezione superiore è il risultato di aver inserito un echo nel tuo condizionale, solo per vedere cosa succede.

L'ho modificato di nuovo, non passavo il percorso completo a wp_insert_attachment e wp_generate_attachment_metadata. Spero che questo risolva il problema.

Funziona perfettamente, grazie mille! Questo ha anche risolto un problema di dimensioni, che apparentemente era causato da percorsi non corretti (anche se l'immagine veniva visualizzata). Non potrebbe andare meglio!

Grazie per il tuo ottimo codice. È stato necessario solo un piccolo aggiustamento per farlo funzionare con il mio import CSV, ovvero anteporre il postid al nome del file per garantire che i file immagine rimangano univoci.

Permettimi di unirmi agli elogi. Adoro questo frammento di codice. Grazie per avermi fatto risparmiare ore!

Mi chiedevo: è sicuro? C'è il rischio che qualcuno possa mascherare un'immagine, oppure wp_check_filetype() si occupa di questo?

Ho utilizzato il codice sopra e l'ho leggermente modificato per ottenere le immagini in evidenza che hanno il nome dello slug del post (cosa piuttosto dispendiosa in termini di tempo se gestisci migliaia di post):
code
<?php
$slug = basename(get_permalink());
$featuredimageurl = '[YOUR PATH]/wp-content/uploads/featuredimages/' . $slug . '.png';
Generate_Featured_Image( $featuredimageurl, $post_id );
?>

l'uso di file_get_contents
con un URL non funzionerà se allow_url_fopen
è disabilitato in php.ini
- wp_remote_get
sarà più compatibile in diversi ambienti WP

Attenzione: questa risposta sovrascrive il file se ha lo stesso nome, fate attenzione. Dovrebbe generare nomi usando $post_id o almeno uniqid()

Quando uso questo codice, le immagini create nella cartella "uploads" hanno una dimensione di file pari a zero.

Vorrei migliorare la risposta di Rob utilizzando le funzioni core di WordPress download_url
e media_handle_sideload
<?php
/**
* Scarica un'immagine dall'URL specificato e la associa a un post come immagine in evidenza.
*
* @param string $file L'URL dell'immagine da scaricare.
* @param int $post_id L'ID del post a cui associare l'immagine in evidenza.
* @param string $desc Opzionale. Descrizione dell'immagine.
* @return string|WP_Error ID dell'allegato, oggetto WP_Error in caso di errore.
*/
function Generate_Featured_Image( $file, $post_id, $desc ){
// Imposta le variabili per lo storage, corregge il nome del file per le query string.
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
if ( ! $matches ) {
return new WP_Error( 'image_sideload_failed', __( 'URL immagine non valido' ) );
}
$file_array = array();
$file_array['name'] = basename( $matches[0] );
// Scarica il file in una posizione temporanea.
$file_array['tmp_name'] = download_url( $file );
// Se si verifica un errore durante il salvataggio temporaneo, restituisce l'errore.
if ( is_wp_error( $file_array['tmp_name'] ) ) {
return $file_array['tmp_name'];
}
// Esegue la validazione e il salvataggio.
$id = media_handle_sideload( $file_array, $post_id, $desc );
// Se si verifica un errore durante il salvataggio permanente, elimina il file temporaneo.
if ( is_wp_error( $id ) ) {
@unlink( $file_array['tmp_name'] );
return $id;
}
return set_post_thumbnail( $post_id, $id );
}

Utilizzare le funzioni native di WordPress è la migliore pratica, grazie.

Per qualche motivo, questa versione mi ha dato errori dicendo "Non è stato fornito un URL valido", mentre la risposta di Rob Vermeer ha funzionato.

Posso confermare che il codice modificato non funziona, il che è un peccato perché il sideload degli URL sarebbe fantastico!

Prova a utilizzare set_post_thumbnail()
.
Modifica di Otto: Hai chiarito la tua domanda, quindi chiarirò la risposta che ha dato Chip.
In sostanza, devi creare anche l'allegato ('attachment') per il post. Quando un'immagine viene caricata nella libreria multimediale di WordPress, viene creato un post speciale per essa con un tipo di post 'attachment'. Questo allegato è collegato a un post specifico tramite l'identificatore post_parent.
Quindi, se conosci l'ID dell'allegato, chiamare set_post_thumbnail con l'oggetto post o l'ID e l'ID dell'allegato imposterà semplicemente il flag della miniatura del post.
Se non hai ancora creato l'allegato, dovrai farlo prima. Il modo più semplice per farlo è con wp_insert_attachment()
. Questa funzione accetta un array di alcuni parametri, il nome del file (il file deve già essere nella directory corretta degli uploads) e l'ID del post genitore a cui vuoi allegare l'allegato.
Avere un file caricato e allegato a un post non fa nulla automaticamente. Questo è semplicemente un meccanismo di categorizzazione. Il meccanismo della galleria, ad esempio, utilizza le immagini allegate a un post per costruire la [gallery] per quel post. Una miniatura per un post è semplicemente una delle immagini allegate che è stata impostata come miniatura.
Maggiori informazioni su come utilizzare wp_insert_attachment possono essere trovate nel codex (linkato sopra).

Grazie per la tua risposta! Ma come posso recuperare l'ID della miniatura? Sto partendo da un URL di un'immagine, quindi immagino che dovrei prima aggiungere l'immagine alla libreria di WordPress usando un'altra funzione?

Visto che stai già inserendo un articolo, avevo presupposto che tu stessi già allegando immagini al post che stai inserendo. Non è un presupposto valido?

Scusa, ma non ho ancora capito come allegare immagini a un post tramite URL. Inoltre, non vorrei che l'immagine venisse effettivamente visualizzata nel post stesso. Sto cercando la funzione che restituisca il $thumbnail_id, e pensavo che forse wp_insert_attachment() potesse funzionare, fino a quando non ho notato che richiede già che l'allegato sia nella directory di upload. Non so come ottenere un file immagine lì tramite il suo URL, e non sono sicuro che questa sia la funzione che sto cercando in primo luogo. Grazie per il tuo aiuto!

Puoi per favore riscrivere la tua domanda con queste informazioni, per descrivere meglio ciò che stai cercando di ottenere? (Oppure lascia questa così com'è e inizia una nuova domanda per chiedere come ottenere l'ID dell'allegato quando inserisci un post?)

Ho appena trovato questo e l'ho semplificato molto, funziona ma non sono un esperto di sicurezza
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 = "il tuo id del post!";
$attachment_id = media_handle_upload( 'file', $post_ID );
set_post_thumbnail( $post_ID, $attachment_id );
}
Semplice no? Dopo aver incluso i file necessari, WordPress gestirà il media e lo caricherà, per poi impostarlo come thumbnail.

set_post_thumbnail()
è la funzione migliore per questo requisito.
Penso che tu possa trovare l'ID di un allegato tramite get_children()
o get_posts()
. Il risultato è un array e all'interno di questo array c'è l'ID. Il seguente esempio è per testare; spero funzioni; scritto senza test, solo come bozza.
Per il tuo requisito è importante che sostituisci get_the_ID()
con il tuo post-ID
; restituisci l'ID dell'Allegato e questo puoi usarlo per 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);
}

Hai bisogno di alcune librerie di base caricate per mantenere le cose semplici.
function attach_image_from_url_to_post($image_url, $post_id) {
// Controlla se la funzione esiste (fa parte di 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');
}
// Scarica e carica l'immagine esternamente
$image = media_sideload_image($image_url, $post_id, null, 'id');
// Se c'è un errore, restituiscilo
if (is_wp_error($image)) {
return $image;
}
// Imposta l'immagine come immagine in evidenza (thumbnail del post)
set_post_thumbnail($post_id, $image);
return true;
}
