Formulario de carga de archivos Api

9

Tengo el siguiente código en mi formulario.

$form['new']['upload'] = array(
  '#type' => 'file',
  '#title' => t(''),
  '#size' => 40,
);

En el controlador de envío, devuelve el nombre del archivo pero no guarda el archivo y devuelve un objeto de archivo. ¿Qué más necesito hacer?

Lo que intento hacer es crear un bloque donde pueda cargar un archivo que se guarda en el campo de archivo de un nodo.

Lucy
fuente

Respuestas:

8

Eche un vistazo a file_save_upload () y las funciones que lo llaman.

La función manejará la validación del archivo y lo guardará en una nueva ubicación. En Drupal 7, esto también agrega el archivo a la tabla file_managed.
Tenga en cuenta que el archivo se almacenará como un archivo temporal, así que asegúrese de establecer el estado del archivo en permanente después.

Probablemente desee implementar la función file_save_upload dentro del enlace de validación de su formulario (antes del controlador de envío), para que pueda alertar al usuario si la carga del archivo falló o no cumplió con sus requisitos de validación.

Si el nombre del campo de imagen que está intentando validar es image, entonces el primer parámetro de file_save_upload debería ser image, como tal:

$ ruta = file_save_upload ('imagen', ...);

Esta función devolverá la ruta en el servidor en el que se cargó la imagen (por lo que puede almacenar esa ruta en un campo de base de datos personalizado).

zroger
fuente
4

Te falta esto en la definición de tu formulario:

   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit

Aquí está la lógica que uso para crear un widget de carga de archivos en un formulario:

   // these give us the file upload widget: 
   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit
   $form['fid'] = array( '#title'        => t('Upload image'),
                         '#type'         => 'file',
                         '#description'  => t('Images must be one of jpg, bmp, gif or png formats.'),
                       ); 

Y aquí está la contraparte de esa lógica, que tengo en la devolución de llamada validada de mi formulario, porque tengo restricciones de nombre de archivo de imagen en mi lógica, pero puede colocar esto en la devolución de llamada de envío si lo desea:

   // @see: http://api.drupal.org/api/function/file_save_upload/6
   // $file will become 0 if the upload doesn't exist, or an object describing the uploaded file
   $file = file_save_upload( 'fid' );
   error_log( 'file is "'.print_r( $file, true ).'"' );
   if (!$file) {
      form_set_error('fid', t('Unable to access file or file is missing.'));
   }

Eso es.

Blake Senftner
fuente
3
En realidad no es necesario $form['#attributes']['enctype']en Drupal 7. Se ocupa automáticamente
user724228
3
no necesitas el multipart/form-datapara drupal 7, está construido en drupal 7 cuando usas un campo de archivo.
VUELO
@bsenftner Estoy usando el mismo método que usted, pero cuando lo pruebo, lo encuentro $file === null, lo que significa que no file was uploaded(de acuerdo con las especificaciones: api.drupal.org/api/drupal/includes!file.inc/function / ... ) ¿Qué debo hacer en ese caso? ¿Cómo puedo depurar este tipo de cosas?
Shawn
@ Shawn: ¿estás trabajando en Drupal 7? Esta lógica está probada para Drupal 6. Todavía no he tenido la oportunidad de probarlo en D7, por lo tanto, si estás en D7, entonces "No sé". Si está en D6, entonces debería estar funcionando: ¿está seguro de que 'fid' es el nombre de campo de su widget de carga de archivos?
Blake Senftner
Sí a ambas preguntas: estoy seguro de que tengo el nombre correcto para el widget y estoy usando D7. Creo que debería hacer esta una nueva pregunta ...
Shawn
3

Tengo una función de validación genérica que uso principalmente en temas que necesitan soportar la carga de imágenes. Es posible que pueda usarlo como tal o con pequeños cambios, pero esto debería llevarlo lejos.

/**
 * Validate/submit handler used for handling image uploads
 */
function module_upload_image_validate($form, &$form_state) {
  // This is not needed, I use this to use the same validate function
  // for several fields.
  $key = $form['#key'];
  $file = file_save_upload($key, array(
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('png gif jpg jpeg'),
  ));
  if ($file) {
    // Get the image info to get the correct extension for the uploaded file.
    $info = image_get_info($file->filepath);
    if (file_move($file, 'destination/filename'. $info['extension'], FILE_EXISTS_REPLACE)) {
      // Mark the file for permanent storage.
      file_set_status($file, FILE_STATUS_PERMANENT);
      // Update the files table.
      drupal_write_record('files', $file, 'fid');
      $form_state['values'][$key] = $file->filepath;
    }
    else {
      form_set_error($key, t('Failed to write the uploaded file to the site’s files folder.'));
    }
  }
}

Con esta función, obtendrá la ruta del archivo como el valor en el controlador de envío de formularios. Es posible que desee la identificación del archivo, dependiendo de su uso.

googletorp
fuente