Consenti agli utenti di inviare immagini al tuo sito WordPress

In questo tutorial imparerai come creare un plug-in che consenta agli utenti di inviare immagini e caricarle nella libreria multimediale di WordPress. Scoprirai anche come cancellare correttamente le immagini dalla libreria multimediale di WordPress e fare alcune convalide di base sulle immagini caricate.


In precedenza…

Questo tutorial è su richiesta di alcuni utenti che hanno trovato interessante il mio tutorial sui plugin delle citazioni, ma erano particolarmente desiderosi di scoprire come utilizzare la stessa tecnica per caricare le immagini dal frontend. Quindi, ecco una reiterazione di quel tutorial che fa proprio questo. Per informazioni dettagliate sulla configurazione del plug-in, shortcode e non, consultare il tutorial precedente.

Il plugin:

  • visualizza un modulo di caricamento delle immagini usando un codice funzione
  • accetta solo le immagini di un certo tipo e la dimensione massima
  • aggiungi un tipo di messaggio personalizzato per le immagini dell'utente
  • aggiungere immagini alla libreria multimediale di WordPress con una didascalia di allegato corretta
  • mostra immagini inedite
  • consentire agli utenti di eliminare le loro immagini non pubblicate

Utilizzeremo il meta campo integrato di WordPress post thumbnail (aka Featured Image) per contenere l'immagine per ogni post. Ciò rende anche più facile visualizzare e lavorare con la nostra immagine, dato che possiamo usare le funzioni post_thumbnail.

Ecco a cosa miriamo:

Tutto il codice è disponibile nella sorgente del plugin nella parte superiore di questo tutorial.


Passaggio 1 Configurare il plug-in

Crea un file plugin chiamato submit_user_images.php nel wp-content / plugins / inviare-user-immagini elenco.

Fare riferimento alla fonte del plugin per informazioni sull'intestazione del plugin.


Fase 2 Inizializzazione del plugin

Creeremo un tipo di post personalizzato denominato user_images per contenere le immagini dell'utente e una tassonomia personalizzata denominata user_image_category. Ciò consentirà un'amministrazione più pulita delle immagini piuttosto che assegnarle a normali post e categorie.

Il gancio e la funzione Init

Utilizzeremo il seguente codice di inizializzazione per creare il nostro tipo di post personalizzato e la nostra tassonomia personalizzata:

 add_action ('init', 'sui_plugin_init'); function sui_plugin_init () $ image_type_labels = array ('name' => _x ('Immagini utente', 'nome generale del tipo di posta'), 'singular_name' => _x ('Immagine utente', 'nome del tipo singolare'), 'add_new' => _x ('Aggiungi nuova immagine utente', 'immagine'), 'add_new_item' => __ ('Aggiungi nuova immagine utente'), 'edit_item' => __ ('Modifica immagine utente'), 'new_item '=> __ (' Aggiungi nuova immagine utente '),' all_items '=> __ (' Visualizza immagini utente '),' view_item '=> __ (' Visualizza immagine utente '),' search_items '=> __ (' Cerca Immagini utente '),' not_found '=> __ (' Nessuna immagine utente trovata '),' not_found_in_trash '=> __ (' Nessuna immagine utente trovata nel cestino '),' parent_item_colon '=> ",' menu_name '=>' User Images '); $ image_type_args = array (' labels '=> $ image_type_labels,' public '=> true,' query_var '=> true,' rewrite '=> true,' capability_type '=>' post ',' has_archive '=> true,' hierarchical '=> false,' map_meta_cap '=> true,' menu_position '=> null,' supports '=> array (' title ',' editor ',' author ',' thumbnail '))) ; register_post_type ('user_images', $ image_type_args); $ image_catego ry_labels = array ('name' => _x ('Categorie immagine utente', 'nome generale tassonomia'), 'singular_name' => _x ('Immagine utente', 'nome tassonomio singolare'), 'search_items' => __ ( 'Cerca categorie immagini utente'), 'all_items' => __ ('Tutte le categorie immagini utente'), 'parent_item' => __ ('Parent Image Category utente'), 'parent_item_colon' => __ ('Parent Image Image utente : '),' edit_item '=> __ (' Modifica categoria immagine utente '),' update_item '=> __ (' Aggiorna categoria immagine utente '),' add_new_item '=> __ (' Aggiungi nuova categoria immagine utente '), 'new_item_name' => __ ('Nuovo nome immagine utente'), 'menu_name' => __ ('Categorie immagini utente'),); $ image_category_args = array ('hierarchical' => true, 'labels' => $ image_category_labels, 'show_ui' => true, 'query_var' => true, 'rewrite' => array ('slug' => 'user_image_category') ,); register_taxonomy ('sui_image_category', array ('user_images'), $ image_category_args); $ default_image_cats = array ('humor', 'paesaggi', 'sport', 'persone'); foreach ($ default_image_cats as $ cat) if (! term_exists ($ cat, 'sui_image_category')) wp_insert_term ($ cat, 'sui_image_category'); 

Cosa fa questo codice:

  • usa il hook di azione init di WordPress per chiamare una funzione di inizializzazione del plugin
  • registra un tipo di messaggio personalizzato denominato user_images
  • registra una tassonomia personalizzata denominata user_image_category e la assegna al tipo di post user_images
  • aggiunge alcune categorie predefinite alla tassonomia user_image_category se non esistono già

Ora avremo un menu Immagini utente nella nostra bacheca di amministrazione e un modo per amministrare le immagini degli utenti e le loro categorie.


Passaggio 3 Configurare alcuni valori predefiniti

Dovremo eseguire alcune convalide di base, quindi definiamo due costanti per un uso futuro:

 define ('MAX_UPLOAD_SIZE', 200000); define ('TYPE_WHITELIST', serialize (array ('image / jpeg', 'image / png', 'image / gif')));

Passaggio 4 Definire un codice funzione

Definiremo uno shortcode che ci consentirà di visualizzare (ed elaborare) il modulo di invio delle immagini dell'utente in un post o una pagina:

 add_shortcode ('sui_form', 'sui_form_shortcode');

Sicurezza

Poiché il nostro plugin accetta i dati dell'utente, implementiamo i seguenti meccanismi di sicurezza:

  • solo gli utenti che hanno effettuato l'accesso hanno accesso al modulo di invio immagini
  • usiamo nonce per verificare che i moduli siano stati generati dal nostro plugin
  • le immagini vengono inviate usando wp_insert_post che sanifica i dati prima di salvarli nel database
  • gli utenti possono solo visualizzare le proprie immagini e non impedire loro di eliminare i post di immagini di altri utenti

Passaggio 5 La funzione principale

Questa è la funzione chiamata dal nostro shortcode. Visualizza ed elabora il modulo di invio immagini e il modulo elenco / cancellazione immagini. Lo prenderemo in pezzi di dimensioni ridotte e nel passaggio 6 esamineremo le funzioni di supporto.

 function sui_form_shortcode () if (! is_user_logged_in ()) return '

Devi essere registrato per inviare un'immagine.

'; global $ current_user;
  • controlla per vedere se l'utente è loggato
  • prendi la variabile WordPress $ current_user di cui avremo bisogno per ottenere il nostro ID utente
 if (isset ($ _POST ['sui_upload_image_form_submitted']) && wp_verify_nonce ($ _ POST ['sui_upload_image_form_submitted'], 'sui_upload_image_form')) $ result = sui_parse_file_errors ($ _ FILES ['sui_image_file'], $ _POST ['sui_image_caption'])) ; if ($ result ['error']) echo '

ERRORE: '. $ result ['errore']. '

'; else $ user_image_data = array ('post_title' => $ result ['caption'], 'post_status' => 'in sospeso', 'post_author' => $ current_user-> ID, 'post_type' => 'user_images') ; if ($ post_id = wp_insert_post ($ user_image_data)) sui_process_image ('sui_image_file', $ post_id, $ result ['caption']); wp_set_object_terms ($ post_id, (int) $ _ POST ['sui_image_category'], 'sui_image_category');
  • se il modulo immagine è stato inviato, ci sarà un campo sui_upload_image_form_submitted che è stato generato dalla nostra funzione wp_nonce_field. Possiamo quindi verificare il nonce e procedere all'elaborazione dell'immagine inviata
  • effettuare alcune convalide passando l'input del file (dove sono archiviati i dati dell'immagine caricata) e la didascalia immette i dati in una funzione di convalida, sui_parse_file_errors e visualizza eventuali errori restituiti
  • costruire un array impostando lo stato del post in sospeso (l'amministratore dovrà ora approvarlo per la pubblicazione), impostando il tipo di post su user_images (il nostro tipo di post personalizzato) e impostando l'autore del post dell'immagine all'utente attualmente loggato
  • se il post dell'immagine è stato inserito correttamente, salva l'immagine nella libreria multimediale di WordPress (sui_process_image) e infine imposta la categoria per il post dell'immagine e visualizza un messaggio di successo
 if (isset ($ _POST ['sui_form_delete_submitted']) && wp_verify_nonce ($ _ POST ['sui_form_delete_submitted'], 'sui_form_delete')) if (isset ($ _ POST ['sui_image_delete_id'])) if ($ user_images_deleted = sui_delete_user_images ( $ _POST ['sui_image_delete_id'])) echo '

'. $ user_images_deleted. 'immagini (s) cancellate!

';
  • se il modulo di cancellazione dell'immagine è stato inviato, ci sarà un campo sui_form_delete_submitted che è stato generato dalla nostra funzione wp_nonce_field. Possiamo quindi verificare il nonce e procedere all'elaborazione della matrice di immagini controllate per l'eliminazione
  • controlliamo la presenza di alcune immagini per la cancellazione testando $ _POST ['sui_image_delete_id']. Se è così, li consegniamo alla funzione sui_delete_user_images (vedi punto 6)
  • se le immagini sono state cancellate, viene visualizzato un messaggio di successo
 echo sui_get_upload_image_form ($ sui_image_caption = $ _POST ['sui_image_caption'], $ sui_image_category = $ _POST ['sui_image_category']); if ($ user_images_table = sui_get_user_images_table ($ current_user-> ID)) echo $ user_images_table; 
  • forniamo il modulo di caricamento delle immagini
  • infine, viene visualizzato il modulo di elenco / eliminazione delle immagini passando l'ID utente alla funzione sui_get_user_images_table (vedere il Passaggio 6)

Passo 6 Funzioni di supporto

Qui vedremo le funzioni che generano i moduli, aggiungere le immagini al catalogo multimediale e la funzione che cancella le immagini selezionate.

 function sui_get_upload_image_form ($ sui_image_caption = ", $ sui_image_category = 0) $ out ="; $ out. = '
'; $ out. = wp_nonce_field ('sui_upload_image_form', 'sui_upload_image_form_submitted'); $ out. = '
'; $ out. = '
'; $ out. = '
'; $ out. = sui_get_image_categories_dropdown ('sui_image_category', $ sui_image_category). '
'; $ out. = '
'; $ out. = '
'; $ out. = ''; $ out. = '
'; restituire $ out;
  • la funzione accetta 2 argomenti opzionali per ripopolare i campi del modulo. Questa è una comodità per l'utente.
  • viene emesso un campo nonce che controlliamo quando il modulo viene inviato
  • produciamo un menu a discesa per le categorie di immagini chiamando sui_get_image_categories_dropdown (vedi la prossima funzione)
 function sui_get_image_categories_dropdown ($ taxonomy, $ selected) return wp_dropdown_categories (array ('taxonomy' => $ taxonomy, 'name' => 'sui_image_category', 'selected' => $ selected, 'hide_empty' => 0, 'echo' => 0)); 
  • la funzione accetta 2 argomenti incluso l'ID dell'elemento della categoria attualmente selezionata
  • usiamo la funzione wp_dropdown_categories di WordPress per creare un menu a discesa che elenca le categorie di immagini dell'utente dalla tassonomia user_image_category (la nostra tassonomia personalizzata)
 function sui_get_user_images_table ($ user_id) $ args = array ('author' => $ user_id, 'post_type' => 'user_images', 'post_status' => 'in sospeso'); $ user_images = new WP_Query ($ args); se (! $ user_images-> post_count) restituisce 0; $ out = "; $ out. = '

Immagini inedite: fai clic per vedere a schermo intero

'; $ out. = '
'; $ out. = wp_nonce_field ('sui_form_delete', 'sui_form_delete_submitted'); $ out. = ''; $ out. = ''; foreach ($ user_images-> post come $ user_image) $ user_image_cats = get_the_terms ($ user_image-> ID, 'sui_image_category'); foreach ($ user_image_cats as $ cat) $ user_image_cat = $ cat-> nome; $ post_thumbnail_id = get_post_thumbnail_id ($ user_image-> ID); $ out. = wp_nonce_field ('sui_image_delete_'. $ user_image-> ID, 'sui_image_delete_id_'. $ user_image-> ID, false); $ out. = ''; $ out. = ''; $ out. = ''; $ out. = ''; $ out. = ''; $ out. = ''; $ out. = '
ImmagineDidascaliaCategoriaElimina
'. wp_get_attachment_link ($ post_thumbnail_id, 'miniatura'). ''. $ user_image-> post_title. ''. $ user_image_cat. '
'; $ out. = ''; $ out. = '
'; restituire $ out;
  • accetta l'ID utente perché è necessario ottenere un elenco di immagini utente solo per l'utente corrente
  • crea $ args per specificare il nostro utente, il tipo di post di user_images e le immagini dell'utente che sono in sospeso (non ancora pubblicate dall'amministratore)
  • eseguire una query personalizzata usando WP_Query
  • restituisce false se la nostra query non restituisce immagini dell'utente
  • avvia un modulo e genera un nonce per il modulo
  • passa attraverso i post delle immagini assicurandoci che prendiamo anche la categoria del post dell'immagine
  • generare un nonce per la casella di controllo eliminazione immagine, assegnando un nome univoco per il nonce concatenando l'ID del post dell'immagine dell'utente
  • visualizza una riga della tabella contenente le informazioni sul post dell'immagine e una casella di controllo Elimina

Perché aggiungere un nonce per ogni post dell'immagine?

I moduli possono essere manipolati nel browser per postare dati imprevisti. Nel nostro caso, a ogni casella di spunta viene assegnato il valore di un post. Ma cosa succede se un utente malintenzionato ha alterato quel valore e ha causato la nostra funzione di eliminazione per rimuovere un post che non era effettivamente elencato?

Un modo per evitarlo, è usare nonce per ogni riga di dati del post, assicurandosi che i nonces siano nominati univocamente con il valore del post da eliminare. Verifichiamo quindi la nonce al momento dell'invio del modulo per assicurarci che sia un vero valore di ritorno.

 function sui_delete_user_images ($ images_to_delete) $ images_deleted = 0; foreach ($ images_to_delete come $ user_image) if (isset ($ _ POST ['sui_image_delete_id_'. $ user_image]) && wp_verify_nonce ($ _ POST ['sui_image_delete_id_'. $ user_image], 'sui_image_delete_'. $ user_image)) if ($ post_thumbnail_id = get_post_thumbnail_id ($ user_image)) wp_delete_attachment ($ post_thumbnail_id);  wp_trash_post ($ user_image); $ images_deleted ++;  return $ images_deleted; 
  • la funzione accetta un array di ID post immagine da eliminare
  • ogni ID post immagine viene controllato per vedere se è stato generato un nonce per questo
  • se il nonce verifica, eliminiamo l'allegato dell'immagine che esiste nel catalogo multimediale passando l'id della miniatura del post dell'immagine alla funzione di WordPress wp_delete_attachment
  • cancelliamo anche il post dell'immagine utilizzando la funzione WordPress wp_trash_post

Ma l'allegato in miniatura non viene eliminato quando il post viene eliminato?

No, perché WordPress memorizza gli allegati come post normali nella tabella del database dei post. Dai un'occhiata: tutti gli allegati sono memorizzati nella tabella dei post con un post_type di allegato. Semplicemente cancellando un post di tipo user_images non cancella il suo allegato in miniatura. Rimane nella libreria multimediale per uso futuro, a meno che non lo elimini in modo specifico con wp_delete_attachment. Per i nostri scopi, ho pensato che fosse meglio rimuovere l'allegato quando il post dell'utente è stato cancellato.


Passaggio 7 Le funzioni di gestione delle immagini

Ricordiamoci di come appare l'output di un file html quando invia un'immagine al tuo script:

 Matrice ([nome] => ref_blind.jpg [tipo] => immagine / jpeg [nome_tmp] => / tmp / php79xI4e [errore] => 0 [dimensione] => 106290)

Passiamo quell'array alla funzione sui_process_image insieme all'ID del post dell'immagine utente salvata e alla didascalia dell'immagine santized.

 funzione sui_process_image ($ file, $ post_id, $ caption) require_once (ABSPATH. "wp-admin". '/includes/image.php'); require_once (ABSPATH. "wp-admin". "/includes/file.php"); require_once (ABSPATH. "wp-admin". "/includes/media.php"); $ attachment_id = media_handle_upload ($ file, $ post_id); update_post_meta ($ post_id, '_thumbnail_id', $ attachment_id); $ attachment_data = array ('ID' => $ attachment_id, 'post_excerpt' => $ caption); wp_update_post ($ attachment_data); return $ attachment_id; 
  • abbiamo bisogno di includere gli script admin di WordPress che gestiscono il caricamento di immagini dietro le quinte
  • chiamiamo la funzione media_handle_upload (che è parte di media.php), passandogli l'array di file caricato e l'id post
  • ora abbiamo un ID allegato che possiamo usare con update_post_meta per assegnare l'allegato al post come miniatura. Nota: "_thumbnail_id" si riferisce al campo meta della miniatura interna (Immagine in primo piano). I campi Wordpress interni iniziano con un carattere di sottolineatura.
  • in seguito utilizzeremo l'id allegato per aggiornare la didascalia dell'allegato utilizzando la funzione wp_update_post

Poiché gli allegati sono solo post normali, se aggiorniamo il campo post_excerpt per l'allegato, stiamo effettivamente aggiornando il campo didascalia dell'allegato come mostrato nella schermata di modifica della libreria multimediale.

La funzione di validazione

Convalidiamo anche l'array di file e la didascalia dell'immagine fornita dall'utente con la funzione sui_parse_file_errors.

 function sui_parse_file_errors ($ file = ", $ image_caption) $ result = array (); $ result ['error'] = 0; if ($ file ['error']) $ result ['error'] =" No file caricato o si è verificato un errore di caricamento! "; return $ result; $ image_caption = trim (preg_replace ('/ [^ a-zA-Z0-9 \ s] + /',", $ image_caption)); if ($ image_caption == ") $ result ['error'] =" La tua didascalia può contenere solo lettere, numeri e spazi! "; return $ result; $ result ['caption'] = $ image_caption; $ image_data = getimagesize ($ file ['tmp_name']); if (! in_array ($ image_data ['mime'], unserialize (TYPE_WHITELIST))) $ result ['error'] = 'La tua immagine deve essere jpeg, png o gif ! '; elseif (($ file [' size ']> MAX_UPLOAD_SIZE)) $ result [' error '] =' La tua immagine era '. $ file [' size '].' byte! Non deve superare '. MAX_UPLOAD_SIZE. 'Byte.'; Return $ result;
  • controlla l'elemento di errore dell'array di file per un errore di caricamento html, se trovato restituisce un array di risultati con errore
  • eseguire alcune espressioni regolari sulla didascalia dell'immagine per rimuovere tutto tranne dati e spazi alfanumerici, sostituendo con spazi per la leggibilità
  • se finiamo con una didascalia vuota dopo averla disinfettata, restituiamo un errore
  • controlla il tipo di immagine interna (non fidarti dell'estensione del file) usando la funzione PHP getimagesize rispetto alla costante TYPE_WHITELIST
  • controlla la dimensione dell'immagine rispetto alla costante MAX_UPLOAD_SIZE

Step 8 Alcuni stili

Basta rilasciare queste informazioni di stile nel file style.css nella cartella del tema:

 #sui_upload_image_form #sui_image_caption width: 500px;  #user_images font-size: 12px;  #user_images th text-align: left;  #user_images td vertical-align: middle;  #user_images td input margin: 0px; 

Passaggio 9 Provalo

Attiva il plugin, inserisci lo shortcode in una pagina, accedi al tuo sito e testalo. Quando carichi un'immagine, viene visualizzato un nuovo post nel menu di amministrazione Immagini utente. Sarà in attesa di pubblicazione. Vedrai anche una nuova immagine elencata nel tuo catalogo multimediale, allegata al tuo nuovo post e con la didascalia fornita.

La sorgente completa del codice del plugin e un link al sito demo sono elencati all'inizio di questo tutorial.

La cartella di origine contiene anche un modello di pagina Wordpress con un ciclo personalizzato che mostra le immagini pubblicate per tutti gli utenti.


Pensieri finali

Potresti voler inserire una convalida più rigorosa sui tuoi caricamenti di immagini. Ricorda che accetti i dati degli utenti che potrebbero caricare accidentalmente o in modo inappropriato file inappropriati. Controllare il tipo e la dimensione del file è un buon inizio.

Inoltre, abbiamo creato la didascalia dell'allegato aggiornando il campo post_excerpt dell'allegato. È inoltre possibile impostare una descrizione di allegato utilizzando il campo post_content dell'allegato.