2

I am implementing a module (in Drupal 7) that allows the user to upload or remove a file using the managed_file form type. I have looked at the form APIs and it states that info about the file should appear in ['values]['form_name'] but that is not what I see. To find any info about the uploaded file I need to look in ['input']['form_name'][0]. And when I do, the only values available are ['fid'] (which is always set to the file id) and ['UPLOAD'] (which is always NULL). The problem is that I don't know if the user wanted to add or remove the file. How do I determine this? What have I screwed up?

Here is my form:

$form_array = array(
  '#type' => 'managed_file',
  '#title' => t('File'),
  '#description' => 'The file associated with this submission',
  '#name' => 'obj_file',
  '#upload_location' => 'private://temp',
  '#default_value' => $submission->file,
);

Here is the submit portion:

if ($file_id == 0 && $submission->file) {
  $file = file_load($submission->file);
  file_delete($file);
} else {
  $file = file_load($file_id);
  $file->status = FILE_STATUS_PERMANENT;
  file_save($file);
  file_usage_add($file, 'my_module', 'submission', $submission->id);
}

According to the API file id should be 0 if removed but it never is in my case. Is it possible to hook into file_managed_file_submit()? That would at least provide an avenue to see which button is being pressed.

Any help or insights would be appreciated!

1 Answer 1

4

The file managed_file field is used to upload files I am not sure if it can be used to delete a file from the server if that is what you are trying to do.

The process actually works as follows

When you click the upload button it uploads the file to the server and stored the fid to the field itself and this is the only value we need in the submit function to handle the file as we would using the file_load function to load the file and get the file object using the fid alone.

Now when the user clicks the remove button the field value is set to 0. But the actual file is not deleted from the server and the fid is still stored in the file table.

the '#default_value' should be set to variable_get('image_example_image_fid', ''), this would be used in our form submit function when the field is 0.

The documentation is talking about deleting the file from the temporary table and the server. You would need to remove it in your submit function.

Please check the example from the examples module

if ($form_state['values']['image_example_image_fid'] != 0) {
    // The new file's status is set to 0 or temporary and in order to ensure
    // that the file is not removed after 6 hours we need to change it's status
    // to 1. Save the ID of the uploaded image for later use.
    $file = file_load($form_state['values']['image_example_image_fid']);
    $file->status = FILE_STATUS_PERMANENT;
    file_save($file);

    // When a module is managing a file, it must manage the usage count.
    // Here we increment the usage count with file_usage_add().
    file_usage_add($file, 'image_example', 'sample_image', 1);

    // Save the fid of the file so that the module can reference it later.
    variable_set('image_example_image_fid', $file->fid);
    drupal_set_message(t('The image @image_name was uploaded and saved with an ID of @fid and will be displayed using the style @style.', array('@image_name' => $file->filename, '@fid' => $file->fid, '@style' => $form_state['values']['image_example_style_name'])));
  }
  // If the file was removed we need to remove the module's reference to the
  // removed file's fid, and remove the file.
  elseif ($form_state['values']['image_example_image_fid'] == 0) {
    // Retrieve the old file's id.
    $fid = variable_get('image_example_image_fid', FALSE);
    $file = $fid ? file_load($fid) : FALSE;
    if ($file) {
      // When a module is managing a file, it must manage the usage count.
      // Here we decrement the usage count with file_usage_delete().
      file_usage_delete($file, 'image_example', 'sample_image', 1);

      // The file_delete() function takes a file object and checks to see if
      // the file is being used by any other modules. If it is the delete
      // operation is cancelled, otherwise the file is deleted.
      file_delete($file);
    }

    // Either way the module needs to update it's reference since even if the
    // file is in use by another module and not deleted we no longer want to
    // use it.
    variable_set('image_example_image_fid', FALSE);
    drupal_set_message(t('The image @image_name was removed.', array('@image_name' => $file->filename)));
  }
2
  • Thanks, I keep forgetting about the examples module (self: attach post-it note to forehead). I will take it a look at it to see what I am missing but as I mentioned in my question, I am not seeing the entries that the API says should be there.
    – user5013
    Commented Jan 25, 2013 at 21:28
  • Which particular value in the documentation is that you are not getting. Commented Jan 26, 2013 at 5:07

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.