Drupal And the Disappearing Images Mystery

You are here

Contact

Israel Office

+972-52-838-7222

+972-52-430-5252

Europe office

+33-695-805-004

02.12.2014
Drupal And the Disappearing Images Mystery
submitted by: ehud

After working many years with a specific framework, you sometimes face difficulties that in other situations, specifically while learning a new language or framework would not even challenge you.
One example for such a case is one I’ve encountered this past week, and to tackle it, all I’ve needed to do is to actually read the Drupal docs and not just flip through it.
One of my clients came to me and told me that all of the images he’s uploading to his site are deleted from the files directory of his Drupal project after several hours.
After checking that the images are created successfully in the Drupal’s temp directory and are then moved to the files directory as they should, I begun checking for any file/image related modules and any Drupal configurations that could hint a relation to the problem.
Checking those off I’ve started to look at custom code developed by our programmers, as this is a more time-consuming task I’ve not started with it but knew from the beginning that this is probably where the culprit could be found.
While carefully combing the code I’ve landed upon a form api piece of code related to an image field similar to this:

<!--?php
// Use the #managed_file FAPI element to upload an image file.
$form['image_example_image_fid'] = array(
  '#title' => t('Image'),
  '#type' => 'managed_file',
  '#description' => t('The uploaded image will be displayed on this page using the image style chosen below.'),
  '#default_value' => variable_get('image_example_image_fid', ''),
  '#upload_location' => 'public://image_example_images/',
);
?>

This piece of code will add a nice file/image field to the page and will allow you to attach an image to the current entity.
After finding the “managed_file” type documentation the problem and the solution was clear.

Note: New files are uploaded with a status of 0 and are treated as temporary files which are removed after 6 hours via cron. Your module is responsible for changing the $file objects status to FILE_STATUS_PERMANENT and saving the new status to the database. Something like the following within your submit handler should do the trick.

 <!--?php
 // Load the file via file.fid.
 $file = file_load($form_state['values']['my_file_field']);
 // Change status to permanent.
 $file->status = FILE_STATUS_PERMANENT;
 // Save.
 file_save($file);
 // Record that the module (in this example, user module) is using the file. 
 file_usage_add($file, 'user', 'user', $account->uid); 
?>

So in order to prevent the (weird – in my opinion) automatic 6 hour cron deletion of the uploaded images you have to add a submit handler and inside it add that piece of code.
To clarify and help those in need, this is an expanded example of a form and submit functions.

$form = drupal_get_form('my_module_example_form');
...
function my_module_example_form($form, &$form_state) {
  $form['image_example_image_fid'] = array(
    '#title' => t('Image'),
    '#type' => 'managed_file',
    '#description' => t('The uploaded image will be displayed on this page using the image style chosen below.'),
    '#default_value' => variable_get('image_example_image_fid', ''),
    '#upload_location' => 'public://image_example_images/',
  );

    $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}
function my_module_example_form_validate($form, &$form_state) {
  // Validation logic.
}
function my_module_example_form_submit($form, &$form_state) {
  // Submission logic.

   // Load the file via file.fid.
   $file = file_load($form_state['values']['my_file_field']);
   // Change status to permanent.
   $file->status = FILE_STATUS_PERMANENT;
   // Save.
   file_save($file);
   // Record that the module (in this example, user module) is using the file. 
   file_usage_add($file, 'user', 'user', $account->uid);
   // a more generic example of file_usage_add
   // file_usage_add($file, 'my_module_name', 'user or node or any entity', 'that entity id');
   // you don't need to use "file_usage_add" if you're not attaching the image to an entity
}

Originally posted on my personal blog.

 

Add new comment

blogs