If a node is previewed while editing and attaching new files, any new attachments are lost when finally saving.
How to reproduce (Drupal 6.5)
1. Go to the edit form of a node.
2. Select a file for attachment.
3. Click the Preview-button.
The form reloads. The newly attached file is visible in the list of attachmens. If you investigate the database it has been saved in the {files} table with with status=0, and has not been saved in the {upload} table yet. On disk the file has been saved.
4. Click the Save-button.
The form reloads. The file no longer appears in the list of attachments. The {files}.status has been changed to 1, but no entry has been created in {upload}.
I would have expected an entry to be created in {upload} table when I clicked Save, so that the new upload would appear in the list of attachments.
Solution
When a previewed node is submitted, (at least in some case?) the files are represented by arrays rather than objects. A cast from array to object fixes the problem as far as I can tell, see the attached diff. I made a diff against Drupal 7, as it says HEAD should be used when making patches.
The line of code that seems to cause the problem was introduced between these versions. I am using Drupal 6.5, so I only know the bug exists there. (Actually I am using some customizations, but they should not matter.) But as the line causing the problem remains in Drupal 7 I guess it exists there too.
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | upload-preview.patch | 2.58 KB | mfb |
| #6 | upload_notice.patch | 452 bytes | chx |
| #5 | upload_notice.patch | 462 bytes | chx |
| upload_previewed_D6.diff | 696 bytes | emok | |
| upload_previewed_D7.diff | 696 bytes | emok |
Comments
Comment #1
emok commentedI just realized that PHP version may matter, since this was a type (casting) issue. The server I use runs PHP 4.3.11. Perhaps newer versions allow you to use
$a->fieldeven on arrays where$a['field']should be used.Comment #2
boombatower commentedAs of http://testing.drupal.org/pifr/node/1/323438 patches fail to apply... D6 don't worry about as it only tests D7 trying to get d.o updated to that end.
Please make patches from drupal root.
Comment #3
damien tournoud commentedOk, this breaks a key functionality, so raising to critical.
I'm not convince this whole loop:
... is even needed, because we already set 'new' and $form_state['value'] above.
This will have to be fixed in D7 first, then trivially backported.
Comment #4
Anonymous (not verified) commentedSee emok's note about PHP version in #1. For 7.x-dev we need PHP 5 for HEAD.
Comment #5
chx commentedThe original issue I can't reproduce any more. I found another and patched it.
Comment #6
chx commentedBetter patch.
Comment #7
webchickUpload module was just removed from D7 in favour of filefield. Moving down to D6.
Comment #8
mfbI am reproducing this bug on PHP 5.2.12
I didn't yet track down why the file object is converted to an array after repeated previewing.
Comment #9
mfbThis is probably why the bug appears with PHP 5.2.12: http://bugs.php.net/bug.php?id=50255 In previous versions of PHP, if you try to check the existence of a property on an array with empty() or isset(), you get results as if the array were an object. This is no longer the case as of 5.2.12
Comment #10
GoofyX commentedThe patch in #8 works just fine for me (Drupal 6.16, PHP 5.2.13).
Comment #11
advseb commentedsubscribe
Comment #12
Anonymous (not verified) commentedSo we have confirmation of the patch in #8 is working and the patch looks good structurally so marking RTBC.
Comment #13
advseb commentedYes, we are using this patch on a rather large site and it is working.
Comment #14
Matthew OMalley commentedSo this seem like a very important issue, causing a number of Drupal sites to not work with basic upload functionality (including some of mine) - yet it's been a month (after RTBC) without a release of a new version of Drupal including the patch. Anyone know when the fix will get released in D6.17?
Comment #15
GoofyX commentedI pinged Gábor about this, so he will hopefully commit it soon.
Comment #16
gábor hojtsyOk, I've added an extra space inbetween the cast and the variable because I believe that is in line with our coding standards. Committed, thanks!
Comment #18
amitkumarmits@gmail.com commentedI am using the drupal 6.15 . I was not able to show the attachment on the page . I just add these two lines and got the benefits.
upload.module
if (isset($form_state['values']['files'])) {
foreach ($form_state['values']['files'] as $fid => $file) {
$form_state['values']['files'][$fid]['new'] = !empty($form['#node']->files[$fid]->new);
// If the node was previewed prior to saving, $form['#node']->files[$fid]
// is an array instead of an object. Convert file to object for compatibility.
$nodefile = (object) $form['#node']->files[$fid];
$form_state['values']['files'][$fid]['new'] = !empty($nodefile->new);
Thanks a lot.......