In my case, i have images in private folder, without a record in the file_managed table.
When i try to generate derivative images via image_style_ hooks, i found this error:

Notice: Trying to get property of non-object in webform_multifile_file_download() (line 79 of ...)

Problem is that $target_document is not set.

Here is the patch:

diff --git a/modules/contrib/webform_multifile/webform_multifile.module b/modules/contrib/webform_multifile/webform_multifile.module
index ef0c5b1..0a6ee1d 100644
--- a/modules/contrib/webform_multifile/webform_multifile.module
+++ b/modules/contrib/webform_multifile/webform_multifile.module
@@ -76,7 +76,7 @@ function webform_multifile_file_download($uri) {
   $submission_id = $submission_uid = NULL;
   while($multifile_row = $multifile_scan->fetchAssoc()) {
   	$file_ids = unserialize($multifile_row['data']);
-  	if (in_array($target_document->fid, $file_ids) ) {
+  	if ($target_document && in_array($target_document->fid, $file_ids) ) {
   		$submission_id = $multifile_row['sid'];
   	}
   }
@@ -94,7 +94,7 @@ function webform_multifile_file_download($uri) {
     return -1;
   }
   // This is not a webform-controlled file.
-  return NULL;
+  return null;
 }
 
 /**

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

richsky’s picture

Oh my... I also found this was a serious issue when unserialize($multifile_row['data']) is executed against Null or not serialized data.

I added this test:

if($multifile_row['data'] !== NULL && preg_match('/^([adObis]:|N;)/', $multifile_row['data']) === 1) { 
  $file_ids = unserialize($multifile_row['data']);
    if (in_array($target_document->fid, $file_ids) ) {
      $submission_id = $multifile_row['sid'];
  }
}
sammys’s picture

FileSize
1.26 KB

Here's a patch that should handle both situations more gracefully.

Shuairan’s picture

Thanks for the patch!

BTW, the whole webform_multifile_file_download() function is big crap. Really big crap.
With ~10 private images on a page and around ~20.000 webform submissions this two stupid notices producing around 250.000 watchdog entries per request here.

Even with the patch this code loops over all webform submissions (with a multifile field) for each download request, in most cases just to find out it is NOT responsible for the file. BTW, that's why I call that piece of code "big crap".
So if you are building a huge site with downloadable private files and lots of webform submissions, be aware of that!

I think I'll have to write a patch to restructure the logic behind this by using the file_usage table...

ahsanra’s picture

So is there any solution to those damn 10,000 loops and watchdog entries being produced by just visiting the gallery page? I am having the same problem and it is very annoying to have those entries in your watchdog list.

Anyone come up with solution? I have applied both the patches but still it produces those watchdog entries with something like

Warning: in_array() expects parameter 2 to be array, boolean given in webform_multifile_file_download() (line 80 of /docroot/sites/all/modules/contrib/webform_multifile/webform_multifile.module).

Whats the solution?

Shuairan’s picture

Here is a patch which might help you, depending on which webform version you are using.

The patch adds a webform_multifile_webform_submission_presave() function which is very similar to webform-4.1's webform_submission_presave function. It adds the multifile files to the file_usage table. Be careful: Might not work if you are using "file" and "multifile" form fields together (in one single form)!
This way the webform file access handled by webform_file_download() in the main module works quite well for me.

And it also removes the broken webform_multifile_file_download function.

Jochen Wendebaum’s picture

What is the status of this patch? Will it be included into the projet some day?

laboratory.mike’s picture

Status: Active » Reviewed & tested by the community

The initial patch works. Which patch do we want to review & commit?

laboratory.mike’s picture

Status: Reviewed & tested by the community » Needs review
JeroenT’s picture

FileSize
4.42 KB

Patch in #5 worked for me, but the patch no longer applied and I got a notice on node/.../done.

Patch attached is a re-roll of patch #5 + a small bugfix.

JeroenT’s picture

FileSize
4.42 KB
406 bytes

Uploaded the wrong patch. This is the right one.

brianfisher’s picture

Status: Needs review » Needs work

with webform 3.24 patch fails to upload file, generates log entries

Notice: Undefined offset: 0 in webform_multifile_webform_submission_presave() (line 64 of webform_multifile/webform_multifile.module).
Warning: array_merge(): Argument #2 is not an array in webform_multifile_webform_submission_presave() (line 65 of webform_multifile/webform_multifile.module).
Warning: array_diff(): Argument #2 is not an array in webform_multifile_webform_submission_presave() (line 90 of webform_multifile/webform_multifile.module).
Warning: array_diff(): Argument #1 is not an array in webform_multifile_webform_submission_presave() (line 92 of webform_multifile/webform_multifile.module).

Looking at hook_webform_submission_presave()

$submission->data[$component_id]['value'][0] = 'foo';

but the patch includes

$ufid = unserialize($submission->data[$cid][0]);
brianfisher’s picture

Status: Needs work » Needs review
FileSize
4.73 KB

revised patch to detect api version

brianfisher’s picture

FileSize
4.73 KB

reroll patch

GaëlG’s picture

Warning, since last security update, unserialize has to be replaced with drupal_json_decode in patch #13.

marco-s’s picture

FileSize
4.75 KB

I've updated the patch with 'drupal_json_decode' (instead of 'unserialize').
This patch solves this issue as well: 2821896

joewhitsitt’s picture

I don't think the presave works if the multifile component exists but isn't populated. Testing #15 patch

I get $submission->data[1][0] = NULL which causes errors:

Notice: Undefined offset: 0 in webform_multifile_webform_submission_presave() (line 72 of .../webform_multifile/webform_multifile.module).
Notice: Undefined offset: 0 in webform_multifile_webform_submission_presave() (line 73 of .../webform_multifile/webform_multifile.module).
Warning: array_merge(): Argument #2 is not an array in webform_multifile_webform_submission_presave() (line 75 of .../webform_multifile/webform_multifile.module).
Warning: array_diff(): Argument #2 is not an array in webform_multifile_webform_submission_presave() (line 100 of .../webform_multifile/webform_multifile.module).
Warning: array_diff(): Argument #1 is not an array in webform_multifile_webform_submission_presave() (line 102 of .../webform_multifile/webform_multifile.module).

This also causes issues when there is more than one multifile type component on a form and one of them is not populated. The errors above occur but the files that were uploaded via the other component get a usage 0 and aren't accessible. access denied.

Jānis Bebrītis’s picture

Here's a patch to fix two issues:
- array_merge does not like false value that get returned by empty parameter in drupal_json_decode
- files cannot be deleted because the deleting code is targeted for webform3

rudins’s picture

FileSize
5.99 KB

There is correct patch, small fix ;)

nicobot’s picture

I tested the latest patch with current dev and it works fine.
Thanks!

nicobot’s picture

Version: 7.x-1.2 » 7.x-1.x-dev
Status: Needs review » Reviewed & tested by the community

Moving to RBTW, patch works fine.

Jaesin’s picture

Plus 1 for this patch.

marco-s’s picture

Patch #18 works. Thanks.

VISIOS’s picture

Patch #18 works for me too. Unfortunately took me 2 hours to find out Webform Multiple File Upload caused this. Please commit, thanks.

dmsmidt’s picture

Title: Bug in webform_multifile_file_download » File uploads not logged in file usage, results in buggy hook_file_download implementation.
Assigned: Unassigned » dmsmidt
Status: Reviewed & tested by the community » Needs work

Thanks for the work on this. Some comments.

  1. +++ b/webform_multifile.module
    @@ -38,6 +38,71 @@ function webform_multifile_webform_component_info() {
    + * Use the same as the main webform module @see webform_webform_submission_presave() but handle the multifile elements.
    + * this is untestet for "file" and "multifile" formelements together in one single form!
    

    This can't be committed like this. It should be tested or there should be an incompatibility validation during the setup of the form.

    Either way, we should fix typ0's and coding standards.

  2. +++ b/webform_multifile.module
    @@ -38,6 +38,71 @@ function webform_multifile_webform_component_info() {
    +  $new_fids = isset($submission->file_usage) ? $submission->file_usage['added_fids'] : array();
    +  $old_fids = isset($submission->file_usage) ? $submission->file_usage['deleted_fids'] : array();
    

    This will only work if this hook runs later than webform_webform_submission_presave(). Check if safer if we check the existence of the keys as well.

  3. +++ b/webform_multifile.module
    @@ -38,6 +38,71 @@ function webform_multifile_webform_component_info() {
    +    if ($component['type'] == 'multifile') {
    ...
    +      if (!empty($submission->data[$cid])) {
    

    We can reduce nesting here with early continues.

  4. +++ b/webform_multifile.module
    @@ -38,6 +38,71 @@ function webform_multifile_webform_component_info() {
    +        $info = system_get_info('module', 'webform');
    +        $version = explode('-', $info['version']);
    +        $version = explode('.', $version[1]);
    +        if ($version[0] == 3) {
    +          $ufid = !empty($submission->data[$cid]['value']) ? drupal_json_decode($submission->data[$cid]['value'][0]) : array();
    +        }
    +        elseif ($version[0] == 4) {
    +          $ufid = !empty($submission->data[$cid]) ? drupal_json_decode($submission->data[$cid][0]) : array();
    +        }
    

    Let's just check for version higher than 3. And add an helper function for getting the major version.

  5. +++ b/webform_multifile.module
    @@ -38,6 +38,71 @@ function webform_multifile_webform_component_info() {
    +  if ($has_file_components) {
    

    Use early return.

  6. +++ b/webform_multifile.module
    @@ -38,6 +38,71 @@ function webform_multifile_webform_component_info() {
    +        if ($component['type'] == 'multifile') {
    +          if (!empty($old_submission->data[$cid])) {
    

    Early continue.

  7. +++ b/webform_multifile.module
    @@ -71,47 +136,17 @@ function webform_multifile_delete_form_submit($form, &$form_state) {
    +  $info = system_get_info('module', 'webform');
    +  $version = explode('-', $info['version']);
    +  $version = explode('.', $version[1]);
    

    Reuse version check helper function.

  8. +++ b/webform_multifile.module
    @@ -71,47 +136,17 @@ function webform_multifile_delete_form_submit($form, &$form_state) {
    +  if ($version[0] == 3) $fids = drupal_json_decode($form_state['values']['submission']->data[$cid]['value'][0]);
    +  elseif ($version[0] == 4) $fids = drupal_json_decode($form_state['values']['submission']->data[$cid][0]);
    

    Fix coding standards.

dmsmidt’s picture

Here is a new patch which fixes my mentioned issues. It also works with multiple components and together with the normal single File component.

swhitters’s picture

Oh my gosh, I've been trying to fix this for ages. The patch in #25 works for me. Thank you.

jacob.embree’s picture

Status: Needs review » Reviewed & tested by the community

Nice going, dmsmidt. #25 looks good and fixes the access issues I was having.

Notes for anyone else wanting to use this patch:

  • Clear your cache after applying the patch.
  • I you are using a git checkout of webform or the version is missing from webform.info for any other reason then webform_multiple_get_webform_major_version() will assume an old version which will break stuff for Webform 7.x-4.x.
ShaneOnABike’s picture

It's not clear to me whether this is related, but in my situation we had set multifiles to be uploaded to a private directory. I cannot download these files and keep getting Access Denied. I tried to apply the patch, and finally had to do that by hand to make it apply not sure why git was unhappy with it.

I noticed that the patch removes the download mechanism, and I //assume// it's using the default webform but I cannot be sure. How are files being downloaded now? Regardless, it still isn't working properly in my case. In using a single file upload all is fine so it's not a permissions issue on teh file structure itself.

What am I missing?

fjgarlin’s picture

Thanks a lot for the patch. I run into the issue described in #27 and made this addition to try to get the major version in another way if the previous attempts don't work (I am using git submodules).

jacob.embree’s picture

Status: Reviewed & tested by the community » Needs review