Carga de archivos en WordPress Revisited, Parte 2 – El lado del servidor
Antes de saltar directamente al código para esto, quería mencionar dos cosas:
- Sí, he cubierto esto con cierto detalle hace un tiempo,
- Y esta es la segunda parte de una serie de dos partes.
Si no has leído la primera parte, hazlo primero. La idea es que el código funcione junto con lo que voy a cubrir en esta publicación para asegurarme de que tanto el lado del cliente como el lado del servidor estén cubiertos.
En última instancia, la razón para desglosarlo de esta manera no es solo para asegurarse de que las cosas se hagan correctamente, sino también para asegurarse de que el usuario tenga la experiencia más positiva posible.
Dicho esto, aquí se explica cómo cargar archivos en WordPress en el lado del servidor.
Subir archivos en WordPress en el lado del servidor
Tenga en cuenta que, aunque hay algunas comprobaciones de seguridad que pueden y deben realizarse, todavía tengo que encontrar una manera que sea completamente infalible para detectar que el archivo que se está cargando es del tipo adecuado.
Eso significa que todavía existe la posibilidad de que se cargue un tipo de archivo incorrecto. Si esto es malicioso o no, obviamente depende del usuario final. Solo comparto esto para que quede claro que el código que voy a mostrar es tan bueno como puedo proporcionar, pero que todavía hay un nivel de discreción que debe usar.
Quizás valga la pena incluso buscar una biblioteca de terceros para validar los datos binarios una vez que se reciben. Pero yo divago.
1 Verificar permisos de usuario
Recuerde que cada vez que creamos el front-end, hacemos que WordPress genere un nonce para que podamos usarlo para asegurarnos de que el usuario tiene permiso para cargar el archivo.
Además de verificar el nonce, hay varias otras cosas que me gusta verificar, todas las cuales están envueltas en un método llamado userCanSave.
Primero, recuerda el 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>
Luego mira cómo lo uso en el código. Primero, defino la función 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);
}
Y luego simplemente llamo a esto al comienzo del proceso. Si falla, vuelvo.
<?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...
}
Recomiendo mostrar un mensaje de error, pero estoy divagando en este punto ya que hay algunas formas de hacer esto dentro de la publicación.
2 Sube el archivo
Suponiendo que el usuario tiene permiso para verificar el archivo, entonces es seguro cargar el archivo. El proceso para hacer esto es sencillo pero aún requiere un poco de trabajo con la API de WordPress (es decir, con la función wp_upload_bits ).
Primero, el archivo debe tomarse de $_FILES global de PHP y luego cargarse. Sin embargo, al hacer eso, es importante asegurarse de que está cargando un archivo con la extensión de archivo correcta (como mínimo).
<?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 el tipo de archivo no es un PDF, puede arrojar un error, simplemente regresar (aunque no soy un fanático de esto) o dar algunos comentarios al usuario (lo cual soy fanático de hacer).
<?php
if ($uploadFile['error']) {
// Your preferred method of feedback here.
}
Sin embargo, el último paso es obtener el archivo en el cargador de medios.
3 Cargarlo en el cargador de medios
El último paso en todo esto es obtener el archivo en el cargador de medios. Para hacer esto, necesita varias cosas del núcleo de WordPress:
- la biblioteca file.php,
- una matriz de archivos adjuntos necesaria para decirle a WordPress lo que se está agregando,
- una función API de WordPress, wp_insert_attachment
- redirigir de nuevo a la página de llamada
Suena como mucho, ¿verdad? No es tan malo.
Normalmente agrupo la inclusión de la biblioteca de archivos de WordPress y wp_insert_attachment en un solo bloque.
Notará que configuro el tipo MIME en pdf y me aseguro de que el título no incluya nada excepto el nombre del archivo. Después de eso, uso wp_insert_attachment para cargar el archivo en la biblioteca multimedia.
El código completo para eso es el siguiente:
<?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']);
Después de eso, redirijo de nuevo a la página que inició todo esto (que suele ser la página de administración que vimos en la publicación anterior). Para esto, tomo el _wp_http_referer de la matriz $_REQUEST de PHP .
<?php
wp_safe_redirect(
$_REQUEST['_wp_http_referer'],
301
);
exit;
Y eso redirigirá al usuario a la página de donde vino.
Y El Archivo Se Sube
En este punto, hemos establecido lo que queremos hacer:
- Ofrezca una experiencia decente del lado del cliente,
- Subió el archivo a la biblioteca de medios (con oportunidades para ofrecer comentarios)
- Y redirigido de nuevo a la página que comenzó todo.
De acuerdo, hay mucho espacio para comentarios en esto, y lo insto a que lo adapte según sea necesario para su código, pero la base de lo que necesita se debe proporcionar tanto en la publicación anterior como en esta publicación.