Una de las cosas que pueden ser más complejas o complicadas puede ser el subir archivos a través de un formulario a Drupal, pero vamos a ver como de una manera sencilla podemos hacerlo.
En este ejemplo vamos a subir un archivo gestionado, es decir, Drupal almacenará la información de ese archivo en la base de datos siendo una entidad File (Drupal\file\Entity\File), y la ID de esa entidad la vamos a almacenar en una configuración, es decir, vamos a usar un formulario de tipo "Drupal\Core\Form\ConfigFormBase".
Lo primero que necesitaremos, es el servicio "entity_type.manager" el cual se considera inyectado para este ejemplo, ya que vamos a trabajar con entidades, de modo que debemos saber que vamos a usarlo. Lo siguiente es en el método "buildForm" añadir el campo que usaremos para subir el archivo, como he comentado va a ser de tipo "managed_file" para que Drupal tenga constancia de que ese archivo existe y sea una entidad File.
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('escueladrupal.config');
$form['upload_file_field'] = [
'#type' => 'managed_file',
'#multiple' => FALSE,
'#title' => $this->t('Upload file'),
'#upload_location' => 'public://',
'#default_value' => $config->get('upload_file_field') ?: '',
'#upload_validators' => [
'file_validate_extensions' => ['pdf'],
],
];
return parent::buildForm($form, $form_state);
}
En ese método lo que estamos usando el un FormElement de tipo "managed_file" para subir el archivo y estamos indicando que se suba directamente como archivo público y estamos limitando las extensiones a solo PDF. Además, obtenemos la anterior configuración de la configuración "escueladrupal.config" y de su clave "upload_file_field".
Ahora que ya tenemos lo básico que es el campo donde subir los archivos, vamos a ver cómo hacer el submit para guardar el archivo y al mismo tiempo borrar el anterior en caso de que exista.
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('escueladrupal.config');
$id = $form_state->getValue(['upload_file_field', 0]);
$old_id = $config->get('upload_file_field');
if($id && $old_id && $id != $old_id[0]){
$old_file = $this->entityTypeManager->getStorage('file')->load($old_id[0]);
// Dado que se ha subido un nuevo archivo, borramos el viejo en caso de que exista.
if ($old_file) {
$old_file->delete();
}
$new_file = $this->entityTypeManager->getStorage('file')->load($id);
if($new_file){
// Tenemos que hacerlo permanente y guardarlo, si no, Drupal lo considera temporal
// y lo borra a las pocas horas.
$new_file->setPermanent();
$new_file->save();
}
$config->set('upload_file_field', $form_state->getValue('upload_file_field'))
->save();
}
parent::submitForm($form, $form_state);
}
Y listo, con ese código ya podréis subir archivos y guardarlos en la configuración para usarlos en cualquier lado de vuestro código. Es un poquito largo, pero realmente es sencillo, ya que obtenemos la nueva ID del archivo que se va a subir, ya que cuando se hace el submit del formulario Drupal internamente ya detecta que se sube un archivo, crea la entidad y nos indica la ID de la entidad en el valor del campo del formulario. De modo que solo tenemos que compararlo con la antigua y borrar o guardar la nueva.
Gracias Abel Salas por el código.
Me metí en la aventura de Drupal con la versión 6, y aquí estoy, 10 años después, escribiendo articulos y haciendo videos sobre Drupal, quien me lo iba a decir. Aunque he probado otros framworks y cms, me quedo con Drupal de lejos, pero Symfony y Django estan entre mis favoritos. Aficionado a la montaña, la bicicleta, y el comer, de eso que no falte.