Drupals current file upload system is insufficient for what I need. Rather that writing a module that extends it (the current file upload system will still be utilized to some degree), I found it easier to write a module that creates an entirely new system that utilizes two new tables and allows for a versioning system and the ability to organize the files within a certain directory (www.example.com/documents for this example).

Currently the system uploads, moves, deletes files and creates,moves,renames and deletes directories from within this structure. I have hit a problem with file downloads at the moment. hook_file_download seems to be what I am looking for, but I don't really understand the documentation or how it would work with files NOT stored in {files}.

If someone could explain how hook_file_download should be implemented, or at least point me in the direction of a module that correctly implements it it would be most appreciated.

Comments

WorldFallz’s picture

afaik, hook_file_download is only invoked when the private download method system setting is used (or when using something like http://drupal.org/node/540754 to emulate the private setting).

To find examples, see http://drupalcontrib.org/api/search/6/_file_download

xangelo’s picture

Thanks for that link, it actually explained a lot. I believe that hook_file_download will never be invoked using my method because of the versioning system in place. The URL passed would need to be a relative path to the file, which it isn't. Rather than tacking on extra redirects I opted to force out the existing page headers, set my own and then transfer the file.

ob_end_clean();
  
  drupal_set_header('Pragma: public');
  drupal_set_header('Cache-Control: cache, must-revalidate');
  drupal_set_header('Accept-Ranges: bytes');
  drupal_set_header('Content-Type: application/zip');
  drupal_set_header('Content-Transfer-Encoding: binary');
  drupal_set_header('Content-Disposition: attachment; filename="'. $filename .'"');
  drupal_set_header('Content-Length: '.$info['file_size']);
    
  if ($fd = fopen($path, 'rb')) {
    while (!feof($fd)) {
      print fread($fd, 1024);
    }
    fclose($fd);
  }

I've implemented the same base functionality present in file_transfer() to ensure lower memory usage.

Thanks for your help in figuring this out.