39

I am having some issues with the managed_file type. Whenever I try to edit and save a form that has a managed_file element in it an error occurs: The file used in the Picture field may not be referenced.

This is the code I'm using:

function foo_form ($form, &$form_state, $foo) {  
  ...     
  $form['file'] = array(
    '#type' => 'managed_file',
    '#title' => t('Picture'),
    '#default_value' => (isset($foo->file->fid) ? $banner->foo->fid : ''),
    '#upload_location' => variable_get('foo_upload_location'),
  );

  if (isset($foo->file)) {
    $form['current_file'] = array(
      '#type' => 'hidden',
      '#value' => $foo->file->fid,
    );
  }
  ...
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
 }

function foo_form_submit ($form, &$form_state) {
  $foo = (object)$form_state['values'];

  $current_file_set = isset($form_state['values']['current_file']);

  if ($form_state['values']['file'] != 0 && !$current_file_set) {
    // Load the file uploaded in the form.
    $file = file_load($form_state['values']['file']);

    $file->status = FILE_STATUS_PERMANENT;

    file_save($file);

    $foo->file = $file->fid;
  } else if ($form_state['values']['file'] != 0 && $current_file_set) {

    // If we are uploading a different picture, delete the old one and save the
    // new one. If not, don't do anything.
    if ($form_state['values']['current_file'] != $form_state['values']['file']) {
      file_delete(file_load($form_state['values']['current_file']));
      // Load the file uploaded in the form.
      $file = file_load($form_state['values']['file']);

      $file->status = FILE_STATUS_PERMANENT;

      file_save($file);

      $foo->file = $file->fid;
    }
  } else {
    file_delete(file_load($form_state['values']['current_file']));
    $foo->file = null;
  }

  ...
}

I traced the error back to the file_managed_file_validate function in modules/file/file.module but don't know anything about the file references.

39

The solution is to add a call to file_usage_add after the file is saved. This call adds a reference to the file in the database. The file_managed_file_validate function will spot the reference and won't trigger the error.

file_usage_add($file, 'foo', 'foo', $foo->id);

This isn't documented in the Form API under the managed_file example.

This issue is being discussed on the Drupal documentation issues: link

  • 3
    +1 Just been tearing my hair our over this, adding a file usage record solves the problem immediately. Thank you! – Clive Mar 14 '12 at 12:04
  • Thankfully it is now added to the managed_file example. But it wasn't in whatever example I'd followed so this answer was a lifesaver! – Joshua Stewardson Jul 6 '12 at 1:17
  • @Clive What is about saving files from template settings?! There is no module to act as parameter in that function! – SaidbakR Jul 22 '14 at 20:04
  • 1
    @sємsєм just use the name of the theme - the string itself isn't validated, it just needs to be something unique to the thing that's tracking it - module name is used for namespacing all over Drupal so that's the convention that stuck – Clive Jul 22 '14 at 20:14
  • @Clive Could you please get a look at this question: drupal.stackexchange.com/questions/124373/… – SaidbakR Jul 22 '14 at 20:31

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.