0

I am trying to implement a file upload form in which files are saved. I had written the following code

<?php

/**
 * @file
 * Contains \Drupal\avenue_product_import\Form\avenue_product_importForm.
 */

namespace Drupal\avenue_product_import\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;

class AvenueForm extends FormBase {

  public function getFormId() {
    return 'AvenueForm';
  }


  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['description'] = [
      '#markup' => '<p>Use this form to upload a CSV file of Data</p>',
    ];

    $form['import_csv'] = [
      '#type'              => 'managed_file',
      '#title'             => t('Upload file here'),
      '#upload_location'   => 'public://importcsv/',
      '#default_value'     => '',
      "#upload_validators" => ["file_validate_extensions" => ["csv"]],
      '#states'            => [
        'visible' => [
          ':input[name="File_type"]' => ['value' => t('Upload Your File')],
        ],
      ],
    ];

    $form['actions']['#type'] = 'actions';


    $form['actions']['submit'] = [
      '#type'        => 'submit',
      '#value'       => $this->t('Upload CSV'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

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

    /* Fetch the array of the file stored temporarily in database */
    $csv_file = $form_state->getValue('import_csv');

    /* Load the object of the file by it's fid */
    $file = File::load($csv_file[0]);

    /* Set the status flag permanent of the file object */
    $file->setPermanent();

    /* Save the file in database */
    $file->save();

    drupal_set_message('File Uploaded Successfully');
  }

}

But here the problem is if the filename in which I am uploading is same. It is getting renamed. But I want to replace old with the new one. How can I achieve this? I had seen file_move() and file_save_upload() function. What changes should I make to replace existing filename with the newly uploaded CSV file?

  • There is a thread on Drupal.org regarding this. Somewhere in core, when a file is saved with the file field widget or managed file, FILE_EXISTS_RENAME is the default with no way to override it yet. drupal.org/project/drupal/issues/2648816 – Kevin Sep 19 '18 at 13:20
  • If you do this, be sure to also adjust htaccess/caching rules in regards to Varnish etc if in use... so the browser gets the latest version of the file. We did this for a client for a file field containing PDFs. – Kevin Sep 19 '18 at 13:26
1

This would save always save the latest upload to public://importcsv/avenue.csv:

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

  /* Fetch the array of the file stored temporarily in database */
  $csv_file = $form_state->getValue('import_csv');

  /* Load the object of the file by it's fid */
  $file = File::load($csv_file[0]);

  $file_real_path = \Drupal::service('file_system')->realpath($csv_file->getFileUri());
  $file_contents = file_get_contents($file_real_path);
  file_unmanaged_save_data($file_contents, 'public://importcsv/avenue.csv', FILE_EXISTS_REPLACE);

  drupal_set_message('File Uploaded Successfully');
}
-1

You could check if a file exists with that name beforehand? If so, remove it and continue saving.

https://api.drupal.org/api/drupal/core%21includes%21file.inc/function/file_delete/8.5.x

or

https://api.drupal.org/api/drupal/core!lib!Drupal!Core!File!FileSystem.php/function/FileSystem%3A%3Aunlink/8.2.x

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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