Come impostare programmaticamente l'immagine in evidenza per un post personalizzato dall'esterno

27 mag 2013, 10:21:12
Visualizzazioni: 35.2K
Voti: 16

Sto cercando di recuperare e inserire immagini dall'esterno dell'ambiente WordPress in un post personalizzato tramite PHP.

Come posso spostare/caricare quell'immagine nella directory di upload di WordPress con il formato cartella anno/data come fa WordPress e impostare quell'immagine come immagine in evidenza per il post personalizzato?

E come caricare l'immagine nella galleria del post personalizzato?

Questo è il mio codice

$filename = $image['name'];
$target_path = "../wp-content/uploads/";
$target_path = $target_path . $filename;
$wp_filetype = wp_check_filetype(basename($filename), null );
$wp_upload_dir = wp_upload_dir();
$attachment = array(
    'guid' => $wp_upload_dir['baseurl'] . '/' . basename( $filename ),
    'post_mime_type' => $wp_filetype['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
    'post_content' => '',
    'post_status' => 'inherit',
);
$attach_id = wp_insert_attachment( $attachment, $target_path, $post_id );
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
set_post_thumbnail( $post_id, $attach_id );

Sono riuscito a caricare l'immagine nella mia directory uploads ma non riesco a creare la cartella dell'anno e della data. Esiste una funzione WordPress per questo?

0
Tutte le risposte alla domanda 3
4
29

Non può essere fatto semplicemente con media_sideload_image()?

Sembra abbastanza semplice. L'unica complicazione è che se non sei nell'area di amministrazione, devi includere alcune librerie dagli include di WordPress:

// necessari solo se eseguito al di fuori dell'ambiente di amministrazione
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');

// immagine di esempio
$image = 'http://example.com/logo.png';

// media_sideload_image restituisce un'immagine HTML, non un ID
$media = media_sideload_image($image, $post_id);

// quindi dobbiamo trovarla per poterla impostare come ID featured
if(!empty($media) && !is_wp_error($media)){
    $args = array(
        'post_type' => 'attachment',
        'posts_per_page' => -1,
        'post_status' => 'any',
        'post_parent' => $post_id
    );

    // referenzia la nuova immagine da impostare come featured
    $attachments = get_posts($args);

    if(isset($attachments) && is_array($attachments)){
        foreach($attachments as $attachment){
            // ottieni il percorso delle immagini a dimensione intera (senza ridimensionamenti tipo 300x150)
            $image = wp_get_attachment_image_src($attachment->ID, 'full');
            // verifica se nell'immagine $media creata esiste la stringa dell'URL
            if(strpos($media, $image[0]) !== false){
                // se sì, abbiamo trovato la nostra immagine. impostala come thumbnail
                set_post_thumbnail($post_id, $attachment->ID);
                // vogliamo solo un'immagine
                break;
            }
        }
    }
}
29 ago 2013 22:33:35
Commenti

Questa soluzione funziona alla perfezione (y)

Omar Tariq Omar Tariq
2 mag 2015 23:16:42

Dove posso aggiungere questo codice?

er.irfankhan11 er.irfankhan11
28 giu 2016 14:51:18

A partire da WordPress 4.8 puoi impostare il quarto parametro in media_sideload_image a 'id' e restituirà il nuovo ID dell'allegato. Esempio: $new_att_id = media_sideload_image($image, $post_id, "descrizione immagine...", 'id'); if(!is_wp_error($new_att_id)) { set_post_thumbnail($post_id, $new_att_id); }

Don Wilson Don Wilson
3 mar 2018 00:49:07

Questo ha funzionato sicuramente per me utilizzando il suggerimento di @DonWilson, basta non dimenticare di includere le 3 librerie dei media se si usa su un form frontend (altrimenti media_sideload_image non viene trovato). Avevo bisogno di copiare le immagini in evidenza da un sito a un altro multisite tramite switch_to_blog()

cogdog cogdog
2 giu 2020 23:58:16
0

Prova questa spiegazione su come caricare utilizzando un percorso e un ID post.

Ecco il codice (per legacy):

/* Importa media da URL
 *
 * @param string $file_url URL del file esistente dal sito originale
 * @param int $post_id L'ID del post a cui il media importato sarà associato
 *
 * @return boolean True in caso di successo, false in caso di fallimento
 */

function fetch_media($file_url, $post_id) {
require_once(ABSPATH . 'wp-load.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
global $wpdb;

if(!$post_id) {
    return false;
}

//directory in cui importare    
$artDir = 'wp-content/uploads/2013/06';

//se la directory non esiste, creala 
if(!file_exists(ABSPATH.$artDir)) {
    mkdir(ABSPATH.$artDir);
}

//rinomina il file
$ext = array_pop(explode("/", $file_url));
$new_filename = 'blogmedia-'.$ext;

if (@fclose(@fopen($file_url, "r"))) { //verifica che il file esista davvero
    copy($file_url, ABSPATH.$artDir.$new_filename);


    $siteurl = get_option('siteurl');
    $file_info = getimagesize(ABSPATH.$artDir.$new_filename);

    //crea un array di dati allegato da inserire nella tabella wp_posts
    $artdata = array();
    $artdata = array(
        'post_author' => 1, 
        'post_date' => current_time('mysql'),
        'post_date_gmt' => current_time('mysql'),
        'post_title' => $new_filename, 
        'post_status' => 'inherit',
        'comment_status' => 'closed',
        'ping_status' => 'closed',
        'post_name' => sanitize_title_with_dashes(str_replace("_", "-", $new_filename)),                                            'post_modified' => current_time('mysql'),
        'post_modified_gmt' => current_time('mysql'),
        'post_parent' => $post_id,
        'post_type' => 'attachment',
        'guid' => $siteurl.'/'.$artDir.$new_filename,
        'post_mime_type' => $file_info['mime'],
        'post_excerpt' => '',
        'post_content' => ''
    );

    $uploads = wp_upload_dir();
            $save_path = $uploads['basedir'].'/2013/06/'.$new_filename;

    //inserisci il record nel database
    $attach_id = wp_insert_attachment( $artdata, $save_path, $post_id );

    //genera metadata e miniature
    if ($attach_data = wp_generate_attachment_metadata( $attach_id, $save_path)) {
        wp_update_attachment_metadata($attach_id, $attach_data);
    }

    //opzionale: rendilo l'immagine in evidenza del post a cui è associato
    $rows_affected = $wpdb->insert($wpdb->prefix.'postmeta', array('post_id' => $post_id, 'meta_key' => '_thumbnail_id', 'meta_value' => $attach_id));
}
else {
    return false;
}

return true;
}
20 giu 2013 13:45:16
4

Forse ho capito male, ma perché vorresti farlo al di fuori dell'ambiente WordPress? Replicare questa funzionalità richiederebbe un sacco di lavoro! WordPress fa molto più che semplicemente caricare il file e posizionarlo in una directory specifica, ad esempio controlla quali utenti possono caricare file, aggiunge record nel database per gli upload e imposta relazioni per le immagini in evidenza, esegue azioni e filtri per plugin esterni che dipendono dal caricamento dei file - il tutto rispettando le impostazioni del sito (riguardo alle convenzioni di denominazione, posizione di caricamento dei media, ecc.).

Se cerchi semplicemente di caricare file senza essere loggato nella sezione di amministrazione di WordPress, ad esempio per caricare file da un sito esterno, potresti voler dare un'occhiata all'API XML-RPC e nello specifico al metodo uploadFile.

Un'altra opzione potrebbe essere quella di scrivere una mini API personalizzata. Fondamentalmente quello che dovresti fare è questo:

  1. Ottenere il file sul server tramite upload (o far scaricare al server il file da un URL specificato).
  2. Usare wp_upload_dir() per ottenere il percorso della directory di upload e sanitize_file_name() per costruire il percorso e scrivere il file nella posizione risultante.
  3. Usare wp_insert_attachment() per memorizzare l'allegato nel database (wp_check_filetype() sarà utile per impostare post_mime_type). Opzionalmente puoi anche impostare post_parent e la chiave meta _thumbnail_id se lo desideri.
  4. Esponi la tua API agli utenti esterni, o richiedi il login, se necessario. Se usi un modulo pubblico, come minimo utilizza wp_create_nonce() e wp_verify_nonce() per rendere il modulo un po' più sicuro.
27 mag 2013 11:47:16
Commenti

Sto scrivendo un servizio web per un'applicazione. L'applicazione mi invia un array FILE attraverso il quale voglio inserire i dati del post e l'immagine. Ho inserito i dettagli del post nel database ma sono bloccato nella parte relativa all'immagine.

Faisal Shehzad Faisal Shehzad
27 mag 2013 13:10:49

Consulta la documentazione per wp_insert_attachment(), dovrebbe fare gran parte di ciò che ti serve secondo me. Sconsiglio vivamente di modificare manualmente il database al di fuori di WordPress, se è quello che stai facendo. Invece, dai un'occhiata al codice sorgente di WordPress e cerca di identificare le parti responsabili dell'aggiunta dei dati dei post, della gestione degli upload di file e dell'inserimento degli allegati. In altre parole, più o meno quello che ho descritto nella mia risposta sopra.

Simon Simon
27 mag 2013 15:57:18

@Simon Ho lo stesso problema. Un altro motivo per cui potresti voler caricare è quando hai un lavoro in batch di immagini che vuoi allegare a diversi post e non vuoi farlo manualmente.

hitautodestruct hitautodestruct
20 giu 2013 13:39:04

@hitautodestruct: Assolutamente, lo faccio spesso quando migro dati da siti esistenti, sistemi legacy, esportazioni di database, ecc. Il mio punto è che dovresti sempre cercare di sfruttare la funzionalità principale di WordPress per ottenere questo risultato, piuttosto che scrivere semplicemente uno script personalizzato che posiziona le immagini nel percorso corretto (che era in qualche modo ciò che percepivo fosse il fulcro della domanda).

Simon Simon
24 giu 2013 14:19:26