diff --git a/field_file.inc b/field_file.inc index 0be3bca8edf934964f4ad33016a5cef9bc71ad99..1763b44399f51f27470106be15bbdc2ce322cc56 100644 --- a/field_file.inc +++ b/field_file.inc @@ -38,7 +38,7 @@ function field_file_load($fid, $reset = NULL) { } if (!$file) { - $file = array('fid' => 0, 'filepath' => '', 'filename' => '', 'filemime' => '', 'filesize' => 0); + $file = (object) array('fid' => 0, 'filepath' => '', 'filename' => '', 'filemime' => '', 'filesize' => 0); } foreach (module_implements('file_load') as $module) { diff --git a/filefield_field.inc b/filefield_field.inc index 1e8fdd21c207a5dbb136a065a7a06c435d69e394..eb20522d6fce973af0c326049c108738c421f3b3 100644 --- a/filefield_field.inc +++ b/filefield_field.inc @@ -272,25 +272,26 @@ function filefield_field_sanitize($node, $field, &$items, $teaser, $page) { continue; } } - // Load the complete file if a filepath is not available. - if (!empty($item['fid']) && empty($item['filepath'])) { - $items[$delta] = array_merge($item, field_file_load($item['fid'])); - } + // Add nid so formatters can create a link to the node. $items[$delta]['nid'] = $node->nid; - // TODO: This is only necessary for Views, which doesn't call the "load" - // $op. It might be preferable to move this to Views integration somehow. - if (!empty($items['data']) && is_string($items[$delta]['data'])) { - $item['data'] = unserialize($item['data']); - } - // Temporary fix to unserialize data serialized multiple times. + // Get the 'data' column stored by CCK into an array. This is necessary + // for Views, which doesn't call the "load" $op and to fix an issue with + // CCK double-serializing data. // See the FileField issue http://drupal.org/node/402860. // And the CCK issue http://drupal.org/node/407446. while (!empty($items[$delta]['data']) && is_string($items[$delta]['data'])) { $items[$delta]['data'] = unserialize($items[$delta]['data']); } + // Load the complete file if a filepath is not available. + if (!empty($item['fid']) && empty($item['filepath'])) { + $file = (array) field_file_load($item['fid']); + $items[$delta]['data'] = array_merge($item['data'], $file['data']); + $items[$delta] = array_merge($item, $file); + } + // Verify the file exists on the server. if (!empty($item['filepath']) && !file_exists($item['filepath'])) { watchdog('filefield', 'FileField was trying to display the file %file, but it does not exist.', array('%file' => $item['filepath']), WATCHDOG_WARNING); diff --git a/filefield_meta/filefield_meta.module b/filefield_meta/filefield_meta.module index 49c9ac9f0f0f33b7ec60705365c91a5327ded1a6..eae0f96e82a1281873326bf7bc038724d3c7591b 100644 --- a/filefield_meta/filefield_meta.module +++ b/filefield_meta/filefield_meta.module @@ -76,7 +76,7 @@ function filefield_meta_file_load(&$file) { function filefield_meta_file_insert(&$file) { if (!empty($file->fid)) { filefield_meta($file); - $record = array_merge(array('fid' => $file->fid), $file->data); + $record = array_merge($file->data, array('fid' => $file->fid)); drupal_write_record('filefield_meta', $record); } } diff --git a/filefield_widget.inc b/filefield_widget.inc index 1b3a1fafa870855768c95d5815d89a9590a82134..4d3d85d3236c98170113ecb712d1d89acd53780b 100644 --- a/filefield_widget.inc +++ b/filefield_widget.inc @@ -204,7 +204,7 @@ function filefield_widget_value($element, $edit = FALSE) { $item = $element['#default_value']; } else { - $item = array_merge($element['#default_value'], $edit); + $item = $edit; $field = content_fields($element['#field_name'], $element['#type_name']); // Uploads take priority over value of fid text field. @@ -236,6 +236,9 @@ function filefield_widget_value($element, $edit = FALSE) { } } // Merge file and item data so it is available to all widgets. + if (isset($item['data']) && isset($file['data'])) { + $file['data'] = array_merge($item['data'], $file['data']); + } $item = array_merge($item, $file); return $item; diff --git a/tests/filefield.test b/tests/filefield.test index 0f33c1ee4c435738790805d1c3cd036deb6b11f1..bd33b1d18b8de4f58c9f708f157109fe9bb76b69 100644 --- a/tests/filefield.test +++ b/tests/filefield.test @@ -8,9 +8,9 @@ class FileFieldTestCase extends DrupalWebTestCase { * Implementation of setUp(). */ function setUp() { - // Views and ImageCache are included here just so that they don't whine - // when CCK tries to clear thier caches. - $modules = array_merge(func_get_args(), array('content', 'filefield', 'mimedetect', 'token', 'views')); + // Views is included here just so that it doesn't whine when CCK tries to + // clear the caches. + $modules = array_merge(func_get_args(), array('content', 'filefield', 'filefield_meta', 'getid3', 'mimedetect', 'token', 'views')); call_user_func_array(array($this, 'parent::setUp'), $modules); // Create and login user @@ -88,7 +88,8 @@ class FileFieldTestCase extends DrupalWebTestCase { /** * Upload a file to a node. */ - function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE) { + function uploadNodeFile($file, $field, $nid_or_type, $new_revision = TRUE) { + $field_name = $field['field_name']; $edit = array( 'title' => $this->randomName(), 'revision' => (string) (int) $new_revision, @@ -101,14 +102,26 @@ class FileFieldTestCase extends DrupalWebTestCase { $this->drupalPost('node/' . $nid_or_type . '/edit', $edit, t('Save')); } else { - $edit['files[' . $field_name . '_0]'] = realpath($file->filepath); + $delta = '0'; + $edit['files[' . $field_name . '_' . $delta . ']'] = realpath($file->filepath); $type = str_replace('_', '-', $nid_or_type); $this->drupalPost('node/add/' . $type, $edit, t('Save')); } $matches = array(); preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches); - return isset($matches[1]) ? $matches[1] : FALSE; + $nid = isset($matches[1]) ? $matches[1] : FALSE; + + // Edit the node and add a description if possible. + if ($nid && $field['description_field']) { + $edit = array( + 'revision' => 0, + $field_name . '[' . $delta . '][data][description]' => $this->randomString(), + ); + $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save')); + } + + return $nid; } /** @@ -200,12 +213,15 @@ class FileFieldRevisionTestCase extends FileFieldTestCase { function testRevisions() { $field_name = 'field_' . strtolower($this->randomName()); $type = $this->drupalCreateContentType(); - $field = $this->createFileField($field_name, $type->name); + $field_options = array( + 'description_field' => '1', + ); + $field = $this->createFileField($field_name, $type->name, $field_options); $test_file = $this->getTestFile('text'); // Create a new node with the uploaded file. - $nid = $this->uploadNodeFile($test_file, $field_name, $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); // Check that the file exists on disk and in the database. $node = node_load($nid, NULL, TRUE); @@ -234,6 +250,12 @@ class FileFieldRevisionTestCase extends FileFieldTestCase { $node = node_load($nid, NULL, TRUE); $node_file_r3 = $node->{$field['field_name']}[0]; $node_vid_r3 = $node->vid; + + // FileField Meta's extensive meta data can be difficult to match up exactly + // (mostly differences between strings and integers). Just compare the + // descriptions. + $node_file_r2['data'] = array('description' => $node_file_r2['data']['description']); + $node_file_r3['data'] = array('description' => $node_file_r3['data']['description']); $this->assertEqual($node_file_r2, $node_file_r3, t('Previous revision file still in place after creating a new revision without a new file.')); // Revert to the first revision and check that the original file is active. @@ -288,8 +310,8 @@ class FileFieldDisplayTestCase extends FileFieldTestCase { $test_file = $this->getTestFile('text'); // Create a new node with the uploaded file. - $nid = $this->uploadNodeFile($test_file, $field_name, $type->name); - $this->drupalGet('node/' . $nid . '/edit'); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); + $this->drupalGet('node/' . $nid); // Check that the default formatter is displaying with the file name. $node = node_load($nid, NULL, TRUE); @@ -325,7 +347,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { * Implementation of setUp(). */ function setUp() { - $modules = array_merge(func_get_args(), array('content', 'filefield', 'mimedetect', 'token', 'views')); + $modules = array_merge(func_get_args(), array('content', 'filefield', 'filefield_meta', 'getid3', 'mimedetect', 'token', 'views')); call_user_func_array(array($this, 'parent::setUp'), $modules); $this->node_type = $this->drupalCreateContentType(); @@ -353,7 +375,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->assertRaw(t('%title field is required.', array('%title' => $field['widget']['label'])), t('Node save failed when required file field was empty.')); // Create a new node with the uploaded file. - $nid = $this->uploadNodeFile($test_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading to the required field.')); @@ -369,7 +391,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->assertRaw(t('%title field is required.', array('%title' => $field['widget']['label'])), t('Node save failed when required multiple value file field was empty.')); // Create a new node with the uploaded file into the multivalue field. - $nid = $this->uploadNodeFile($test_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading to the required multiple value field.')); @@ -401,14 +423,14 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->updateFileField($field['field_name'], $type->name, array(), array('max_filesize_per_file' => $max_filesize_per_file)); // Create a new node with the small file, which should pass. - $nid = $this->uploadNodeFile($small_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($small_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading a file (%filesize) under the max limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_filesize_per_file))); $this->assertFileEntryExists($node_file, t('File entry exists after uploading a file (%filesize) under the max limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_filesize_per_file))); // Check that uploading the large file fails (1M limit). - $nid = $this->uploadNodeFile($large_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($large_file, $field, $type->name); $error_message = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($large_file->filesize), '%maxsize' => format_size($file_limit))); $this->assertRaw($error_message, t('Node save failed when file (%filesize) exceeded the max upload size (%maxsize).', array('%filesize' => format_size($large_file->filesize), '%maxsize' => $max_filesize_per_file))); } @@ -417,7 +439,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->updateFileField($field['field_name'], $type->name, array(), array('max_filesize_per_file' => '')); // Upload the big file successfully. - $nid = $this->uploadNodeFile($large_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($large_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading a file (%filesize) with no max limit.', array('%filesize' => format_size($large_file->filesize)))); @@ -440,26 +462,26 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->updateFileField($field['field_name'], $type->name, array('multiple' => '1'), array('max_filesize_per_node' => $max_node_limit)); // Create a new node with the small file, which should pass. - $nid = $this->uploadNodeFile($small_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($small_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading a file (%filesize) under the max node limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_node_limit))); $this->assertFileEntryExists($node_file, t('File entry exists after uploading a file (%filesize) under the max node limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_node_limit))); // Add a second file to the same node which should pass. - $nid = $this->uploadNodeFile($small_file, $field['field_name'], $nid); + $nid = $this->uploadNodeFile($small_file, $field, $nid); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading a file (%filesize) under the max node limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_node_limit))); $this->assertFileEntryExists($node_file, t('File entry exists after uploading a file (%filesize) under the max node limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_node_limit))); // Add a third file to the same node which should fail. - $nid = $this->uploadNodeFile($small_file, $field['field_name'], $nid); + $nid = $this->uploadNodeFile($small_file, $field, $nid); $error_message = t('exceeds field settings of %msize.', array('%msize' => format_size($file_limit))); $this->assertRaw($error_message, t('File not uploaded as the file (%filesize) exceeds the max node limit (%maxsize).', array('%filesize' => format_size($small_file->filesize), '%maxsize' => $max_node_limit))); // Check that uploading the large file fails (1M limit). - $nid = $this->uploadNodeFile($large_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($large_file, $field, $type->name); $error_message = t('exceeds field settings of %msize.', array('%msize' => format_size($file_limit))); $this->assertRaw($error_message, t('File not uploaded as the file (%filesize) exceeds the max node limit (%maxsize).', array('%filesize' => format_size($large_file->filesize), '%maxsize' => $max_node_limit))); @@ -487,7 +509,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->updateFileField($field['field_name'], $type->name, array(), array('file_extensions' => '')); // Check that the file can be uploaded with no extension checking. - $nid = $this->uploadNodeFile($test_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading a file with no extension checking.')); @@ -497,7 +519,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { $this->updateFileField($field['field_name'], $type->name, array(), array('file_extensions' => "txt png jpg $extention")); // Check that the file can be uploaded with extension checking. - $nid = $this->uploadNodeFile($test_file, $field['field_name'], $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); $node = node_load($nid, NULL, TRUE); $node_file = $node->{$field['field_name']}[0]; $this->assertFileExists($node_file, t('File exists after uploading a file with extension checking.')); @@ -505,7 +527,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase { // Check that a mismatched extension cannot be uploaded. if (module_exists('mimedetect')) { - $this->uploadNodeFile($wrong_extension_file, $field['field_name'], $type->name); + $this->uploadNodeFile($wrong_extension_file, $field, $type->name); $error_pattern = "/The file contents \([a-z\-\/]+\) do not match its extension \([a-z]+\)\./"; $this->assertPattern($error_pattern, t('File prevented from uploading because its extension does not match its content.')); } @@ -540,7 +562,7 @@ class FileFieldPathTestCase extends FileFieldTestCase { $test_file = $this->getTestFile('text'); // Create a new node. - $nid = $this->uploadNodeFile($test_file, $field_name, $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); // Check that the file was uploaded to the file root. $node = node_load($nid, NULL, TRUE); @@ -551,7 +573,7 @@ class FileFieldPathTestCase extends FileFieldTestCase { $field = $this->updateFileField($field['field_name'], $type->name, array(), array('file_path' => 'foo/bar/baz')); // Upload a new file into the subdirectories. - $nid = $this->uploadNodeFile($test_file, $field_name, $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); // Check that the file was uploaded into the subdirectory. $node = node_load($nid, NULL, TRUE); @@ -564,7 +586,7 @@ class FileFieldPathTestCase extends FileFieldTestCase { $field = $this->updateFileField($field['field_name'], $type->name, array(), array('file_path' => '[uid]/[user-raw]')); // Upload a new file into the token subdirectories. - $nid = $this->uploadNodeFile($test_file, $field_name, $type->name); + $nid = $this->uploadNodeFile($test_file, $field, $type->name); // Check that the file was uploaded into the subdirectory. $node = node_load($nid, NULL, TRUE);