MDL-39177 File reference is not updated when overwriting the file

This commit is contained in:
Marina Glancy 2013-05-08 12:48:54 +10:00
parent c9b4b8d83a
commit e9e32b1d88
4 changed files with 45 additions and 2 deletions

View File

@ -101,6 +101,7 @@ $string['enter'] = 'Enter';
$string['entername'] = 'Please enter folder name';
$string['enternewname'] = 'Please enter the new file name';
$string['error'] = 'An unknown error occurred!';
$string['errordoublereference'] = 'Unable to overwrite file with a shortcut/alias because shortcuts to this file already exist.';
$string['errornotyourfile'] = 'You cannot pick file which is not added by your';
$string['erroruniquename'] = 'Repository instance name should be unique';
$string['errorpostmaxsize'] = 'The uploaded file may exceed the post_max_size directive in php.ini.';

View File

@ -889,9 +889,14 @@ function file_save_draft_area_files($draftitemid, $contextid, $component, $filea
$oldfile->set_timemodified($newfile->get_timemodified());
}
if ($newfile->is_external_file() && !$allowreferences) {
continue;
}
// Replaced file content
if ($oldfile->get_contenthash() != $newfile->get_contenthash() || $oldfile->get_filesize() != $newfile->get_filesize()) {
$oldfile->replace_content_with($newfile);
else if ($oldfile->get_contenthash() != $newfile->get_contenthash() ||
$oldfile->get_filesize() != $newfile->get_filesize() ||
$oldfile->get_referencefileid() != $newfile->get_referencefileid()) {
$oldfile->replace_file_with($newfile);
// push changes to all local files that are referencing this file
$fs->update_references_to_storedfile($oldfile);
}

View File

@ -210,6 +210,36 @@ class stored_file {
$this->set_filesize($storedfile->get_filesize());
}
/**
* Replaces the fields that might have changed when file was overriden in filepicker:
* reference, contenthash, filesize
*
* Note that field source must be updated separately
*
* @param stored_file $newfile
* @throws coding_exception
*/
public function replace_file_with(stored_file $newfile) {
if ($newfile->get_referencefileid() &&
$this->fs->get_references_count_by_storedfile($this)) {
// The new file is a reference.
// The current file has other local files referencing to it.
// Double reference is not allowed.
throw new moodle_exception('errordoublereference', 'repository');
}
$filerecord = new stdClass;
$contenthash = $newfile->get_contenthash();
if ($this->fs->content_exists($contenthash)) {
$filerecord->contenthash = $contenthash;
} else {
throw new file_exception('storedfileproblem', 'Invalid contenthash, content must be already in filepool', $contenthash);
}
$filerecord->filesize = $newfile->get_filesize();
$filerecord->referencefileid = $newfile->get_referencefileid();
$this->update($filerecord);
}
/**
* Unlink the stored file from the referenced file
*

View File

@ -2546,6 +2546,13 @@ abstract class repository implements cacheable_object {
$user_context = context_user::instance($USER->id);
if ($file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $filepath, $filename)) {
if ($tempfile = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $newfilepath, $newfilename)) {
if ($tempfile->is_external_file()) {
// New file is a reference. Check that existing file does not have any other files referencing to it
$source = @unserialize($file->get_source());
if (isset($source->original) && $fs->search_references_count($source->original)) {
return (object)array('error' => get_string('errordoublereference', 'repository'));
}
}
// delete existing file to release filename
$file->delete();
// create new file