0

I have a form, where I can upload a file:

function policies_edit_form($form, &$form_state, $data_array = NULL)
{
  ...
  $form['file'] = array(
        "#title" => "Document file",
        '#type' => 'file',
        '#size' => 22,
        );
  ...
}

function policies_edit_form_validate($form, &$form_state)
{
   $file = file_save_upload('file', array(
           'file_validate_extensions' => array('pdf doc docx'),
                                 ));
   if ($file) {
        // Save the file for use in the submit handler.
        $form_state['values']['file'] = $file;
    }
}

function policies_edit_form_submit($form, &$form_state)
{
  if($form_state['values']['file'] != '')
  {
    $form_state['values']['file']->status = FILE_STATUS_PERMANENT;
    $file = file_save($form_state['values']['file']);
  }
}

Despite I set the status to FILE_STATUS_PERMANENT, the file is uploaded to /tmp directory. After the upload is done, bash commands give this:

bash-4.2$ cd /tmp
bash-4.2$ ls -la 1_1.pdf
-rw-rw-r-- 1 apache apache 111531 Sep 16 16:06 1_1.pdf

And "temporary://" folder in the database:

mysql> SELECT * FROM file_managed;
+-----+-----+----------+---------------------+-----------------+----------+--------+------------+
| fid | uid | filename | uri                 | filemime        | filesize | status | timestamp  |
+-----+-----+----------+---------------------+-----------------+----------+--------+------------+
|   2 |   1 | 1.pdf    | temporary://1_1.pdf | application/pdf |   111531 |      1 | 1379333217 |
+-----+-----+----------+---------------------+-----------------+----------+--------+------------+

How can I upload it to public://policies/ folder? Should I manually set $form_state['values']['file']->uri or there is another way?

2

Just use a managed file element, it's much easier:

$form['fid'] = array(
  "#title" => "Document file",
  '#type' => 'managed_file',
  '#size' => 22,
  '#upload_location' => 'public://',
  '#upload_validators' => array(
    'file_validate_extensions' => array('pdf doc docx'),
  ),
);

Then remove the validation handler and change you submit handler to:

$file = file_load($form_state['values']['fid']);
$file->status = FILE_STATUS_PERMANENT;
file_save($file);

And you're done; Drupal handles moving the temp file into the right place for you, as well as adding relevant records to the file_managed/file_usage tables.

  • In drupal 8 it appears that the managed file element still works along with #upload_location and #upload_validators but you are required to add the PERM status on the file and ->add() the file usage yourself to avoid temp file deletion on cron and properly document usage. Cheers! – Michael Favia Aug 22 '18 at 15:28

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.