I have this code in the submitForm() function of a custom form I've created:

$fid = $form_state->getValue('my_form_file_field');
$file = \Drupal\file\Entity\File::load($fid);

Is this right? I can't seem to get the filename of the file chosen by the user (via the form's 'choose file' button).

Thanks!

Comments

Jaypan’s picture

Well the syntax is correct.

You haven't given us enough information to know what you are trying to do to tell you if your code is correct or not though.

CatsFromStonehenge’s picture

The full code is below. I want to get the filename from the form field of type 'file'. This is where the user can click on a 'Choose File' button in a form, and a file browser dialog appears. Once they choose a file, I want to be able to get the full path and filename, of the file they chose.

<?php
/**
 * @file
 * Contains \Drupal\amazing_forms\Form\ContributeForm.
 */

namespace Drupal\amazing_forms\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\UrlHelper;

/**
 * Contribute form.
 */
class ContributeForm extends FormBase {
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'amazing_forms_contribute_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['my_file'] = array(
      '#type' => 'file',
      '#title' => t('Scanned Document'),
      '#description' => t('Upload the scanned document. Allowed extensions: jpg, jpeg, png, gif')
    );
    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Submit'),
    );
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Display result.
    foreach ($form_state->getValues() as $key => $value) {
      drupal_set_message($key . ': ' . $value);
    }

    // ****** I want to get the filename here ******
    $fid = $form_state->getValue('my_file');
    drupal_set_message("****$fid****");
    $file = \Drupal\file\Entity\File::load($fid);
  }
}
?>
Jaypan’s picture

Using #file as the type will not handle the saving of the file for you, neither will there be an FID. It only handles the upload to the server.

You should use the #managed_file type, and that will save the file to the files directory, as well as create a database entry with an FID. Then you can use this:

public function submitForm(array &$form, FormStateInterface $form_state) {
    // Display result.
    foreach ($form_state->getValues() as $key => $value) {
      drupal_set_message($key . ': ' . $value);
    }

    // ****** I want to get the filename here ******
    $fid = $form_state->getValue('my_file');
    $file = \Drupal\file\Entity\File::load($fid);
    $filename = $file->name; //or maybe $file->filename
  }
CatsFromStonehenge’s picture

Thanks. The final code was:

if ($form_state->hasFileElement())
{
  drupal_set_message("This form has a file element.");
  $passport_scan_file_array = $form_state->getValue('passport_scan');
  if (is_array($passport_scan_file_array))
  {
    if (isset($passport_scan_file_array[0]))
    {
      $passport_scan_file_id = $passport_scan_file_array[0];
      $file = \Drupal\file\Entity\File::load($passport_scan_file_id);
      if ($file != NULL)
      {
        $filename = $file->getFilename();
        drupal_set_message('Filename: ' . $filename);
      }
    }
  }
}