18

I want to upload a file and I have to use form element type as 'file'. In submit function I am not able to get any proper data related to the file which I am uploading. SO Can anyone please help me to resolve this. Please find the below code:

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['test_CERTIFICATE'] = [
    '#type' => 'file',
    '#title' => $this->t('Certificate'),
    '#description' => $this->t('Your Certificate (.pem file)').': '.\Drupal::state()->get('test_CERTIFICATE_NAME'),           
  ];
  
  return parent::buildForm($form, $form_state);
}

Submit function:

public function submitForm(array &$form, FormStateInterface $form_state) {
  parent::submitForm($form, $form_state);

  $validators = array('file_validate_extensions' => array('pem'));
  $files = file_save_upload('test_CERTIFICATE', $validators, 'public://certfiles', FILE_EXISTS_REPLACE);
  $file = File::load($files[0]);
  if ($file) {
    kint($files); exit;
    // here control is not coming
    $file->setPermanent();
    $file->save();
  }
}
1

2 Answers 2

26

I had the same problem with the file form element. Solved this by using managed_file and providing the upload location and validators in the form element:

$form['test_CERTIFICATE'] = [
  '#type' => 'managed_file',
  '#title' => $this->t('Certificate'),
  '#upload_location' => 'private://certfiles',
  '#upload_validators' => [
    'file_validate_extensions' => ['pem'],
  ],
];

Then in submit:

use Drupal\file\Entity\File;

$form_file = $form_state->getValue('test_CERTIFICATE', 0);
if (isset($form_file[0]) && !empty($form_file[0])) {
  $file = File::load($form_file[0]);
  $file->setPermanent();
  $file->save();
}
4
  • Hi, thank you for your suggestion. even I got success with this method. But here, how can I prevent entry of duplicate files in the public folder. Because of this reason I opted for "file" type. in this we can do by using file_save_upload so..
    – Suraj
    Commented Jul 3, 2017 at 6:15
  • The temporary file is deleted automatically, I think by default within 6 hours. If you don't want to wait you can delete it after you've saved the permanent file.
    – 4uk4
    Commented Jul 3, 2017 at 6:28
  • I am not telling about temporary file buddy. if i uploaded same file twice, that time its keeping both the files in the public folder by appending random number to latest file. this type of duplication am telling.
    – Suraj
    Commented Jul 3, 2017 at 6:52
  • You could check for an existing file with the same name before you make the temporary file permanent.
    – 4uk4
    Commented Jul 3, 2017 at 7:15
16

You can access files data uploaded through "file" field using the following code (from D8.5 core/modules/config/src/Form/ConfigImportForm.php)

$all_files = $this->getRequest()->files->get('files', []);
$file = $all_files['test_CERTIFICATE'];
$file_path = $file->getRealPath();
5
  • Would love to know reason for downvote. Unnecessarily complex, or bad practice?
    – almcnicoll
    Commented Jul 7, 2018 at 23:47
  • 2
    I believe this is a more correct to the question, when you use '#type' => 'file' this is the way to get the file.
    – andeersg
    Commented Dec 3, 2018 at 8:17
  • @almcnicoll The reason for the downvote was that there is no reason to get into this low level of file upload. It's just bad advice. Commented Feb 11, 2019 at 12:08
  • 6
    Upvoted. This is the clearest way of uploading unmanaged files. To obtain the original file name you may use $file_name = $file->getClientOriginalName(), and then save the file to the final location via file_unmanaged_copy($file_path, "PATH/$file_name");.
    – Michal Gow
    Commented May 22, 2019 at 10:53
  • 1
    Thanks for posting, CamelCode. In certain advanced implementations, this information is useful. Upvoted. Commented Feb 6, 2020 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.