I set the private file system to /system/files/export , I create a file in private directory programmatically and it not belong to any field ,and show link to user , I implement Hook_file_download , I want check some condition in it but when user click on link to download the file created in private path it return me Forbidden and mymodule_file_download not tirggered ( I put some code to it , even die but never called). I clear cache but noting changes, the link that showed for user is http://localhost/mytestdrupal/system/files/export/Export-couponcards-1393307265.csv where is problem?

Part of my code to create file in submit

function mymodule_export_form_submit($form, $form_state) {
    $temp1 = variable_get('file_private_path');
    if (!file_prepare_directory($temp1, FILE_CREATE_DIRECTORY)) {
        drupal_set_message(t('Problem in write file in directory'), 'error');
    $filename = 'Export-file'. '.csv';
    $filepath = $temp1 . '/' . $filename;
    $df = fopen($filepath, 'w');
    if (!$df) {
        drupal_set_message(t('Can not write file in') . $filepath, 'error');
            fputcsv($df, array('code', 'name'));
            fputcsv($df, array('test','test'));

    $path = file_create_url($filepath);
    drupal_set_message(t('Export done. ') . '<a href="' . $path . '">' . t('Download export file') . '</a>');
  • Can you post link shown to user ? It should be system/files/*** – Anil Sagar Feb 25 '14 at 6:44
  • link is http://localhost/mytestdrupal/system/files/export/Export-couponcards-1393307265.csv – Yusef Feb 25 '14 at 6:49
  • Can you post the hook implementation ? That will give us better idea what you are doing and why you are getting forbidden message .. – Anil Sagar Feb 25 '14 at 6:55
  • 1. Are folder and files permissions correct? 2. check virtual host's (.htaccess) configuration. 3. Check server log, may be you can find something interesting. – xurshid29 Feb 25 '14 at 7:06
  • Maybe I'm missing something obvious but it looks like the above code is saving a file to the public directory variable_get('file_public_path'); not the private file path. Note also the menu callback uses system/files but your private folder path should probably be different, e.g sites/default/files/private or somewhere outside the webroot. – David Thomas Feb 25 '14 at 8:56

hook_file_download working perfectly, List of steps which worked for me

  1. I made File System to Private
  2. Created a File Field in Article Content Type and marked it as Private In Settings
  3. Uploaded a PDF File
  4. Link to file is something link below


Created a custom module with hook_file_download, When ever i access above URL and visit any page i can see drupal set message "Hi"

function drup_custom_file_download($uri) {
  • I said I created file programmatically ,and not belong to any field – Yusef Feb 25 '14 at 6:50
  • How did you created programatically ? Can you post the code. It should be through file API so that any entry exist in file Table. – Anil Sagar Feb 25 '14 at 6:51
  • I update question with part of my code that create file – Yusef Feb 25 '14 at 7:22
  • Can you save your file using api.drupal.org/api/drupal/includes%21file.inc/function/… and try the same ? – Anil Sagar Feb 25 '14 at 7:28
  • It doesn't have to be in a file field or the drupal managed files table. If you want access to be controlled by file_file_download() then you do but if you have your own hook_file_download() implementation you don't. – rooby Feb 25 '14 at 7:28

First you need to verify your file is being saved to the correct place.

You say you want to save to a sub-directory 'export' but that is not what your code is doing.

You should be saving to the private file system, not the public one. So variable_get('file_private_path', '') instead of variable_get('file_public_path').

Then append you export directory, so it would be:

$temp1 = variable_get('file_private_path', '') . '/export';

Then if you file is successfully saved at /sites/default/files/private/export (or wherever your private files should be), then you are ready for the next step.

When making the link to the file you have to pass in a uri, so

$path = file_create_url($filepath);

should be something like:

$path = file_create_url('private://export/' . $filename);

Using the 'private' stream wrapper means that internal links match to /sites/default/files/private (or whatever you have variable_get('file_private_path', '') set to) and external links generate like www.example.com/system/files/...

For more information see: DrupalPrivateStreamWrapper

  • sorry, after private not worked , I changed it to public and paste here without notice that it is change to public, it public , I set the private file system to 'system/files/export' ; – Yusef Feb 25 '14 at 10:06
  • Private file system should be something like sites/default/files/private, unless you actually have a directory on the file system that is system/files. system/files is a drupal url, not an actual directory on the file system. – rooby Feb 25 '14 at 10:16
  • First I set it to something if 'defaults/files/private/` after I chnage it to /system/files/export there are exist directory and file create correctly (I check it) – Yusef Feb 25 '14 at 10:30

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.