Assume the following excerpt of a file object:

    [filename] => filename1
    [uri] => public://path1/filename1
    [source] => upload
    [destination] => path1/filename1

Assume the following code and the destination file exists:

$source = 'public://path1/filename1';
$destination = 'public://path2/filename2';
$file = file_move($source, $destination);

The returned file object will look like:

    [filename] => filename1
    [uri] => public://path2/filename2_n
    [source] => upload
    [destination] => path1/filename1

The file_move() code

elseif ($replace == FILE_EXISTS_RENAME && is_file($destination))

attempts to change the filename property but fails because is_file() does not recognize Drupal's stream wrapper.

Is the File API intended to keep the properties of the file object in sync? If so, should this function update the filename and destination properties in this case? i did not notice a simple equivalent to is_file() in the File API. Perhaps this would be useful here.

Comments

Anonymous’s picture

thanks for the report, i'll take a look at this.

solotandem’s picture

Any word on this?

gaele’s picture

vegantriathlete’s picture

Version: 7.x-dev » 8.3.x-dev

Note: This is still a bug as of Drupal 8.

Another way to state the issue is that when you do a file_move with FILE_EXISTS_REPLACE the uri in file_managed does not get updated. It does get updated when you use a FILE_EXISTS_RENAME.

The file itself does actually get move to the correct directory; it also gets the desired name.

vegantriathlete’s picture

Title: file_move() does not update file object properties when $replace = FILE_EXISTS_RENAME » file_move() does not update file object properties when $replace = FILE_EXISTS_REPLACE

I think the title is incorrect. I think things do work when using the default (FILE_EXISTS_RENAME). The bug is when using FILE_EXISTS_REPLACE. If I'm mistaken in changing the title, then just change it back and I'll open a new issue.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

vegantriathlete’s picture

Title: file_move() does not update file object properties when $replace = FILE_EXISTS_REPLACE » file_move() does not update file object properties when $replace = FILE_EXISTS_RENAME
Version: 8.4.x-dev » 7.x-dev

I am coming back to this. I've read the issue summary more clearly and I think the OP did intend for this to be against FILE_EXISTS_RENAME. I can't say whether this is still an issue in 7. I don't think it is an issue in 8, though.

I'm opening a new issue for the FILE_EXISTS_REPLACE.

ktrev’s picture

I am using Drupal 8.4.4
When used with hook_entity_insert, file_move is working as expected.
But when using inside hook_entity_update it is not updating the path in the file_managed table. But the file is getting replaced.

the code at both places is:

if($node->get('field_audio')->getValue()){
			$audio = $node->get('field_audio')->getValue();
			$audioFid = $audio[0]['target_id'];
			$audioFile = \Drupal\file\Entity\File::load($audioFid);
			$audioFile_uri = \Drupal\file\Entity\File::load($audioFid)->getFileUri();
			$audio_directory =  file_default_scheme() . '://lecture_audio';
			$destination = file_stream_wrapper_uri_normalize($audio_directory . '/' . $node->id() . '.mp3');
			//print_r($destination);exit;
			if($audioFile_uri != $destination)
                              file_move($audioFile, $destination, $replace = FILE_EXISTS_REPLACE);
		}
msankhala’s picture

Issue summary: View changes

Updated issue summary:

$file = file_move($file, $destination);

to

$file = file_move($source, $destination);