Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I want to create file programmatically ,I want only authenticated user can download it and direct access return 403 to them, I search and saw How Can I Make File Downloads Available Only to Authenticated Users? but my files not field files(not record in file table) and programmatically I create them,

    $temp1=variable_get('file_public_path').'/export';
      if(!file_prepare_directory($temp1,FILE_CREATE_DIRECTORY)){
          drupal_set_message(t('Problem in write file in directory'),'error');
          return;
      }
    $filename='Export-giftcard-'.time().'.csv';
        $filepath=$temp1.'/'.$filename;
    //    $filepath='sites\\defauls\\files\\Export-giftcard-.csv';
        $df = fopen($filepath, 'w');
        if(!$df){
            drupal_set_message(t('Can not write file in').$filepath,'error');
            return;
        }
        fputcsv($df,array('code','credit'));
   fclose($df);
    $path = file_create_url($filepath);
    drupal_set_message(t('Export done. ') . '<a href="' . $path . '">' . t('Download export file') . '</a>');

after rooby answer I update my question

I set private file system to system/files/export and in my code use it $temp1 = variable_get('file_private_path'); also I implement hook_file_download

function mymodule_file_download($uri) {
  // Check if the file is controlled by the current module.
  if (!file_prepare_directory($uri)) {
    $uri = FALSE;
  }
// I will put my conditions later
      $info = image_get_info($uri);
      return array('Content-Type' => $info['mime_type']);
}

but when I try to click on link to downlaod file return Forbidden to me.I think mymodule_file_download not run when I try to access system/files/export/myfile.csv

share|improve this question
    
If you don't want to use file management provided by Drupal, with it's private file system, then it is not really a Drupal question. –  Mołot Feb 24 at 13:23
    
@Mołot , Is it right if I I create it in private file system direct access to it return 403? –  zhilevan Feb 24 at 13:24
    
I honestly don't understand the comment above. –  Mołot Feb 24 at 13:42
    
I said If I create a file in private file system ,is it accessible directly? –  zhilevan Feb 24 at 13:52
    
@Mołot I create file in private file system programmatically, but when I want download it ,it return me 403,Forbidden . –  zhilevan Feb 24 at 13:55

2 Answers 2

You can use the private file system instead of the public file system. The private file system restricts direct access to files.

Then you link to the files like: system/files/filename.ext. Then when someone clicks one of those links it calls drupal core's file_download() function, which in turn invokes hook_file_download().

Drupal core implements hook_file_download() in the file module as file_file_download(), which handles these private files to allow users with the appropriate access permissions to download the file.

However file_file_download() won't work out of the box with non drupal field files (like your custom files appear to be), it only works for files attached to drupal fields.

So you will also have to implement your own version of hook_file_download() to handle your particular files.

One way to single out your files and avoid massing with the files that file_file_download() already handles is to put your custom files in a sub-directory of the private files directory that is not used by any other files, then in your hook_file_download() you check for that directory in the file path, return headers if the file is in the right directory and the user has the correct permissions, otherwise, if the user doesn't have perms return -1 and if the file is outside of your special sub-directory just return null to ignore the file and let drupal handle it as normal.

To implement hook_file_download() you have to create a custom drupal module that implements the hook like so:

/**
 * Implements hook_file_download().
 */
function YOURMODULENAME_file_download($uri, $field_type = 'file') {
  // Your code goes here.
}

See file_file_download() as an example.

For more information see:
https://drupal.org/node/292
https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7

Note:
Your private file system path will be something like sites/default/files/private (a directory on your server). The path system/files is a drupal website url, not a path on the file system, and is only used to create hyperlinks to the files that are in the private files directory.

So if you set your private file system path to sites/default/files/private, a hyperlink on your site that points to /system/files/export/filename.txt will open the file on your web server at /sites/default/files/export/filename.txt.

share|improve this answer
    
I understand your theory,but how can I implement it in form sumbmit, I want download file after form submit, –  zhilevan Feb 24 at 14:26
    
you mean I implement hook_file_download and in sumbit of my form do something like this ? insumbit{ return mymodule_file_download($path); } ? –  zhilevan Feb 24 at 14:29
    
The hook_file_download() handles your access control to your custom file. The download code can be just like you already have except you are saving the file to the private file system instead of the public one and the link to the file that you are creating links to /system/files/filepath.ext instead of /sites/default/files/private/filepath.ext –  rooby Feb 24 at 14:29
    
When a user downloads a file from system/files/... drupal proccesses it as a private file and then runs hook_file_download() to determine the access control for the file instead of just directly serving the file as it would for a public file. –  rooby Feb 24 at 14:30
    
I dont understand how can this hook engaged to run? should I call it in my form_submit? –  zhilevan Feb 24 at 14:30

Create a private file field as you would if they were regular private files.

Hook in to the file download function: https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_file_download/7

Let Drupal handle permissions, create your file dynamically.

share|improve this answer
    
@zhilevan that error suggests that you need to learn how to properly hook in to drupal functions... and is beyond the scope of this question (and this forum). Read the documentation at drupal.org, it will tell you how to properly hook. –  jdu Feb 24 at 14:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.