Téléchargement de fichier Api de formulaire

9

J'ai le code suivant dans mon formulaire.

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

Sur le gestionnaire de soumission, il renvoie le nom du fichier mais il n'enregistre pas le fichier et ne renvoie pas d'objet fichier. Que dois-je faire d'autre?

Ce que j'essaie de faire est de créer un bloc où vous pouvez télécharger un fichier qu'il est enregistré dans le champ de fichier d'un nœud.

Lucy
la source

Réponses:

8

Jetez un œil à file_save_upload () et aux fonctions qui l'appellent.

La fonction gérera la validation du fichier et l'enregistrera dans un nouvel emplacement. Dans Drupal 7, cela ajoute également le fichier à la table file_managed.
Notez que le fichier sera stocké en tant que fichier temporaire, assurez-vous donc de définir le statut du fichier sur permanent par la suite.

Vous souhaiterez probablement implémenter la fonction file_save_upload dans le crochet de validation de votre formulaire (avant le gestionnaire de soumission), afin que vous puissiez alerter l'utilisateur si le téléchargement du fichier a échoué ou ne répond pas à vos exigences de validation.

Si le nom du champ d'image que vous essayez de valider est image, alors le premier paramètre de file_save_upload doit être image, en tant que tel:

$ path = file_save_upload ('image', ...);

Cette fonction renvoie ensuite le chemin sur le serveur sur lequel l'image a été téléchargée (vous pouvez par exemple stocker ce chemin dans un champ de base de données personnalisé).

zroger
la source
4

Il vous manque ceci dans votre définition de formulaire:

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

Voici la logique que j'utilise pour créer un widget de téléchargement de fichier sur un formulaire:

   // 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.'),
                       ); 

Et voici l'équivalent de cette logique, que j'ai dans le rappel de validation de mon formulaire, car j'ai des restrictions de nom de fichier d'image dans ma logique, mais vous pouvez le placer dans le rappel de soumission si vous le souhaitez:

   // @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.'));
   }

c'est ça.

Blake Senftner
la source
3
Vous n'avez en fait pas besoin $form['#attributes']['enctype']dans Drupal 7. Il est pris en charge automatiquement
user724228
3
vous n'avez pas besoin de multipart/form-datafor drupal 7, il est intégré à drupal 7 lorsque vous utilisez un champ de fichier.
FLY
@bsenftner J'utilise la même méthode que vous, mais quand je l'essaye, je trouve cela $file === null, ce qui signifie que no file was uploaded(selon les spécifications: api.drupal.org/api/drupal/includes!file.inc/function /… ) Que dois-je faire dans ce cas? Comment puis-je déboguer ce genre de chose?
Shawn
@Shawn: travaillez-vous dans Drupal 7? Cette logique est testée pour Drupal 6. Je n'ai pas encore eu l'occasion de l'essayer sur D7, donc, si vous êtes en D7 alors "je ne sais pas". Si vous êtes en D6, cela devrait fonctionner - êtes-vous sûr que 'fid' est le nom de champ de votre widget de téléchargement de fichiers?
Blake Senftner
Oui aux deux questions: je suis sûr que j'ai le bon nom pour le widget et j'utilise D7. Je pense que je devrais en faire une nouvelle question ...
Shawn
3

J'ai une fonction de validation générique que j'utilise principalement dans les thèmes qui doivent prendre en charge le téléchargement d'images. Vous pourrez peut-être l'utiliser tel quel ou avec des modifications mineures, mais cela devrait vous mener loin.

/**
 * 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.'));
    }
  }
}

En utilisant cette fonction, vous obtiendrez le chemin de fichier comme gestionnaire de soumission de la valeur dans le formulaire. Vous voudrez peut-être l'ID de fichier à la place, selon votre utilisation.

googletorp
la source