Prima di saltare direttamente al codice per questo, volevo menzionare due cose:
- Sì, l’ho trattato in dettaglio qualche tempo fa,
- E questa è la seconda parte di una serie in due parti.
Se non hai letto la prima parte, fallo prima. L’idea è che il codice funzionerà insieme a ciò che tratterò in questo post per assicurarmi che sia il lato client che il lato server siano coperti.
In definitiva, il motivo per scomporlo in questo modo non è solo per assicurarsi che le cose siano fatte correttamente, ma anche per assicurarsi che l’utente abbia l’esperienza più positiva possibile.
Detto questo, ecco come caricare i file in WordPress sul lato server.
Caricamento di file in WordPress sul lato server
Nota che anche se ci sono alcuni controlli di sicurezza che possono – e dovrebbero – essere eseguiti, devo ancora trovare un modo che sia completamente infallibile per rilevare che il file caricato è del tipo corretto.
Ciò significa che esiste ancora la possibilità che venga caricato un tipo di file errato. Se questo è dannoso o meno dipende ovviamente dall’utente finale. Condivido solo questo per essere chiaro che il codice che mostrerò è il massimo che posso fornire, ma che c’è ancora un livello di discrezione che dovresti usare.
Forse vale anche la pena cercare una libreria di terze parti per convalidare i dati binari una volta ricevuti. Ma sto divagando.
1 Verificare le autorizzazioni utente
Ricorda che ogni volta che abbiamo creato il front-end, WordPress genera un nonce in modo da poterlo utilizzare per assicurarci che l’utente abbia l’autorizzazione per caricare il file.
Oltre a controllare il nonce, ci sono molte altre cose che mi piace controllare, tutte racchiuse in un metodo chiamato userCanSave.
Innanzitutto, ricorda il front-end:
<form method="post"
enctype="multipart/form-data"
action="<?php echo esc_html(admin_url('admin-post.php')); ?>"">
<!-- Snip For Brevity --->
<?php
wp_nonce_field(
'acme-item-upload',
'acme-item-importer'
);
?>
</form>
Quindi dai un’occhiata a come lo uso nel codice. Innanzitutto, definisco la funzione userCanSave :
<?php
/**
* Determines if the current user has permission to upload a file based on their current role and the values
* of the security nonce.
*
* @param string $nonce The WordPress-generated nonce.
* @param string $action The developer-generated action name.
* @return bool True if the user has permission to save; otherwise, false.
*/
private function userCanSave($nonce, $action)
{
$isNonceSet = isset($_POST[$nonce]);
$isValidNonce = false;
if ($isNonceSet) {
$isValidNonce = wp_verify_nonce($_POST[$nonce], $action);
}
return ($isNonceSet && $isValidNonce);
}
E poi lo chiamo semplicemente all’inizio del processo. Se fallisce, allora ritorno.
<?php
/**
* Assuming the user has permission, verifies the security nonce and uploads the PDF file to the `uploads`
* directory and the Media Library.
*/
public function save()
{
if (!$this->userCanSave('acme-item-importer', 'acme-item-upload')) {
return;
}
// More to come...
}
Raccomando di mostrare un messaggio di errore, ma divago su questo punto poiché ci sono alcuni modi per farlo all’interno del post.
2 Caricare il file
Supponendo che l’utente abbia l’autorizzazione per controllare il file, è sicuro caricare il file. Il processo per farlo è semplice ma richiede comunque un po’ di lavoro con l’API di WordPress (vale a dire con la funzione wp_upload_bits ).
Innanzitutto, il file deve essere prelevato da $ _FILES globale di PHP e quindi caricato. Quando lo fai, tuttavia, è importante assicurarsi di caricare un file con l’estensione di file corretta (almeno).
<?php
$file_type = explode('.', $filename);
$file_type = strtolower($file_type[count($file_type) - 1]);
if ('pdf' !== $file_type) {
// Give your feedback of choice here.
}
Se il tipo di file non è un PDF, puoi generare un errore, semplicemente restituire (anche se non ne sono un fan) o fornire un feedback all’utente (cosa che sono un fan di fare).
<?php
if ($uploadFile['error']) {
// Your preferred method of feedback here.
}
L’ultimo passaggio, tuttavia, è inserire il file nell’uploader multimediale.
3 Caricamento nel Media Uploader
L’ultimo passaggio in tutto questo è inserire il file nell’uploader multimediale. Per fare ciò, hai bisogno di diverse cose dal core di WordPress:
- la libreria file.php,
- un array di allegati necessario per dire a WordPress cosa viene aggiunto,
- una funzione dell’API di WordPress, wp_insert_attachment
- reindirizzamento alla pagina chiamante
Sembra molto, vero? Non è male.
Di solito raggruppo l’inclusione della libreria di file di WordPress e di wp_insert_attachment in un unico blocco.
Noterai che ho impostato il tipo MIME su pdf e mi assicuro che il titolo non includa nulla tranne il nome del file. Successivamente, utilizzo wp_insert_attachment per caricare il file nella libreria multimediale.
Il codice completo per questo è il seguente:
<?php
require_once(ABSPATH. "wp-admin". '/includes/file.php');
$attachment = array(
'post_mime_type' => 'pdf',
'post_title' => preg_replace('/.[^.]+$/', '', $filename),
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment($attachment, $uploadFile['file']);
Dopodiché, ritorno alla pagina che ha avviato tutto questo (che di solito è la pagina di amministrazione che abbiamo visto nel post precedente. Per questo, prendo il _wp_http_referer dall’array $ _REQUEST di PHP .
<?php
wp_safe_redirect(
$_REQUEST['_wp_http_referer'],
301
);
exit;
E ciò reindirizzerà l’utente alla pagina da cui è venuto.
E il file viene caricato
A questo punto, abbiamo definito cosa vogliamo fare:
- Offri un’esperienza decente lato client,
- Caricato il file nella libreria multimediale (con possibilità di offrire feedback)
- E reindirizzato alla pagina che ha avviato tutto.
Certo, c’è molto spazio per il feedback in questo e ti esorto ad adattarlo secondo necessità per il tuo codice, ma le basi di ciò di cui hai bisogno dovrebbero essere fornite sia nel post precedente che in questo post.