summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/file.inc141
-rw-r--r--modules/simpletest/tests/file.test652
-rw-r--r--modules/simpletest/tests/file_test.module28
3 files changed, 710 insertions, 111 deletions
diff --git a/includes/file.inc b/includes/file.inc
index b7a096f98..d047e1f7e 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -361,18 +361,21 @@ function file_save($file) {
* replace the file or rename the file based on the $replace parameter.
* - Adds the new file to the files database. If the source file is a
* temporary file, the resulting file will also be a temporary file.
- * @see file_save_upload about temporary files.
+ * @see file_save_upload() for details on temporary files.
*
* @param $source
* A file object.
* @param $destination
- * A string containing the directory $source should be copied to. If this
- * value is omitted, Drupal's 'files' directory will be used.
+ * A string containing the destination that $source should be copied to. This
+ * can be a complete file path, a directory path or, if this value is omitted,
+ * Drupal's 'files' directory will be used.
* @param $replace
* Replace behavior when the destination file already exists:
- * - FILE_EXISTS_REPLACE - Replace the existing file.
+ * - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with
+ * the destination name exists then its database entry will be updated. If
+ * no database entry is found then a new one will be created.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
- * unique.
+ * unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
* @return
* File object if the copy is successful, or FALSE in the event of an error.
@@ -385,14 +388,30 @@ function file_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME)
if ($filepath = file_unmanaged_copy($source->filepath, $destination, $replace)) {
$file = clone $source;
- $file->fid = NULL;
- $file->filename = basename($filepath);
+ $file->fid = NULL;
$file->filepath = $filepath;
- if ($file = file_save($file)) {
- // Inform modules that the file has been copied.
- module_invoke_all('file_copy', $file, $source);
- return $file;
+ $file->filename = basename($filepath);
+ // If we are replacing an existing file re-use its database record.
+ if ($replace == FILE_EXISTS_REPLACE) {
+ $existing_files = file_load_multiple(array(), array('filepath' => $filepath));
+ if (count($existing_files)) {
+ $existing = reset($existing_files);
+ $file->fid = $existing->fid;
+ $file->filename = $existing->filename;
+ }
}
+ // If we are renaming around an existing file (rather than a directory),
+ // use its basename for the filename.
+ else if ($replace == FILE_EXISTS_RENAME && is_file(file_create_path($destination))) {
+ $file->filename = basename($destination);
+ }
+
+ $file = file_save($file);
+
+ // Inform modules that the file has been copied.
+ module_invoke_all('file_copy', $file, $source);
+
+ return $file;
}
return FALSE;
}
@@ -412,13 +431,14 @@ function file_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME)
* @param $source
* A string specifying the file location of the original file.
* @param $destination
- * A string containing the directory $source should be copied to. If this
- * value is omitted, Drupal's 'files' directory will be used.
+ * A string containing the destination that $source should be copied to. This
+ * can be a complete file path, a directory path or, if this value is omitted,
+ * Drupal's 'files' directory will be used.
* @param $replace
* Replace behavior when the destination file already exists:
* - FILE_EXISTS_REPLACE - Replace the existing file.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
- * unique.
+ * unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
* @return
* The path to the new file, or FALSE in the event of an error.
@@ -482,7 +502,7 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST
* Replace behavior when the destination file already exists.
* - FILE_EXISTS_REPLACE - Replace the existing file.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
- * unique.
+ * unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
* @return
* The destination file path or FALSE if the file already exists and
@@ -523,13 +543,18 @@ function file_destination($destination, $replace) {
* @param $source
* A file object.
* @param $destination
- * A string containing the directory $source should be copied to. If this
- * value is omitted, Drupal's 'files' directory will be used.
+ * A string containing the destination that $source should be moved to. This
+ * can be a complete file path, a directory path or, if this value is omitted,
+ * Drupal's 'files' directory will be used.
* @param $replace
* Replace behavior when the destination file already exists:
- * - FILE_EXISTS_REPLACE - Replace the existing file.
+ * - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with
+ * the destination name exists then its database entry will be updated and
+ * file_delete() called on the source file after hook_file_move is called.
+ * If no database entry is found then the source files record will be
+ * updated.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
- * unique.
+ * unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
* @return
* Resulting file object for success, or FALSE in the event of an error.
@@ -541,15 +566,36 @@ function file_move($source, $destination = NULL, $replace = FILE_EXISTS_RENAME)
$source = (object)$source;
if ($filepath = file_unmanaged_move($source->filepath, $destination, $replace)) {
+ $delete_source = FALSE;
+
$file = clone $source;
- $file->filename = basename($filepath);
$file->filepath = $filepath;
- if ($file = file_save($file)) {
- // Inform modules that the file has been moved.
- module_invoke_all('file_move', $file, $source);
- return $file;
+ // If we are replacing an existing file re-use its database record.
+ if ($replace == FILE_EXISTS_REPLACE) {
+ $existing_files = file_load_multiple(array(), array('filepath' => $filepath));
+ if (count($existing_files)) {
+ $existing = reset($existing_files);
+ $delete_source = TRUE;
+ $file->fid = $existing->fid;
+ }
}
- drupal_set_message(t('The removal of the original file %file has failed.', array('%file' => $source->filepath)), 'error');
+ // If we are renaming around an existing file (rather than a directory),
+ // use its basename for the filename.
+ else if ($replace == FILE_EXISTS_RENAME && is_file(file_create_path($destination))) {
+ $file->filename = basename($destination);
+ }
+
+ $file = file_save($file);
+
+ // Inform modules that the file has been moved.
+ module_invoke_all('file_move', $file, $source);
+
+ if ($delete_source) {
+ // Try a soft delete to remove original if it's not in use elsewhere.
+ file_delete($source);
+ }
+
+ return $file;
}
return FALSE;
}
@@ -561,13 +607,14 @@ function file_move($source, $destination = NULL, $replace = FILE_EXISTS_RENAME)
* @param $source
* A string specifying the file location of the original file.
* @param $destination
- * A string containing the directory $source should be copied to. If this
- * value is omitted, Drupal's 'files' directory will be used.
+ * A string containing the destination that $source should be moved to. This
+ * can be a complete file path, a directory name or, if this value is omitted,
+ * Drupal's 'files' directory will be used.
* @param $replace
* Replace behavior when the destination file already exists:
* - FILE_EXISTS_REPLACE - Replace the existing file.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
- * unique.
+ * unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
* @return
* The filepath of the moved file, or FALSE in the event of an error.
@@ -875,6 +922,11 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
$file->source = $source;
$file->destination = file_destination(file_create_path($destination . '/' . $file->filename), $replace);
+ // If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
+ // there's an existing file so we need to bail.
+ if ($file->destination === FALSE) {
+ return FALSE;
+ }
// Add in our check of the the file name length.
$validators['file_validate_name_length'] = array();
@@ -905,6 +957,15 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
return FALSE;
}
+ // If we are replacing an existing file re-use its database record.
+ if ($replace == FILE_EXISTS_REPLACE) {
+ $existing_files = file_load_multiple(array(), array('filepath' => $file->filepath));
+ if (count($existing_files)) {
+ $existing = reset($existing_files);
+ $file->fid = $existing->fid;
+ }
+ }
+
// If we made it this far it's safe to record this file in the database.
if ($file = file_save($file)) {
// Add file to the cache.
@@ -1121,9 +1182,11 @@ function file_validate_image_resolution(&$file, $maximum_dimensions = 0, $minimu
* files directory.
* @param $replace
* Replace behavior when the destination file already exists:
- * - FILE_EXISTS_REPLACE - Replace the existing file.
+ * - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with
+ * the destination name exists then its database entry will be updated. If
+ * no database entry is found then a new one will be created.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
- * unique.
+ * unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
* @return
* A file object, or FALSE on error.
@@ -1136,11 +1199,27 @@ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAM
if ($filepath = file_unmanaged_save_data($data, $destination, $replace)) {
// Create a file object.
$file = new stdClass();
+ $file->fid = NULL;
$file->filepath = $filepath;
- $file->filename = basename($file->filepath);
+ $file->filename = basename($filepath);
$file->filemime = file_get_mimetype($file->filepath);
$file->uid = $user->uid;
$file->status |= FILE_STATUS_PERMANENT;
+ // If we are replacing an existing file re-use its database record.
+ if ($replace == FILE_EXISTS_REPLACE) {
+ $existing_files = file_load_multiple(array(), array('filepath' => $filepath));
+ if (count($existing_files)) {
+ $existing = reset($existing_files);
+ $file->fid = $existing->fid;
+ $file->filename = $existing->filename;
+ }
+ }
+ // If we are renaming around an existing file (rather than a directory),
+ // use its basename for the filename.
+ else if ($replace == FILE_EXISTS_RENAME && is_file(file_create_path($destination))) {
+ $file->filename = basename($destination);
+ }
+
return file_save($file);
}
return FALSE;
diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test
index ee7c9ef62..d5ca1d854 100644
--- a/modules/simpletest/tests/file.test
+++ b/modules/simpletest/tests/file.test
@@ -20,6 +20,51 @@ function file_test_validator($file, $errors) {
*/
class FileTestCase extends DrupalWebTestCase {
/**
+ * Check that two files have the same values for all fields other than the
+ * timestamp.
+ *
+ * @param $before
+ * File object to compare.
+ * @param $after
+ * File object to compare.
+ */
+ function assertFileUnchanged($before, $after) {
+ $this->assertEqual($before->fid, $after->fid, t('File id is the same: %file1 == %file2.', array('%file1' => $before->fid, '%file2' => $after->fid)), 'File unchanged');
+ $this->assertEqual($before->uid, $after->uid, t('File owner is the same: %file1 == %file2.', array('%file1' => $before->uid, '%file2' => $after->uid)), 'File unchanged');
+ $this->assertEqual($before->filename, $after->filename, t('File name is the same: %file1 == %file2.', array('%file1' => $before->filename, '%file2' => $after->filename)), 'File unchanged');
+ $this->assertEqual($before->filepath, $after->filepath, t('File path is the same: %file1 == %file2.', array('%file1' => $before->filepath, '%file2' => $after->filepath)), 'File unchanged');
+ $this->assertEqual($before->filemime, $after->filemime, t('File MIME type is the same: %file1 == %file2.', array('%file1' => $before->filemime, '%file2' => $after->filemime)), 'File unchanged');
+ $this->assertEqual($before->filesize, $after->filesize, t('File size is the same: %file1 == %file2.', array('%file1' => $before->filesize, '%file2' => $after->filesize)), 'File unchanged');
+ $this->assertEqual($before->status, $after->status, t('File status is the same: %file1 == %file2.', array('%file1' => $before->status, '%file2' => $after->status)), 'File unchanged');
+ }
+
+ /**
+ * Check that two files are not the same by comparing the fid and filepath.
+ *
+ * @param $file1
+ * File object to compare.
+ * @param $file2
+ * File object to compare.
+ */
+ function assertDifferentFile($file1, $file2) {
+ $this->assertNotEqual($file1->fid, $file2->fid, t('Files have different ids: %file1 != %file2.', array('%file1' => $file1->fid, '%file2' => $file2->fid)), 'Different file');
+ $this->assertNotEqual($file1->filepath, $file2->filepath, t('Files have different paths: %file1 != %file2.', array('%file1' => $file1->filepath, '%file2' => $file2->filepath)), 'Different file');
+ }
+
+ /**
+ * Check that two files are the same by comparing the fid and filepath.
+ *
+ * @param $file1
+ * File object to compare.
+ * @param $file2
+ * File object to compare.
+ */
+ function assertSameFile($file1, $file2) {
+ $this->assertEqual($file1->fid, $file2->fid, t('Files have the same ids: %file1 == %file2.', array('%file1' => $file1->fid, '%file2-fid' => $file2->fid)), 'Same file');
+ $this->assertEqual($file1->filepath, $file2->filepath, t('Files have the same path: %file1 == %file2.', array('%file1' => $file1->filepath, '%file2' => $file2->filepath)), 'Same file');
+ }
+
+ /**
* Helper function to test the permissions of a file.
*
* @param $filepath
@@ -68,16 +113,23 @@ class FileTestCase extends DrupalWebTestCase {
* @param $filepath
* Optional string specifying the file path. If none is provided then a
* randomly named file will be created in the site's files directory.
+ * @param $contents
+ * Optional contents to save into the file. If a NULL value is provided an
+ * arbitrary string will be used.
* @return
* File object.
*/
- function createFile($filepath = NULL) {
+ function createFile($filepath = NULL, $contents = NULL) {
if (is_null($filepath)) {
$filepath = file_directory_path() . '/' . $this->randomName();
}
- file_put_contents($filepath, 'File put contents does not seem to appreciate empty strings so lets put in some data.');
- $this->assertTrue(is_file($filepath), t('The test file exists on the disk.'));
+ if (is_null($contents)) {
+ $contents = "file_put_contents() doesn't seem to appreciate empty strings so let's put in some data.";
+ }
+
+ file_put_contents($filepath, $contents);
+ $this->assertTrue(is_file($filepath), t('The test file exists on the disk.'), 'Create test file');
$file = new stdClass();
$file->filepath = $filepath;
@@ -87,7 +139,9 @@ class FileTestCase extends DrupalWebTestCase {
$file->timestamp = REQUEST_TIME;
$file->filesize = filesize($file->filepath);
$file->status = 0;
- $this->assertNotIdentical(drupal_write_record('files', $file), FALSE, t('The file was added to the database.'));
+ // Write the record directly rather than calling file_save() so we don't
+ // invoke the hooks.
+ $this->assertNotIdentical(drupal_write_record('files', $file), FALSE, t('The file was added to the database.'), 'Create test file');
return $file;
}
@@ -106,6 +160,37 @@ class FileHookTestCase extends FileTestCase {
}
/**
+ * Assert that all of the specified hook_file_* hooks were called once, other
+ * values result in failure.
+ *
+ * @param $expected
+ * Array with string containing with the hook name, e.g. 'load', 'save',
+ * 'insert', etc.
+ */
+ function assertFileHooksCalled($expected) {
+ // Determine which hooks were called.
+ $actual = array_keys(array_filter(file_test_get_all_calls()));
+
+ // Determine if there were any expected that were not called.
+ $uncalled = array_diff($expected, $actual);
+ if (count($uncalled)) {
+ $this->assertTrue(FALSE, t('Expected hooks %expected to be called but %uncalled was not called.', array('%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled))));
+ }
+ else {
+ $this->assertTrue(TRUE, t('All the expected hooks were called: %expected', array('%expected' => implode(', ', $expected))));
+ }
+
+ // Determine if there were any unexpected calls.
+ $unexpected = array_diff($actual, $expected);
+ if (count($unexpected)) {
+ $this->assertTrue(FALSE, t('Unexpected hooks were called: %unexpected.', array('%unexpected' => implode(', ', $unexpected))));
+ }
+ else {
+ $this->assertTrue(TRUE, t('No unexpected hooks were called.'));
+ }
+ }
+
+ /**
* Assert that a hook_file_* hook was called a certain number of times.
*
* @param $hook
@@ -122,6 +207,9 @@ class FileHookTestCase extends FileTestCase {
if ($actual_count == $expected_count) {
$message = t('hook_file_@name was called correctly.', array('@name' => $hook));
}
+ elseif ($expected_count == 0) {
+ $message = format_plural($actual_count, 'hook_file_@name was not expected to be called but was actually called once.', 'hook_file_@name was not expected to be called but was actually called @count times.', array('@name' => $hook, '@count' => $actual_count));
+ }
else {
$message = t('hook_file_@name was expected to be called %expected times but was called %actual times.', array('@name' => $hook, '%expected' => $expected_count, '%actual' => $actual_count));
}
@@ -387,6 +475,16 @@ class FileUnmanagedSaveDataTest extends FileTestCase {
* Test the file_save_upload() function.
*/
class FileSaveUploadTest extends FileHookTestCase {
+ /**
+ * An image file path for uploading.
+ */
+ var $image;
+
+ /**
+ * The largest file id when the test starts.
+ */
+ var $maxFidBefore;
+
function getInfo() {
return array(
'name' => t('File uploading'),
@@ -395,36 +493,55 @@ class FileSaveUploadTest extends FileHookTestCase {
);
}
- /**
- * Test the file_save_upload() function.
- */
- function testFileSaveUpload() {
- $max_fid_before = db_query('SELECT MAX(fid) AS fid FROM {files}')->fetchField();
- $upload_user = $this->drupalCreateUser(array('access content'));
- $this->drupalLogin($upload_user);
+ function setUp() {
+ parent::setUp();
+ $account = $this->drupalCreateUser(array('access content'));
+ $this->drupalLogin($account);
- $image = current($this->drupalGetTestFiles('image'));
- $this->assertTrue(is_file($image->filename), t("The file we're going to upload exists."));
- $edit = array('files[file_test_upload]' => realpath($image->filename));
+ $this->image = current($this->drupalGetTestFiles('image'));
+ $this->assertTrue(is_file($this->image->filename), t("The file we're going to upload exists."));
+
+ $this->maxFidBefore = db_query('SELECT MAX(fid) AS fid FROM {files}')->fetchField();
+
+ // Upload with replace to gurantee there's something there.
+ $edit = array(
+ 'file_test_replace' => FILE_EXISTS_REPLACE,
+ 'files[file_test_upload]' => realpath($this->image->filename)
+ );
$this->drupalPost('file-test/upload', $edit, t('Submit'));
$this->assertResponse(200, t('Received a 200 response for posted test file.'));
+ $this->assertRaw(t('You WIN!'), t('Found the success message.'));
- // We can't easily check that the hooks were called but since
- // file_save_upload() calles file_save() we can rely on file_save()'s
- // test to catch problems invoking the hooks.
+ // Check that the correct hooks were called then clean out the hook
+ // counters.
+ $this->assertFileHooksCalled(array('validate', 'insert'));
+ file_test_reset();
+ }
+ /**
+ * Test the file_save_upload() function.
+ */
+ function testNormal() {
$max_fid_after = db_result(db_query('SELECT MAX(fid) AS fid FROM {files}'));
- $this->assertTrue($max_fid_after > $max_fid_before, t('A new file was created.'));
+ $this->assertTrue($max_fid_after > $this->maxFidBefore, t('A new file was created.'));
$file1 = file_load($max_fid_after);
$this->assertTrue($file1, t('Loaded the file.'));
+ // Reset the hook counters to get rid of the 'load' we just called.
+ file_test_reset();
+
// Upload a second file.
$max_fid_before = db_query('SELECT MAX(fid) AS fid FROM {files}')->fetchField();
$image2 = current($this->drupalGetTestFiles('image'));
$edit = array('files[file_test_upload]' => realpath($image2->filename));
$this->drupalPost('file-test/upload', $edit, t('Submit'));
+ $this->assertResponse(200, t('Received a 200 response for posted test file.'));
+ $this->assertRaw(t('You WIN!'));
$max_fid_after = db_query('SELECT MAX(fid) AS fid FROM {files}')->fetchField();
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('validate', 'insert'));
+
$file2 = file_load($max_fid_after);
$this->assertTrue($file2);
@@ -433,6 +550,55 @@ class FileSaveUploadTest extends FileHookTestCase {
$this->assertTrue(isset($files[$file1->fid]), t('File was loaded successfully'));
$this->assertTrue(isset($files[$file2->fid]), t('File was loaded successfully'));
}
+
+
+ /**
+ * Test renaming when uploading over a file that already exists.
+ */
+ function testExistingRename() {
+ $edit = array(
+ 'file_test_replace' => FILE_EXISTS_RENAME,
+ 'files[file_test_upload]' => realpath($this->image->filename)
+ );
+ $this->drupalPost('file-test/upload', $edit, t('Submit'));
+ $this->assertResponse(200, t('Received a 200 response for posted test file.'));
+ $this->assertRaw(t('You WIN!'), t('Found the success message.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('validate', 'insert'));
+ }
+
+ /**
+ * Test replacement when uploading over a file that already exists.
+ */
+ function testExistingReplace() {
+ $edit = array(
+ 'file_test_replace' => FILE_EXISTS_REPLACE,
+ 'files[file_test_upload]' => realpath($this->image->filename)
+ );
+ $this->drupalPost('file-test/upload', $edit, t('Submit'));
+ $this->assertResponse(200, t('Received a 200 response for posted test file.'));
+ $this->assertRaw(t('You WIN!'), t('Found the success message.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('validate', 'load', 'update'));
+ }
+
+ /**
+ * Test for failure when uploading over a file that already exists.
+ */
+ function testExistingError() {
+ $edit = array(
+ 'file_test_replace' => FILE_EXISTS_ERROR,
+ 'files[file_test_upload]' => realpath($this->image->filename)
+ );
+ $this->drupalPost('file-test/upload', $edit, t('Submit'));
+ $this->assertResponse(200, t('Received a 200 response for posted test file.'));
+ $this->assertRaw(t('Epic upload FAIL!'), t('Found the failure message.'));
+
+ // Check that the no hooks were called while failing.
+ $this->assertFileHooksCalled(array());
+ }
}
/**
@@ -855,8 +1021,7 @@ class FileDeleteTest extends FileHookTestCase {
// Check that deletion removes the file and database record.
$this->assertTrue(is_file($file->filepath), t("File exists."));
$this->assertIdentical(file_delete($file), TRUE, t("Delete worked."));
- $this->assertFileHookCalled('references');
- $this->assertFileHookCalled('delete');
+ $this->assertFileHooksCalled(array('references', 'delete'));
$this->assertFalse(file_exists($file->filepath), t("Test file has actually been deleted."));
$this->assertFalse(file_load($file->fid), t('File was removed from the database.'));
@@ -882,19 +1047,147 @@ class FileMoveTest extends FileHookTestCase {
* Move a normal file.
*/
function testNormal() {
- $file = $this->createFile();
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
$desired_filepath = file_directory_path() . '/' . $this->randomName();
- $file = file_move(clone $file, $desired_filepath, FILE_EXISTS_ERROR);
- $this->assertTrue($file, t("File moved sucessfully."));
- $this->assertFileHookCalled('move');
- $this->assertFileHookCalled('update');
- $this->assertEqual($file->fid, $file->fid, t("File id $file->fid is unchanged after move."));
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_move(clone $source, $desired_filepath, FILE_EXISTS_ERROR);
+
+ // Check the return status and that the contents changed.
+ $this->assertTrue($result, t('File moved sucessfully.'));
+ $this->assertFalse(file_exists($source->filepath));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of file correctly written.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('move', 'update'));
+
+ // Make sure we got the same file back.
+ $this->assertEqual($source->fid, $result->fid, t("Source file id's' %fid is unchanged after move.", array('%fid' => $source->fid)));
+
+ // Reload the file from the database and check that the changes were
+ // actually saved.
+ $loaded_file = file_load($result->fid, TRUE);
+ $this->assertTrue($loaded_file, t('File can be loaded from the database.'));
+ $this->assertFileUnchanged($result, $loaded_file);
+ }
+
+ /**
+ * Test renaming when moving onto a file that already exists.
+ */
+ function testExistingRename() {
+ // Setup a file to overwrite.
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
+ $target = $this->createFile();
+ $this->assertDifferentFile($source, $target);
+
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_move(clone $source, $target->filepath, FILE_EXISTS_RENAME);
+
+ // Check the return status and that the contents changed.
+ $this->assertTrue($result, t('File moved sucessfully.'));
+ $this->assertFalse(file_exists($source->filepath));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of file correctly written.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('move', 'update'));
+
+ // Compare the returned value to what made it into the database.
+ $this->assertFileUnchanged($result, file_load($result->fid, TRUE));
+ // The target file should not have been altered.
+ $this->assertFileUnchanged($target, file_load($target->fid, TRUE));
+ // Make sure we end up with two distinct files afterwards.
+ $this->assertDifferentFile($target, $result);
+
+ // Compare the source and results.
+ $loaded_source = file_load($source->fid, TRUE);
+ $this->assertEqual($loaded_source->fid, $result->fid, t("Returned file's id matches the source."));
+ $this->assertNotEqual($loaded_source->filepath, $source->filepath, t("Returned file path has changed from the original."));
+ }
+
+ /**
+ * Test replacement when moving onto a file that already exists.
+ */
+ function testExistingReplace() {
+ // Setup a file to overwrite.
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
+ $target = $this->createFile();
+ $this->assertDifferentFile($source, $target);
+
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_move(clone $source, $target->filepath, FILE_EXISTS_REPLACE);
+
+ // Look at the results.
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of file were overwritten.'));
+ $this->assertFalse(file_exists($source->filepath));
+ $this->assertTrue($result, t('File moved sucessfully.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('move', 'update', 'delete', 'references', 'load'));
+
+ // Reload the file from the database and check that the changes were
+ // actually saved.
+ $loaded_result = file_load($result->fid, TRUE);
+ $this->assertFileUnchanged($result, $loaded_result);
+ // Check that target was re-used.
+ $this->assertSameFile($target, $loaded_result);
+ // Source and result should be totally different.
+ $this->assertDifferentFile($source, $loaded_result);
+ }
+
+ /**
+ * Test replacement when moving onto itself.
+ */
+ function testExistingReplaceSelf() {
+ // Setup a file to overwrite.
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
+
+ // Copy the file over itself. Clone the object so we don't have to worry
+ // about the function changing our reference copy.
+ $result = file_move(clone $source, $source->filepath, FILE_EXISTS_REPLACE);
+ $this->assertFalse($result, t('File move failed.'));
+ $this->assertEqual($contents, file_get_contents($source->filepath), t('Contents of file were not altered.'));
+
+ // Check that no hooks were called while failing.
+ $this->assertFileHooksCalled(array());
+
+ // Load the file from the database and make sure it is identical to what
+ // was returned.
+ $this->assertFileUnchanged($source, file_load($source->fid, TRUE));
+ }
+
+ /**
+ * Test that moving onto an existing file fails when FILE_EXISTS_ERROR is
+ * specified.
+ */
+ function testExistingError() {
+ $contents = $this->randomName(10);
+ $source = $this->createFile();
+ $target = $this->createFile(NULL, $contents);
+ $this->assertDifferentFile($source, $target);
+
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_move(clone $source, $target->filepath, FILE_EXISTS_ERROR);
- $loaded_file = file_load($file->fid);
- $this->assertTrue($loaded_file, t("File can be loaded from the database."));
- $this->assertEqual($file->filename, $loaded_file->filename, t("File name was updated correctly in the database."));
- $this->assertEqual($file->filepath, $loaded_file->filepath, t("File path was updated correctly in the database."));
+ // Check the return status and that the contents did not change.
+ $this->assertFalse($result, t('File move failed.'));
+ $this->assertTrue(file_exists($source->filepath));
+ $this->assertEqual($contents, file_get_contents($target->filepath), t('Contents of file were not altered.'));
+
+ // Check that no hooks were called while failing.
+ $this->assertFileHooksCalled(array());
+
+ // Load the file from the database and make sure it is identical to what
+ // was returned.
+ $this->assertFileUnchanged($source, file_load($source->fid, TRUE));
+ $this->assertFileUnchanged($target, file_load($target->fid, TRUE));
}
}
@@ -912,27 +1205,135 @@ class FileCopyTest extends FileHookTestCase {
}
/**
- * Test copying a normal file.
+ * Test file copying in the normal, base case.
*/
function testNormal() {
- $source_file = $this->createFile();
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
$desired_filepath = file_directory_path() . '/' . $this->randomName();
- $file = file_copy(clone $source_file, $desired_filepath, FILE_EXISTS_ERROR);
- $this->assertTrue($file, t("File copied sucessfully."));
- $this->assertFileHookCalled('copy');
- $this->assertFileHookCalled('insert');
- $this->assertNotEqual($source_file->fid, $file->fid, t("A new file id was created."));
- $this->assertNotEqual($source_file->filepath, $file->filepath, t("A new filepath was created."));
- $this->assertEqual($file->filepath, $desired_filepath, t('The copied file object has the desired filepath.'));
- $this->assertTrue(file_exists($source_file->filepath), t('The original file still exists.'));
- $this->assertTrue(file_exists($file->filepath), t('The copied file exists.'));
-
- // Check that the changes were actually saved to the database.
- $loaded_file = file_load($file->fid);
- $this->assertTrue($loaded_file, t("File can be loaded from the database."));
- $this->assertEqual($file->filename, $loaded_file->filename, t("File name was updated correctly in the database."));
- $this->assertEqual($file->filepath, $loaded_file->filepath, t("File path was updated correctly in the database."));
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_copy(clone $source, $desired_filepath, FILE_EXISTS_ERROR);
+
+ // Check the return status and that the contents changed.
+ $this->assertTrue($result, t('File copied sucessfully.'));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of file were copied correctly.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('copy', 'insert'));
+
+ $this->assertDifferentFile($source, $result);
+ $this->assertEqual($result->filepath, $desired_filepath, t('The copied file object has the desired filepath.'));
+ $this->assertTrue(file_exists($source->filepath), t('The original file still exists.'));
+ $this->assertTrue(file_exists($result->filepath), t('The copied file exists.'));
+
+ // Reload the file from the database and check that the changes were
+ // actually saved.
+ $this->assertFileUnchanged($result, file_load($result->fid, TRUE));
+ }
+
+ /**
+ * Test renaming when copying over a file that already exists.
+ */
+ function testExistingRename() {
+ // Setup a file to overwrite.
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
+ $target = $this->createFile();
+ $this->assertDifferentFile($source, $target);
+
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_copy(clone $source, $target->filepath, FILE_EXISTS_RENAME);
+
+ // Check the return status and that the contents changed.
+ $this->assertTrue($result, t('File copied sucessfully.'));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of file were copied correctly.'));
+ $this->assertNotEqual($result->filepath, $source->filepath, t('Returned file path has changed from the original.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('copy', 'insert'));
+
+ // Load all the affected files to check the changes that actually made it
+ // to the database.
+ $loaded_source = file_load($source->fid, TRUE);
+ $loaded_target = file_load($target->fid, TRUE);
+ $loaded_result = file_load($result->fid, TRUE);
+
+ // Verify that the source file wasn't changed.
+ $this->assertFileUnchanged($source, $loaded_source);
+
+ // Verify that what was returned is what's in the database.
+ $this->assertFileUnchanged($result, $loaded_result);
+
+ // Make sure we end up with three distinct files afterwards.
+ $this->assertDifferentFile($loaded_source, $loaded_target);
+ $this->assertDifferentFile($loaded_target, $loaded_result);
+ $this->assertDifferentFile($loaded_source, $loaded_result);
+ }
+
+ /**
+ * Test replacement when copying over a file that already exists.
+ */
+ function testExistingReplace() {
+ // Setup a file to overwrite.
+ $contents = $this->randomName(10);
+ $source = $this->createFile(NULL, $contents);
+ $target = $this->createFile();
+ $this->assertDifferentFile($source, $target);
+
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_copy(clone $source, $target->filepath, FILE_EXISTS_REPLACE);
+
+ // Check the return status and that the contents changed.
+ $this->assertTrue($result, t('File copied sucessfully.'));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of file were overwritten.'));
+ $this->assertDifferentFile($source, $result);
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('load', 'copy', 'update'));
+
+ // Load all the affected files to check the changes that actually made it
+ // to the database.
+ $loaded_source = file_load($source->fid, TRUE);
+ $loaded_target = file_load($target->fid, TRUE);
+ $loaded_result = file_load($result->fid, TRUE);
+
+ // Verify that the source file wasn't changed.
+ $this->assertFileUnchanged($source, $loaded_source);
+
+ // Verify that what was returned is what's in the database.
+ $this->assertFileUnchanged($result, $loaded_result);
+
+ // Target file was reused for the result.
+ $this->assertFileUnchanged($loaded_target, $loaded_result);
+ }
+
+ /**
+ * Test that copying over an existing file fails when FILE_EXISTS_ERROR is
+ * specified.
+ */
+ function testExistingError() {
+ $contents = $this->randomName(10);
+ $source = $this->createFile();
+ $target = $this->createFile(NULL, $contents);
+ $this->assertDifferentFile($source, $target);
+
+ // Clone the object so we don't have to worry about the function changing
+ // our reference copy.
+ $result = file_copy(clone $source, $target->filepath, FILE_EXISTS_ERROR);
+
+ // Check the return status and that the contents were not changed.
+ $this->assertFalse($result, t('File copy failed.'));
+ $this->assertEqual($contents, file_get_contents($target->filepath), t('Contents of file were not altered.'));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array());
+
+ $this->assertFileUnchanged($source, file_load($source->fid, TRUE));
+ $this->assertFileUnchanged($target, file_load($target->fid, TRUE));
}
}
@@ -954,7 +1355,7 @@ class FileLoadTest extends FileHookTestCase {
*/
function testLoadMissingFid() {
$this->assertFalse(file_load(-1), t("Try to load an invalid fid fails."));
- $this->assertFileHookCalled('load', 0);
+ $this->assertFileHooksCalled(array());
}
/**
@@ -962,7 +1363,7 @@ class FileLoadTest extends FileHookTestCase {
*/
function testLoadMissingFilepath() {
$this->assertFalse(reset(file_load_multiple(array(), array('filepath' => 'misc/druplicon.png'))), t("Try to load a file that doesn't exist in the database fails."));
- $this->assertFileHookCalled('load', 0);
+ $this->assertFileHooksCalled(array());
}
/**
@@ -970,7 +1371,7 @@ class FileLoadTest extends FileHookTestCase {
*/
function testLoadInvalidStatus() {
$this->assertFalse(reset(file_load_multiple(array(), array('status' => -99))), t("Trying to load a file with an invalid status fails."));
- $this->assertFileHookCalled('load', 0);
+ $this->assertFileHooksCalled(array());
}
/**
@@ -989,7 +1390,7 @@ class FileLoadTest extends FileHookTestCase {
$file = file_save($file);
$by_fid_file = file_load($file->fid);
- $this->assertFileHookCalled('load', 1);
+ $this->assertFileHookCalled('load');
$this->assertTrue(is_object($by_fid_file), t('file_load() returned an object.'));
$this->assertEqual($by_fid_file->fid, $file->fid, t("Loading by fid got the same fid."), 'File');
$this->assertEqual($by_fid_file->filepath, $file->filepath, t("Loading by fid got the correct filepath."), 'File');
@@ -1017,7 +1418,7 @@ class FileLoadTest extends FileHookTestCase {
// Load by path.
file_test_reset();
$by_path_files = file_load_multiple(array(), array('filepath' => $file->filepath));
- $this->assertFileHookCalled('load', 1);
+ $this->assertFileHookCalled('load');
$this->assertEqual(1, count($by_path_files), t('file_load_multiple() returned an array of the correct size.'));
$by_path_file = reset($by_path_files);
$this->assertTrue($by_path_file->file_test['loaded'], t('file_test_file_load() was able to modify the file during load.'));
@@ -1026,7 +1427,7 @@ class FileLoadTest extends FileHookTestCase {
// Load by fid.
file_test_reset();
$by_fid_files = file_load_multiple(array($file->fid), array());
- $this->assertFileHookCalled('load', 1);
+ $this->assertFileHookCalled('load');
$this->assertEqual(1, count($by_fid_files), t('file_load_multiple() returned an array of the correct size.'));
$by_fid_file = reset($by_fid_files);
$this->assertTrue($by_fid_file->file_test['loaded'], t('file_test_file_load() was able to modify the file during load.'));
@@ -1060,7 +1461,10 @@ class FileSaveTest extends FileHookTestCase {
// Save it, inserting a new record.
$saved_file = file_save($file);
- $this->assertFileHookCalled('insert');
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('insert'));
+
$this->assertNotNull($saved_file, t("Saving the file should give us back a file object."), 'File');
$this->assertTrue($saved_file->fid > 0, t("A new file ID is set when saving a new file to the database."), 'File');
$loaded_file = db_query('SELECT * FROM {files} f WHERE f.fid = :fid', array(':fid' => $saved_file->fid))->fetch(PDO::FETCH_OBJ);
@@ -1069,11 +1473,15 @@ class FileSaveTest extends FileHookTestCase {
$this->assertEqual($saved_file->filesize, filesize($file->filepath), t("File size was set correctly."), 'File');
$this->assertTrue($saved_file->timestamp > 1, t("File size was set correctly."), 'File');
+
// Resave the file, updating the existing record.
file_test_reset();
$saved_file->status = 7;
$resaved_file = file_save($saved_file);
- $this->assertFileHookCalled('update');
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('update'));
+
$this->assertEqual($resaved_file->fid, $saved_file->fid, t("The file ID of an existing file is not changed when updating the database."), 'File');
$this->assertTrue($resaved_file->timestamp >= $saved_file->timestamp, t("Timestamp didn't go backwards."), 'File');
$loaded_file = db_query('SELECT * FROM {files} f WHERE f.fid = :fid', array(':fid' => $saved_file->fid))->fetch(PDO::FETCH_OBJ);
@@ -1103,7 +1511,7 @@ class FileValidateTest extends FileHookTestCase {
// Empty validators.
$this->assertEqual(file_validate($file, array()), array(), t('Validating an empty array works succesfully.'));
- $this->assertFileHookCalled('validate', 1);
+ $this->assertFileHooksCalled(array('validate'));
// Use the file_test.module's test validator to ensure that passing tests
// return correctly.
@@ -1111,14 +1519,14 @@ class FileValidateTest extends FileHookTestCase {
file_test_set_return('validate', array());
$passing = array('file_test_validator' => array(array()));
$this->assertEqual(file_validate($file, $passing), array(), t('Validating passes.'));
- $this->assertFileHookCalled('validate', 1);
+ $this->assertFileHooksCalled(array('validate'));
// Now test for failures in validators passed in and by hook_validate.
file_test_reset();
file_test_set_return('validate', array('Epic fail'));
$failing = array('file_test_validator' => array(array('Failed', 'Badly')));
$this->assertEqual(file_validate($file, $failing), array('Failed', 'Badly', 'Epic fail'), t('Validating returns errors.'));
- $this->assertFileHookCalled('validate', 1);
+ $this->assertFileHooksCalled(array('validate'));
}
}
@@ -1135,33 +1543,121 @@ class FileSaveDataTest extends FileHookTestCase {
}
/**
- * Test the file_save_data() function.
+ * Test the file_save_data() function when no filename is provided.
*/
- function testFileSaveData() {
+ function testWithoutFilename() {
$contents = $this->randomName(8);
- // No filename.
- $file = file_save_data($contents);
- $this->assertTrue($file, t("Unnamed file saved correctly."));
- $this->assertEqual(file_directory_path(), dirname($file->filepath), t("File was placed in Drupal's files directory."));
- $this->assertEqual($contents, file_get_contents(realpath($file->filepath)), t("Contents of the file are correct."));
- $this->assertEqual($file->filemime, 'application/octet-stream', t("A MIME type was set."));
- $this->assertEqual($file->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
+ $result = file_save_data($contents);
+ $this->assertTrue($result, t('Unnamed file saved correctly.'));
- // Try loading the file.
- $loaded_file = file_load($file->fid);
- $this->assertTrue($loaded_file, t("File loaded from database."));
+ $this->assertEqual(file_directory_path(), dirname($result->filepath), t("File was placed in Drupal's files directory."));
+ $this->assertEqual($result->filename, basename($result->filepath), t("Filename was set to the file's basename."));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of the file are correct.'));
+ $this->assertEqual($result->filemime, 'application/octet-stream', t('A MIME type was set.'));
+ $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
- // Provide a filename.
- $file = file_save_data($contents, 'asdf.txt', FILE_EXISTS_REPLACE);
- $this->assertTrue($file, t("Unnamed file saved correctly."));
- $this->assertEqual(file_directory_path(), dirname($file->filepath), t("File was placed in Drupal's files directory."));
- $this->assertEqual('asdf.txt', basename($file->filepath), t("File was named correctly."));
- $this->assertEqual($contents, file_get_contents(realpath($file->filepath)), t("Contents of the file are correct."));
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('insert'));
+
+ // Verify that what was returned is what's in the database.
+ $this->assertFileUnchanged($result, file_load($result->fid, TRUE));
+ }
+
+ /**
+ * Test the file_save_data() function when a filename is provided.
+ */
+ function testWithFilename() {
+ $contents = $this->randomName(8);
+
+ $result = file_save_data($contents, 'asdf.txt');
+ $this->assertTrue($result, t('Unnamed file saved correctly.'));
+
+ $this->assertEqual(file_directory_path(), dirname($result->filepath), t("File was placed in Drupal's files directory."));
+ $this->assertEqual('asdf.txt', basename($result->filepath), t('File was named correctly.'));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of the file are correct.'));
+ $this->assertEqual($result->filemime, 'text/plain', t('A MIME type was set.'));
+ $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('insert'));
+
+ // Verify that what was returned is what's in the database.
+ $this->assertFileUnchanged($result, file_load($result->fid, TRUE));
+ }
+
+ /**
+ * Test file_save_data() when renaming around an existing file.
+ */
+ function testExistingRename() {
+ // Setup a file to overwrite.
+ $existing = $this->createFile();
+ $contents = $this->randomName(8);
+
+ $result = file_save_data($contents, $existing->filepath, FILE_EXISTS_RENAME);
+ $this->assertTrue($result, t("File saved sucessfully."));
+
+ $this->assertEqual(file_directory_path(), dirname($result->filepath), t("File was placed in Drupal's files directory."));
+ $this->assertEqual($result->filename, $existing->filename, t("Filename was set to the basename of the source, rather than that of the renamed file."));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t("Contents of the file are correct."));
+ $this->assertEqual($result->filemime, 'application/octet-stream', t("A MIME type was set."));
+ $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('insert'));
+
+ // Ensure that the existing file wasn't overwritten.
+ $this->assertDifferentFile($existing, $result);
+ $this->assertFileUnchanged($existing, file_load($existing->fid, TRUE));
+
+ // Verify that was returned is what's in the database.
+ $this->assertFileUnchanged($result, file_load($result->fid, TRUE));
+ }
+
+ /**
+ * Test file_save_data() when replacing an existing file.
+ */
+ function testExistingReplace() {
+ // Setup a file to overwrite.
+ $existing = $this->createFile();
+ $contents = $this->randomName(8);
+
+ $result = file_save_data($contents, $existing->filepath, FILE_EXISTS_REPLACE);
+ $this->assertTrue($result, t('File saved sucessfully.'));
+
+ $this->assertEqual(file_directory_path(), dirname($result->filepath), t("File was placed in Drupal's files directory."));
+ $this->assertEqual($result->filename, $existing->filename, t('Filename was set to the basename of the existing file, rather than preserving the original name.'));
+ $this->assertEqual($contents, file_get_contents($result->filepath), t('Contents of the file are correct.'));
+ $this->assertEqual($result->filemime, 'application/octet-stream', t('A MIME type was set.'));
+ $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
+
+ // Check that the correct hooks were called.
+ $this->assertFileHooksCalled(array('load', 'update'));
+
+ // Verify that the existing file was re-used.
+ $this->assertSameFile($existing, $result);
+
+ // Verify that what was returned is what's in the database.
+ $this->assertFileUnchanged($result, file_load($result->fid, TRUE));
+ }
+
+ /**
+ * Test that file_save_data() fails overwriting an existing file.
+ */
+ function testExistingError() {
+ $contents = $this->randomName(8);
+ $existing = $this->createFile(NULL, $contents);
// Check the overwrite error.
- $file = file_save_data($contents, 'asdf.txt', FILE_EXISTS_ERROR);
- $this->assertFalse($file, t("Overwriting a file fails when FILE_EXISTS_ERROR is specified."));
+ $result = file_save_data('asdf', $existing->filepath, FILE_EXISTS_ERROR);
+ $this->assertFalse($result, t('Overwriting a file fails when FILE_EXISTS_ERROR is specified.'));
+ $this->assertEqual($contents, file_get_contents($existing->filepath), t('Contents of existing file were unchanged.'));
+
+ // Check that no hooks were called while failing.
+ $this->assertFileHooksCalled(array());
+
+ // Ensure that the existing file wasn't overwritten.
+ $this->assertFileUnchanged($existing, file_load($existing->fid, TRUE));
}
}
diff --git a/modules/simpletest/tests/file_test.module b/modules/simpletest/tests/file_test.module
index 7a9644f0d..899bbdc43 100644
--- a/modules/simpletest/tests/file_test.module
+++ b/modules/simpletest/tests/file_test.module
@@ -32,6 +32,16 @@ function _file_test_form(&$form_state) {
'#type' => 'file',
'#title' => t('Upload an image'),
);
+ $form['file_test_replace'] = array(
+ '#type' => 'select',
+ '#title' => t('Replace existing image'),
+ '#options' => array(
+ FILE_EXISTS_RENAME => t('Appends number until name is unique'),
+ FILE_EXISTS_REPLACE => t('Replace the existing file'),
+ FILE_EXISTS_ERROR => t('Fail with an error'),
+ ),
+ '#default_value' => FILE_EXISTS_RENAME,
+ );
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
@@ -43,11 +53,13 @@ function _file_test_form(&$form_state) {
* Process the upload.
*/
function _file_test_form_submit(&$form, &$form_state) {
- // Validate the uploaded picture.
- $file = file_save_upload('file_test_upload', array('file_validate_is_image' => array()));
+ // Process the upload and validate that it is an image. Note: we're using the
+ // form value for the $replace parameter.
+ $file = file_save_upload('file_test_upload', array('file_validate_is_image' => array()), FALSE, $form_state['values']['file_test_replace']);
if ($file) {
$form_state['values']['file_test_upload'] = $file;
drupal_set_message(t('File @filepath was uploaded.', array('@filepath' => $file->filepath)));
+ drupal_set_message(t('You WIN!'));
}
else {
drupal_set_message(t('Epic upload FAIL!'), 'error');
@@ -101,6 +113,18 @@ function file_test_get_calls($op) {
}
/**
+ * Get an array with the calls for all hooks.
+ *
+ * @return
+ * An array keyed by hook name ('load', 'validate', 'download',
+ * 'references', 'insert', 'update', 'copy', 'move', 'delete') with values
+ * being arrays of parameters passed to each call.
+ */
+function file_test_get_all_calls() {
+ return variable_get('file_test_results', array());
+}
+
+/**
* Store the values passed to a hook invocation.
*
* @param $op