Doesn't work with private downloads

Mark Theunissen - February 20, 2009 - 11:20
Project:File Force
Version:6.x-1.1
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

Maybe I'm missing something obvious but it doesn't work with Drupal's private downloads. Should I just write my own hook_download for this, instead of using file_force?

Thanks for any tips! ;)

#1

Garrett Albright - February 24, 2009 - 18:56

Though I haven't thoroughly tested it, I would think that File Force would work with private downloads enabled. Could you be more specific about what's not working?

#2

Mark Theunissen - February 25, 2009 - 09:32

Sure, when you call the file_download() function, File Force passes in the full path 'system/files/image.jpg'.

However, when using private downloads directly, the menu item ['system/files'] maps directly to the file_download() function, and thus it only passes in the file name, i.e. it gets 'image.jpg'.

Put a breakpoint in file_download and see the difference in the arguments.

Thanks!
:)

#3

Mark Theunissen - March 4, 2009 - 15:28

Hi Garrett, have you had a chance to look at this?

#4

Garrett Albright - March 4, 2009 - 16:10

Sorry, no. I've been cramming on other projects lately… It may be a while before I'm able to.

#5

Pol - April 11, 2009 - 10:08

I'm really interested in private download too !

#6

Pol - April 12, 2009 - 08:35

Hi Guys,

I really need to get this working for a customer, so I hack the code myself and succeded to do it !

How to get it working:

1) Edit the file "includes/file.inc"
2) Replace the function file_download() by this one:

function file_download() {
  // Merge remainder of arguments from GET['q'], into relative file path.
  $args = func_get_args();
  $filepath = implode('/', $args);

  // Maintain compatibility with old ?file=paths saved in node bodies.
  if (isset($_GET['file'])) {
    $filepath =  $_GET['file'];
  }

if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
  $tmp = explode("/",$filepath);
  $filepath = file_directory_path()."/".array_pop($tmp);
  unset($tmp);
}


  if (file_exists(file_create_path($filepath))) {
    $headers = module_invoke_all('file_download', $filepath);
    if (in_array(-1, $headers)) {
      return drupal_access_denied();
    }
    if (count($headers)) {
      file_transfer($filepath, $headers);
    }
  }
  return drupal_not_found();
}

3) Enjoy
4) I've included the patch. This is the first one, I'm sure it's not the best, but at least, I'm trying ;)

AttachmentSize
file_download.patch 1.26 KB

#7

Pol - April 12, 2009 - 12:29

Update ! Small bug fix

Replace the function includes/file.php::file_download() (near line 840) by this one:

function file_download() {
  // Merge remainder of arguments from GET['q'], into relative file path.
  $args = func_get_args();
  $filepath = implode('/', $args);

  // Maintain compatibility with old ?file=paths saved in node bodies.
  if (isset($_GET['file'])) {
    $filepath =  $_GET['file'];
  }

  if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
    $filepath = file_directory_path()."/".array_pop(explode('system/files/',$filepath));
  }

  if (file_exists(file_create_path($filepath))) {
    $headers = module_invoke_all('file_download', $filepath);
    if (in_array(-1, $headers)) {
      return drupal_access_denied();
    }
    if (count($headers)) {
      file_transfer($filepath, $headers);
    }
  }
  return drupal_not_found();
}

#8

Garrett Albright - April 12, 2009 - 16:48

Ack! Don't hack core!

#9

Pol - April 12, 2009 - 18:12

Yes we don't have to hack in the core.

But here, without those 3 lines, all the modules that implement file_download() will never be used !

These are the 3 lines of code to add:

  if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
    $filepath = file_directory_path()."/".array_pop(explode('system/files/',$filepath));
  }

It's impossible to do it in an other way!

So... what to do ?

#10

Pol - April 14, 2009 - 14:52

I committed the patch to core.

It's related to file_force but it's a small bug in file_download()

Link: #432332: Private path and file_download

 
 

Drupal is a registered trademark of Dries Buytaert.