/** * Downloads the file from external repository and saves it in moodle filepool. * This function is different from {@link repository::sync_reference()} because it has * bigger request timeout and always downloads the content. * * This function is invoked when we try to unlink the file from the source and convert * a reference into a true copy. * * @throws exception when file could not be imported * * @param stored_file $file * @param int $maxbytes throw an exception if file size is bigger than $maxbytes (0 means no limit) */ public function import_external_file_contents(stored_file $file, $maxbytes = 0) { if (!$file->is_external_file()) { // nothing to import if the file is not a reference return; } else { if ($file->get_repository_id() != $this->id) { // error debugging('Repository instance id does not match'); return; } else { if ($this->has_moodle_files()) { // files that are references to local files are already in moodle filepool // just validate the size if ($maxbytes > 0 && $file->get_filesize() > $maxbytes) { throw new file_exception('maxbytes'); } return; } else { if ($maxbytes > 0 && $file->get_filesize() > $maxbytes) { // note that stored_file::get_filesize() also calls synchronisation throw new file_exception('maxbytes'); } $fs = get_file_storage(); $contentexists = $fs->content_exists($file->get_contenthash()); if ($contentexists && $file->get_filesize() && $file->get_contenthash() === sha1('')) { // even when 'file_storage::content_exists()' returns true this may be an empty // content for the file that was not actually downloaded $contentexists = false; } if (!$file->get_status() && $contentexists) { // we already have the content in moodle filepool and it was synchronised recently. // Repositories may overwrite it if they want to force synchronisation anyway! return; } else { // attempt to get a file try { $fileinfo = $this->get_file($file->get_reference()); if (isset($fileinfo['path'])) { list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($fileinfo['path']); // set this file and other similar aliases synchronised $file->set_synchronized($contenthash, $filesize); } else { throw new moodle_exception('errorwhiledownload', 'repository', '', ''); } } catch (Exception $e) { if ($contentexists) { // better something than nothing. We have a copy of file. It's sync time // has expired but it is still very likely that it is the last version } else { throw $e; } } } } } } }
/** * Overwrite an existing file in a draft area. * * @param stored_file $newfile the new file with the new content and meta-data * @param stored_file $existingfile the file that will be overwritten * @throws moodle_exception * @since Moodle 3.2 */ function file_overwrite_existing_draftfile(stored_file $newfile, stored_file $existingfile) { if ($existingfile->get_component() != 'user' or $existingfile->get_filearea() != 'draft') { throw new coding_exception('The file to overwrite is not in a draft area.'); } $fs = get_file_storage(); // Remember original file source field. $source = @unserialize($existingfile->get_source()); // Remember the original sortorder. $sortorder = $existingfile->get_sortorder(); if ($newfile->is_external_file()) { // New file is a reference. Check that existing file does not have any other files referencing to it if (isset($source->original) && $fs->search_references_count($source->original)) { throw new moodle_exception('errordoublereference', 'repository'); } } // Delete existing file to release filename. $newfilerecord = array('contextid' => $existingfile->get_contextid(), 'component' => 'user', 'filearea' => 'draft', 'itemid' => $existingfile->get_itemid(), 'timemodified' => time()); $existingfile->delete(); // Create new file. $newfile = $fs->create_file_from_storedfile($newfilerecord, $newfile); // Preserve original file location (stored in source field) for handling references. if (isset($source->original)) { if (!($newfilesource = @unserialize($newfile->get_source()))) { $newfilesource = new stdClass(); } $newfilesource->original = $source->original; $newfile->set_source(serialize($newfilesource)); } $newfile->set_sortorder($sortorder); }