Come posso aggiungere un campo di caricamento immagini direttamente a un pannello di scrittura personalizzato?

19 nov 2010, 20:31:26
Visualizzazioni: 114K
Voti: 67

Ho aggiunto una nuova pagina sotto "Pagine" nell'amministrazione di WordPress e ho inserito diversi campi personalizzati. Vorrei anche poter aggiungere un campo per il caricamento delle immagini nell'editor della pagina - c'è un modo per farlo tramite i custom-fields?

Oppure devo prendere una direzione diversa se ho bisogno di questa funzionalità?

2
Commenti

controlla il plugin tdo-forms, forse questa è la soluzione più semplice

bueltge bueltge
19 nov 2010 21:07:43

Questa domanda è probabilmente correlata: http://wordpress.stackexchange.com/questions/4291/how-to-display-category-information-from-a-custom-post

hakre hakre
19 nov 2010 23:41:55
Tutte le risposte alla domanda 2
4
112

Per chi vuole sapere di più sul caricamento dei file, ecco una breve guida che copre gli argomenti principali e i punti critici. Questo è scritto con WordPress 3.0 su un sistema Linux in mente, e il codice è solo una panoramica di base per insegnare i concetti. Sono sicuro che alcune persone qui potrebbero offrire consigli per migliorare l'implementazione.

Delinea l'Approccio di Base

Ci sono almeno tre modi per associare immagini ai post: utilizzando un campo post_meta per memorizzare il percorso dell'immagine, utilizzando un campo post_meta per memorizzare l'ID della libreria media dell'immagine (ne parleremo più avanti), o assegnando l'immagine al post come allegato. Questo esempio utilizzerà un campo post_meta per memorizzare l'ID della libreria media dell'immagine. YMMV (I risultati possono variare).

Codifica Multipart

Per impostazione predefinita, i moduli di creazione e modifica di WordPress non hanno un enctype. Se vuoi caricare un file, dovrai aggiungere un "enctype='multipart/form-data'" al tag del form--altrimenti la collezione $_FILES non verrà passata. In WordPress 3.0, c'è un hook per questo. In alcune versioni precedenti (non sono sicuro delle specifiche) devi sostituire il tag del form con una stringa.

function xxxx_add_edit_form_multipart_encoding() {

    echo ' enctype="multipart/form-data"';

}
add_action('post_edit_form_tag', 'xxxx_add_edit_form_multipart_encoding');

Creare la Meta Box e il Campo di Caricamento

Non mi addentrerò nella creazione di meta box poiché la maggior parte di voi probabilmente sa già come farlo, ma dirò semplicemente che avete bisogno di una semplice meta box con un campo file. Nell'esempio seguente ho incluso del codice per cercare un'immagine esistente e visualizzarla se esiste. Ho incluso anche una semplice funzionalità di errore/feedback che passa gli errori usando un campo post_meta. Vorrai modificare questo per utilizzare la classe WP_Error... è solo per dimostrazione.

function xxxx_render_image_attachment_box($post) {

    // Verifica se esiste un'immagine. (Stiamo associando immagini ai post salvando l'ID dell'allegato dell'immagine come valore meta del post)
    // Tra l'altro, questo è anche il modo in cui troveresti qualsiasi file caricato per visualizzarlo nel frontend.
    $existing_image_id = get_post_meta($post->ID,'_xxxx_attached_image', true);
    if(is_numeric($existing_image_id)) {

        echo '<div>';
            $arr_existing_image = wp_get_attachment_image_src($existing_image_id, 'large');
            $existing_image_url = $arr_existing_image[0];
            echo '<img src="' . $existing_image_url . '" />';
        echo '</div>';

    }

    // Se c'è un'immagine esistente, mostrala
    if($existing_image_id) {

        echo '<div>ID Immagine Allegata: ' . $existing_image_id . '</div>';

    } 

    echo 'Carica un\'immagine: <input type="file" name="xxxx_image" id="xxxx_image" />';

    // Verifica se c'è un messaggio di stato da visualizzare (lo stiamo usando per mostrare errori durante il processo di caricamento, anche se probabilmente dovremmo usare la classe WP_error)
    $status_message = get_post_meta($post->ID,'_xxxx_attached_image_upload_feedback', true);

    // Mostra un messaggio di errore se ce n'è uno
    if($status_message) {

        echo '<div class="upload_status_message">';
            echo $status_message;
        echo '</div>';

    }

    // Inserisce un flag nascosto. Questo aiuta a differenziare tra salvataggi manuali e salvataggi automatici (nei salvataggi automatici, il file non verrebbe passato).
    echo '<input type="hidden" name="xxxx_manual_save_flag" value="true" />';

}



function xxxx_setup_meta_boxes() {

    // Aggiungi la box a una particolare pagina di tipo di contenuto personalizzato
    add_meta_box('xxxx_image_box', 'Carica Immagine', 'xxxx_render_image_attachment_box', 'post', 'normal', 'high');

}
add_action('admin_init','xxxx_setup_meta_boxes');

Gestire il Caricamento dei File

Questo è il più importante--gestire effettivamente il caricamento dei file collegandosi all'azione save_post. Ho incluso una funzione ampiamente commentata qui sotto, ma vorrei evidenziare le due funzioni chiave di WordPress che utilizza:

wp_handle_upload() fa tutta la magia di, beh, gestire il caricamento. Basta passargli un riferimento al tuo campo nell'array $_FILES e un array di opzioni (non preoccuparti troppo di queste--l'unica importante che devi impostare è test_form=false. Fidati). Questa funzione non aggiunge, tuttavia, il file caricato alla libreria media. Si limita a fare il caricamento e restituisce il percorso del nuovo file (e, comodamente, anche l'URL completo). Se c'è un problema, restituisce un errore.

wp_insert_attachment() aggiunge l'immagine alla libreria media e genera tutte le miniature appropriate. Basta passargli un array di opzioni (titolo, stato del post, ecc.), e il percorso LOCALE (non URL) del file appena caricato. La cosa fantastica dell'inserire le immagini nella libreria media è che puoi facilmente eliminare tutti i file in seguito chiamando wp_delete_attachment e passandogli l'ID della libreria media dell'elemento (che sto facendo nella funzione qui sotto). Con questa funzione, dovrai anche usare wp_generate_attachment_metadata() e wp_update_attachment_metadata(), che fanno esattamente ciò che ti aspetteresti--generano metadati per l'elemento multimediale.

function xxxx_update_post($post_id, $post) {

    // Ottieni il tipo di post. Poiché questa funzione verrà eseguita per TUTTI i salvataggi di post (indipendentemente dal tipo di post), dobbiamo saperlo.
    // È anche importante notare che l'azione save_post può essere eseguita più volte ad ogni salvataggio del post, quindi devi controllare e assicurarti che il
    // tipo di post nell'oggetto passato non sia "revision"
    $post_type = $post->post_type;

    // Assicurati che il nostro flag sia presente, altrimenti è un salvataggio automatico e dovremmo uscire.
    if($post_id && isset($_POST['xxxx_manual_save_flag'])) { 

        // Logica per gestire tipi di post specifici
        switch($post_type) {

            // Se questo è un post. Puoi modificare questo caso per riflettere il tuo slug di post personalizzato
            case 'post':

                // GESTISCI IL CARICAMENTO DEL FILE

                // Se il campo di caricamento ha un file
                if(isset($_FILES['xxxx_image']) && ($_FILES['xxxx_image']['size'] > 0)) {

                    // Ottieni il tipo del file caricato. Viene restituito come "tipo/estensione"
                    $arr_file_type = wp_check_filetype(basename($_FILES['xxxx_image']['name']));
                    $uploaded_file_type = $arr_file_type['type'];

                    // Imposta un array contenente un elenco di formati accettabili
                    $allowed_file_types = array('image/jpg','image/jpeg','image/gif','image/png');

                    // Se il file caricato è del formato giusto
                    if(in_array($uploaded_file_type, $allowed_file_types)) {

                        // Array di opzioni per la funzione wp_handle_upload. 'test_upload' => false
                        $upload_overrides = array( 'test_form' => false ); 

                        // Gestisci il caricamento usando la funzione wp_handle_upload di WP. Prende il file postato e un array di opzioni
                        $uploaded_file = wp_handle_upload($_FILES['xxxx_image'], $upload_overrides);

                        // Se la chiamata wp_handle_upload ha restituito un percorso locale per l'immagine
                        if(isset($uploaded_file['file'])) {

                            // La funzione wp_insert_attachment ha bisogno del percorso di sistema letterale, che è stato restituito da wp_handle_upload
                            $file_name_and_location = $uploaded_file['file'];

                            // Genera un titolo per l'immagine che verrà utilizzato nella libreria media
                            $file_title_for_media_library = 'il tuo titolo qui';

                            // Configura l'array di opzioni per aggiungere questo file come allegato
                            $attachment = array(
                                'post_mime_type' => $uploaded_file_type,
                                'post_title' => 'Immagine caricata ' . addslashes($file_title_for_media_library),
                                'post_content' => '',
                                'post_status' => 'inherit'
                            );

                            // Esegui la funzione wp_insert_attachment. Questo aggiunge il file alla libreria media e genera le miniature. Se volessi allegare questa immagine a un post, potresti passare l'id del post come terzo parametro e accadrebbe magicamente.
                            $attach_id = wp_insert_attachment( $attachment, $file_name_and_location );
                            require_once(ABSPATH . "wp-admin" . '/includes/image.php');
                            $attach_data = wp_generate_attachment_metadata( $attach_id, $file_name_and_location );
                            wp_update_attachment_metadata($attach_id,  $attach_data);

                            // Prima di aggiornare il meta del post, elimina qualsiasi immagine precedentemente caricata per questo post.
                            // Potresti non volere questo comportamento, a seconda di come stai usando le immagini caricate.
                            $existing_uploaded_image = (int) get_post_meta($post_id,'_xxxx_attached_image', true);
                            if(is_numeric($existing_uploaded_image)) {
                                wp_delete_attachment($existing_uploaded_image);
                            }

                            // Ora, aggiorna il meta del post per associare la nuova immagine al post
                            update_post_meta($post_id,'_xxxx_attached_image',$attach_id);

                            // Imposta il flag di feedback su false, poiché il caricamento è andato a buon fine
                            $upload_feedback = false;


                        } else { // wp_handle_upload ha restituito qualche tipo di errore. Il ritorno contiene dettagli sull'errore, quindi puoi usarlo qui se vuoi.

                            $upload_feedback = 'C\'è stato un problema con il tuo caricamento.';
                            update_post_meta($post_id,'_xxxx_attached_image',$attach_id);

                        }

                    } else { // tipo di file sbagliato

                        $upload_feedback = 'Per favore carica solo file immagine (jpg, gif o png).';
                        update_post_meta($post_id,'_xxxx_attached_image',$attach_id);

                    }

                } else { // Nessun file è stato passato

                    $upload_feedback = false;

                }

                // Aggiorna il meta del post con qualsiasi feedback
                update_post_meta($post_id,'_xxxx_attached_image_upload_feedback',$upload_feedback);

            break;

            default:

        } // Fine switch

    return;

} // Fine if manual save flag

    return;

}
add_action('save_post','xxxx_update_post',1,2);

Permessi, Proprietà e Sicurezza

Se hai problemi con il caricamento, potrebbe essere dovuto ai permessi. Non sono un esperto di configurazione del server, quindi correggimi se questa parte è imprecisa.

Prima di tutto, assicurati che la cartella wp-content/uploads esista e sia di proprietà di apache:apache. In tal caso, dovresti essere in grado di impostare i permessi a 744 e tutto dovrebbe funzionare. La proprietà è importante--anche impostare i permessi a 777 a volte non aiuta se la directory non è di proprietà corretta.

Dovresti anche considerare di limitare i tipi di file caricati ed eseguiti utilizzando un file htaccess. Questo impedisce alle persone di caricare file che non sono immagini e di eseguire script camuffati da immagini. Dovresti probabilmente cercare su Google informazioni più autorevoli, ma puoi fare una semplice limitazione del tipo di file così:

<Files ^(*.jpeg|*.jpg|*.png|*.gif)>
order deny,allow
deny from all
</Files>
23 nov 2010 02:28:22
Commenti

Grazie mille MathSmath! Esattamente ciò di cui avevo bisogno. Vorrei poter dare più upvote a questa risposta!

Michal Mau Michal Mau
25 gen 2011 06:21:30

Spiegazione eccellente! L'UNICA cosa su cui ti chiederei gentilmente di espandere è come rendere inaccessibili al pubblico file specifici caricati. In altre parole, se volessi creare un post-type specifico dove tutti i file caricati siano accessibili solo da utenti con una specifica capability. Potresti per favore approfondire questo aspetto?

NetConstructor.com NetConstructor.com
25 gen 2011 13:25:17

Per chiunque voglia caricare file sul frontend, sarà necessario includere il seguente codice per avere accesso alla funzione wp_handle_upload(): if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );

Nick Budden Nick Budden
10 nov 2011 19:27:56

@NetConstructor.com Ti suggerisco di creare una domanda poiché ciò è ampiamente al di fuori dello scopo di questa risposta.

hitautodestruct hitautodestruct
7 mar 2013 14:51:02
0

Il codice fornito da @MathSmath è corretto. Tuttavia, se gestisci molti campi di upload o vuoi caricare più file, dovrai modificarlo parecchio.

Inoltre, non utilizza la libreria multimediale di WordPress per il caricamento dei file (che fa tutto il lavoro sporco dietro le quinte).

Ti consiglio di dare un'occhiata a un plugin come Meta Box. Il plugin supporta entrambi i metodi per caricare file:

  • Tramite HTML5 input[type="file"], che utilizza un codice simile a quello sopra (vedi documentazione) e
  • Tramite la Libreria multimediale di WordPress (vedi documentazione).

Può aiutarti a ridurre lo sforzo di scrittura e manutenzione del codice, specialmente quando vuoi creare più upload.

Dichiarazione: sono l'autore di Meta Box.

24 gen 2018 04:57:44