Skip to content
Permalink
Browse files

Merge branch 'wip-MDL-39177-m24' of git://github.com/marinaglancy/moo…

…dle into MOODLE_24_STABLE
  • Loading branch information...
stronk7 committed May 22, 2013
2 parents ec01b32 + 0733e98 commit be06282e1b9303bd34f94be4b15ce9a6653e9ea8
@@ -97,6 +97,7 @@
$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.';
@@ -115,7 +116,7 @@
$string['filesizenull'] = 'File size cannot be determined';
$string['folderexists'] = 'Folder name already being used, please use another name';
$string['foldernotfound'] = 'Folder not found';
$string['folderrecurse'] = 'Folder can not be moved to it\s own subfolder';
$string['folderrecurse'] = 'Folder can not be moved to it\'s own subfolder';
$string['getfile'] = 'Select this file';
$string['hidden'] = 'Hidden';
$string['choosealink'] = 'Choose a link...';
@@ -713,6 +713,9 @@ function file_get_submitted_draft_itemid($elname) {
/**
* Restore the original source field from draft files
*
* Do not use this function because it makes field files.source inconsistent
* for draft area files. This function will be deprecated in 2.6
*
* @param stored_file $storedfile This only works with draft files
* @return stored_file
*/
@@ -783,58 +786,37 @@ function file_save_draft_area_files($draftitemid, $contextid, $component, $filea
$draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id');
$oldfiles = $fs->get_area_files($contextid, $component, $filearea, $itemid, 'id');
if (count($draftfiles) < 2) {
// means there are no files - one file means root dir only ;-)
$fs->delete_area_files($contextid, $component, $filearea, $itemid);
// One file in filearea means it is empty (it has only top-level directory '.').
if (count($draftfiles) > 1 || count($oldfiles) > 1) {
// we have to merge old and new files - we want to keep file ids for files that were not changed
// we change time modified for all new and changed files, we keep time created as is
} else if (count($oldfiles) < 2) {
$newhashes = array();
$filecount = 0;
// there were no files before - one file means root dir only ;-)
foreach ($draftfiles as $file) {
$file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid);
if (!$options['subdirs']) {
if ($file->get_filepath() !== '/' or $file->is_directory()) {
continue;
}
}
if ($options['maxbytes'] and $options['maxbytes'] < $file->get_filesize()) {
// oversized file - should not get here at all
if (!$options['subdirs'] && ($file->get_filepath() !== '/' or $file->is_directory())) {
continue;
}
if ($options['maxfiles'] != -1 and $options['maxfiles'] <= $filecount) {
// more files - should not get here at all
break;
if (!$allowreferences && $file->is_external_file()) {
continue;
}
if (!$file->is_directory()) {
$filecount++;
}
if ($file->is_external_file()) {
if (!$allowreferences) {
if ($options['maxbytes'] and $options['maxbytes'] < $file->get_filesize()) {
// oversized file - should not get here at all
continue;
}
$repoid = $file->get_repository_id();
if (!empty($repoid)) {
$file_record['repositoryid'] = $repoid;
$file_record['reference'] = $file->get_reference();
if ($options['maxfiles'] != -1 and $options['maxfiles'] <= $filecount) {
// more files - should not get here at all
continue;
}
$filecount++;
}
file_restore_source_field_from_draft_file($file);
$fs->create_file_from_storedfile($file_record, $file);
}
} else {
// we have to merge old and new files - we want to keep file ids for files that were not changed
// we change time modified for all new and changed files, we keep time created as is
$newhashes = array();
foreach ($draftfiles as $file) {
$newhash = $fs->get_pathname_hash($contextid, $component, $filearea, $itemid, $file->get_filepath(), $file->get_filename());
file_restore_source_field_from_draft_file($file);
$newhashes[$newhash] = $file;
}
$filecount = 0;
// Loop through oldfiles and decide which we need to delete and which to update.
// After this cycle the array $newhashes will only contain the files that need to be added.
foreach ($oldfiles as $oldfile) {
$oldhash = $oldfile->get_pathnamehash();
if (!isset($newhashes[$oldhash])) {
@@ -844,6 +826,25 @@ function file_save_draft_area_files($draftitemid, $contextid, $component, $filea
}
$newfile = $newhashes[$oldhash];
// Now we know that we have $oldfile and $newfile for the same path.
// Let's check if we can update this file or we need to delete and create.
if ($newfile->is_directory()) {
// Directories are always ok to just update.
} else if (($source = @unserialize($newfile->get_source())) && isset($source->original)) {
// File has the 'original' - we need to update the file (it may even have not been changed at all).
$original = file_storage::unpack_reference($source->original);
if ($original['filename'] !== $oldfile->get_filename() || $original['filepath'] !== $oldfile->get_filepath()) {
// Very odd, original points to another file. Delete and create file.
$oldfile->delete();
continue;
}
} else {
// The same file name but absence of 'original' means that file was deteled and uploaded again.
// By deleting and creating new file we properly manage all existing references.
$oldfile->delete();
continue;
}
// status changed, we delete old file, and create a new one
if ($oldfile->get_status() != $newfile->get_status()) {
// file was changed, use updated with new timemodified data
@@ -862,8 +863,14 @@ function file_save_draft_area_files($draftitemid, $contextid, $component, $filea
}
// Updated file source
if ($oldfile->get_source() != $newfile->get_source()) {
$oldfile->set_source($newfile->get_source());
// Field files.source for draftarea files contains serialised object with source and original information.
// We only store the source part of it for non-draft file area.
$newsource = $newfile->get_source();
if ($source = @unserialize($newfile->get_source())) {
$newsource = $source->source;
}
if ($oldfile->get_source() !== $newsource) {
$oldfile->set_source($newsource);
}
// Updated sort order
@@ -877,44 +884,31 @@ function file_save_draft_area_files($draftitemid, $contextid, $component, $filea
}
// Replaced file content
if ($oldfile->get_contenthash() != $newfile->get_contenthash() || $oldfile->get_filesize() != $newfile->get_filesize()) {
$oldfile->replace_content_with($newfile);
if (!$oldfile->is_directory() &&
($oldfile->get_contenthash() != $newfile->get_contenthash() ||
$oldfile->get_filesize() != $newfile->get_filesize() ||
$oldfile->get_referencefileid() != $newfile->get_referencefileid() ||
$oldfile->get_userid() != $newfile->get_userid())) {
$oldfile->replace_file_with($newfile);
// push changes to all local files that are referencing this file
$fs->update_references_to_storedfile($oldfile);
}
// unchanged file or directory - we keep it as is
unset($newhashes[$oldhash]);
if (!$oldfile->is_directory()) {
$filecount++;
}
}
// Add fresh file or the file which has changed status
// the size and subdirectory tests are extra safety only, the UI should prevent it
foreach ($newhashes as $file) {
$file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'timemodified'=>time());
if (!$options['subdirs']) {
if ($file->get_filepath() !== '/' or $file->is_directory()) {
continue;
}
}
if ($options['maxbytes'] and $options['maxbytes'] < $file->get_filesize()) {
// oversized file - should not get here at all
continue;
}
if ($options['maxfiles'] != -1 and $options['maxfiles'] <= $filecount) {
// more files - should not get here at all
break;
}
if (!$file->is_directory()) {
$filecount++;
if ($source = @unserialize($file->get_source())) {
// Field files.source for draftarea files contains serialised object with source and original information.
// We only store the source part of it for non-draft file area.
$file_record['source'] = $source->source;
}
if ($file->is_external_file()) {
if (!$allowreferences) {
continue;
}
$repoid = $file->get_repository_id();
if (!empty($repoid)) {
$file_record['repositoryid'] = $repoid;
@@ -210,6 +210,40 @@ public function replace_content_with(stored_file $storedfile) {
$this->set_filesize($storedfile->get_filesize());
}
/**
* Replaces the fields that might have changed when file was overriden in filepicker:
* reference, contenthash, filesize, userid
*
* Note that field 'source' must be updated separately because
* it has different format for draft and non-draft areas and
* this function will usually be used to replace non-draft area
* file with draft area file.
*
* @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();
$filerecord->userid = $newfile->get_userid();
$this->update($filerecord);
}
/**
* Unlink the stored file from the referenced file
*

0 comments on commit be06282

Please sign in to comment.
You can’t perform that action at this time.