/** * 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); }
/** * 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 */ function file_restore_source_field_from_draft_file($storedfile) { $source = @unserialize($storedfile->get_source()); if (!empty($source)) { if (is_object($source)) { $restoredsource = $source->source; $storedfile->set_source($restoredsource); } else { throw new moodle_exception('invalidsourcefield', 'error'); } } return $storedfile; }
/** * Gets a file relative to this file in the repository and sends it to the browser. * * @param stored_file $mainfile The main file we are trying to access relative files for. * @param string $relativepath the relative path to the file we are trying to access. */ public function send_relative_file(stored_file $mainfile, $relativepath) { global $CFG; // Check if this repository is allowed to use relative linking. $allowlinks = $this->supports_relative_file(); if (!empty($allowlinks)) { // Get path to the mainfile. $mainfilepath = $mainfile->get_source(); // Strip out filename from the path. $filename = $mainfile->get_filename(); $basepath = strstr($mainfilepath, $filename, true); $fullrelativefilepath = realpath($this->get_rootpath() . $basepath . $relativepath); // Sanity check to make sure this path is inside this repository and the file exists. if (strpos($fullrelativefilepath, realpath($this->get_rootpath())) === 0 && file_exists($fullrelativefilepath)) { send_file($fullrelativefilepath, basename($relativepath), null, 0); } } send_file_not_found(); }