Avant de sauter directement dans le code pour cela, je voulais mentionner deux choses :
- Oui, j’ai couvert cela en détail il y a quelque temps,
- Et ceci est la deuxième partie d’une série en deux parties.
Si vous n’avez pas lu la première partie, faites-la d’abord. L’idée est que le code fonctionnera en conjonction avec ce que je vais couvrir dans ce post pour s’assurer que le côté client et le côté serveur sont couverts.
En fin de compte, la raison de le décomposer ainsi n’est pas seulement de s’assurer que les choses sont faites correctement, mais aussi de s’assurer que l’utilisateur a l’expérience la plus positive possible.
Cela dit, voici comment procéder pour télécharger des fichiers dans WordPress côté serveur.
Téléchargement de fichiers dans WordPress côté serveur
Notez que même si certaines vérifications de sécurité peuvent – et doivent – être effectuées, je n’ai pas encore trouvé de moyen totalement infaillible pour détecter que le fichier en cours de téléchargement est du bon type.
Cela signifie qu’il est toujours possible qu’un type de fichier incorrect soit téléchargé. Que ce soit malveillant ou non dépend évidemment de l’utilisateur final. Je partage juste ceci pour être clair sur le fait que le code que je vais montrer est aussi bon que possible, mais qu’il y a toujours un niveau de discrétion que vous devez utiliser.
Peut-être vaut-il même la peine de rechercher une bibliothèque tierce pour valider les données binaires une fois qu’elles sont reçues. Mais je m’égare.
1 Vérifier les autorisations de l’utilisateur
N’oubliez pas que chaque fois que nous avons créé le front-end, WordPress génère un nonce afin que nous puissions l’utiliser pour nous assurer que l’utilisateur a l’autorisation de télécharger le fichier.
En plus de vérifier le nonce, il y a plusieurs autres choses que j’aime vérifier, toutes regroupées dans une méthode appelée userCanSave.
Tout d’abord, rappelez-vous le 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>
Alors regardez comment je l’utilise dans le code. Tout d’abord, je définis la fonction 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);
}
Et puis j’appelle simplement cela au début du processus. Si ça échoue, je reviens.
<?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...
}
Je recommande d’afficher un message d’erreur, mais je m’égare sur ce point car il existe plusieurs façons de le faire dans le message.
2 Téléchargez le fichier
En supposant que l’utilisateur est autorisé à vérifier le fichier, il est alors possible de télécharger le fichier en toute sécurité. Le processus pour ce faire est simple mais nécessite encore un peu de travail avec l’API WordPress (à savoir avec la fonction wp_upload_bits ).
Tout d’abord, le fichier doit être extrait du global $_FILES de PHP, puis téléchargé. Lorsque vous faites cela, cependant, il est important de vous assurer que vous téléchargez un fichier avec l’extension de fichier correcte (au moins).
<?php
$file_type = explode('.', $filename);
$file_type = strtolower($file_type[count($file_type) - 1]);
if ('pdf' !== $file_type) {
// Give your feedback of choice here.
}
Si le type de fichier n’est pas un PDF, vous pouvez générer une erreur, simplement revenir (bien que je ne sois pas fan de cela) ou donner des commentaires à l’utilisateur (ce que je suis fan de faire).
<?php
if ($uploadFile['error']) {
// Your preferred method of feedback here.
}
La dernière étape, cependant, consiste à transférer le fichier dans le téléchargeur de médias.
3 Le charger dans le Media Uploader
La dernière étape de tout cela consiste à transférer le fichier dans le téléchargeur de médias. Pour ce faire, vous avez besoin de plusieurs choses du noyau WordPress :
- la librairie file.php,
- un tableau de pièces jointes nécessaire pour indiquer à WordPress ce qui est ajouté,
- une fonction API WordPress, wp_insert_attachment
- rediriger vers la page d’appel
Cela semble beaucoup, non ? Ce n’est pas si mal.
Je regroupe généralement l’inclusion de la bibliothèque de fichiers WordPress et le wp_insert_attachment dans un seul bloc.
Vous remarquerez que j’ai défini le type MIME sur pdf et que je m’assure que le titre n’inclut rien d’autre que le nom du fichier. Après cela, j’utilise wp_insert_attachment pour charger le fichier dans la médiathèque.
Le code complet pour cela est le suivant :
<?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']);
Après cela, je redirige vers la page qui a commencé tout cela (qui est généralement la page d’administration que nous avons vue dans le post précédent. Pour cela, je récupère le _wp_http_referer du tableau $_REQUEST de PHP .
<?php
wp_safe_redirect(
$_REQUEST['_wp_http_referer'],
301
);
exit;
Et cela redirigera l’utilisateur vers la page d’où il vient.
Et le fichier est téléchargé
À ce stade, nous avons défini ce que nous voulons faire :
- Offrir une expérience client décente,
- Téléversé le fichier dans la médiathèque (avec possibilité d’offrir des commentaires)
- Et redirigé vers la page qui a tout déclenché.
Certes, il y a beaucoup de place pour les commentaires à ce sujet, et je vous exhorte à l’adapter au besoin pour votre code, mais la base de ce dont vous avez besoin doit être fournie à la fois dans le post précédent et dans ce post.