/** * 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); }
/** * Repository method to serve the referenced file * * @see send_stored_file * * @param stored_file $storedfile the file that contains the reference * @param int $lifetime Number of seconds before the file should expire from caches (null means $CFG->filelifetime) * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin * @param array $options additional options affecting the file serving */ public function send_file($storedfile, $lifetime = null, $filter = 0, $forcedownload = false, array $options = null) { global $USER; $caller = '\\repository_office365::send_file'; $reference = $this->unpack_reference($storedfile->get_reference()); $fileuserid = $storedfile->get_userid(); $sourceclient = $this->get_onedrive_apiclient(false, $fileuserid); if (empty($sourceclient)) { \local_o365\utils::debug('Could not construct api client for user', 'send_file', $fileuserid); send_file_not_found(); die; } $fileinfo = $sourceclient->get_file_metadata($reference['id']); // Do embedding if relevant. $doembed = $this->do_embedding($reference, $forcedownload); if ($doembed === true) { if (\local_o365\utils::is_o365_connected($USER->id) !== true) { // Embedding currently only supported for logged-in Office 365 users. echo get_string('erroro365required', 'repository_office365'); die; } if (!empty($sourceclient)) { if (isset($fileinfo['webUrl'])) { $fileurl = $fileinfo['webUrl']; } else { $fileurl = isset($reference['url']) ? $reference['url'] : ''; } if (empty($fileurl)) { $errstr = 'Embed was requested, but could not get file info to complete request.'; \local_o365\utils::debug($errstr, 'send_file', ['reference' => $reference, 'fileinfo' => $fileinfo]); } else { try { $embedurl = $sourceclient->get_embed_url($reference['id'], $fileurl); $embedurl = isset($embedurl['value']) ? $embedurl['value'] : ''; } catch (\Exception $e) { // Note: exceptions will already be logged in get_embed_url. $embedurl = ''; } if (!empty($embedurl)) { redirect($embedurl); } else { if (!empty($fileurl)) { redirect($fileurl); } else { $errstr = 'Embed was requested, but could not complete.'; \local_o365\utils::debug($errstr, 'send_file', $reference); } } } } else { \local_o365\utils::debug('Could not construct OneDrive client for system api user.', 'send_file'); } } redirect($fileinfo['webUrl']); }
/** * Return the count files referring to provided stored_file instance * This won't work for draft files * * @param stored_file $storedfile * @return int */ public function get_references_count_by_storedfile($storedfile) { global $DB; $params = array(); $params['contextid'] = $storedfile->get_contextid(); $params['component'] = $storedfile->get_component(); $params['filearea'] = $storedfile->get_filearea(); $params['itemid'] = $storedfile->get_itemid(); $params['filename'] = $storedfile->get_filename(); $params['filepath'] = $storedfile->get_filepath(); $params['userid'] = $storedfile->get_userid(); $reference = self::pack_reference($params); $sql = "SELECT COUNT(f.id)\n FROM {files} f\n LEFT JOIN {files_reference} r\n ON f.referencefileid = r.id\n WHERE " . $DB->sql_compare_text('r.reference') . ' = ' . $DB->sql_compare_text('?') . "\n AND (f.component <> ? OR f.filearea <> ?)"; $count = $DB->count_records_sql($sql, array($reference, 'user', 'draft')); return $count; }
function emarking_create_anonymous_page_from_storedfile(stored_file $file) { if (!$file) { throw new Exception('Stored file does not exist'); } // Get file storage and copy file to temp folder. $fs = get_file_storage(); $tmppath = $file->copy_content_to_temp('emarking', 'anonymous'); // Treat the file as an image, get its size and draw a white rectangle. $size = getimagesize($tmppath); $image = imagecreatefrompng($tmppath); $white = imagecolorallocate($image, 255, 255, 255); $y2 = round($size[1] / 10, 0); imagefilledrectangle($image, 0, 0, $size[0], $y2, $white); // Save the new image to replace the file. if (!imagepng($image, $tmppath)) { return false; } clearstatcache(); $filenameanonymous = emarking_get_anonymous_filename($file->get_filename()); // Copy file from temp folder to Moodle's filesystem. $filerecordanonymous = array('contextid' => $file->get_contextid(), 'component' => 'mod_emarking', 'filearea' => 'pages', 'itemid' => $file->get_itemid(), 'filepath' => '/', 'filename' => $filenameanonymous, 'timecreated' => $file->get_timecreated(), 'timemodified' => time(), 'userid' => $file->get_userid(), 'author' => $file->get_author(), 'license' => 'allrightsreserved'); $previousfile = $fs->get_file($file->get_contextid(), 'mod_emarking', 'pages', $file->get_itemid(), '/', $filenameanonymous); if ($previousfile) { $previousfile->delete(); } $fileinfo = $fs->create_file_from_pathname($filerecordanonymous, $tmppath); return $fileinfo; }