/** * Is this filename valid (contains a unique participant ID) for import? * * @param assign $assignment - The assignment instance * @param stored_file $fileinfo - The fileinfo * @param array $participants - A list of valid participants for this module indexed by unique_id * @param stdClass $user - Set to the user that matches by participant id * @param assign_plugin $plugin - Set to the plugin that exported the file * @param string $filename - Set to truncated filename (prefix stripped) * @return true If the participant Id can be extracted and this is a valid user */ public function is_valid_filename_for_import($assignment, $fileinfo, $participants, &$user, &$plugin, &$filename) { if ($fileinfo->is_directory()) { return false; } // Ignore hidden files. if (strpos($fileinfo->get_filename(), '.') === 0) { return false; } // Ignore hidden files. if (strpos($fileinfo->get_filename(), '~') === 0) { return false; } $info = explode('_', $fileinfo->get_filepath() . $fileinfo->get_filename(), 5); if (count($info) < 5) { return false; } $participantid = $info[1]; $filename = $info[4]; $plugin = $assignment->get_plugin_by_type($info[2], $info[3]); if (!is_numeric($participantid)) { return false; } if (!$plugin) { return false; } // Convert to int. $participantid += 0; if (empty($participants[$participantid])) { return false; } $user = $participants[$participantid]; return true; }
/** * Get the URL of a file that belongs to a response variable of this * question_attempt. * @param stored_file $file the file to link to. * @return string the URL of that file. */ public function get_response_file_url(stored_file $file) { return file_encode_url(new moodle_url('/pluginfile.php'), '/' . implode('/', array($file->get_contextid(), $file->get_component(), $file->get_filearea(), $this->usageid, $this->slot, $file->get_itemid())) . $file->get_filepath() . $file->get_filename(), true); }
/** * Updates all files that are referencing this file with the new contenthash * and filesize * * @param stored_file $storedfile */ public function update_references_to_storedfile(stored_file $storedfile) { global $CFG, $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(); $reference = self::pack_reference($params); $referencehash = sha1($reference); $sql = "SELECT repositoryid, id FROM {files_reference}\n WHERE referencehash = ?"; $rs = $DB->get_recordset_sql($sql, array($referencehash)); $now = time(); foreach ($rs as $record) { $this->update_references($record->id, $now, null, $storedfile->get_contenthash(), $storedfile->get_filesize(), 0, $storedfile->get_timemodified()); } $rs->close(); }
/** * Make url based on file for theme_snap components only. * * @param stored_file $file * @return \moodle_url | bool */ private static function snap_pluginfile_url($file) { if (!$file) { return false; } else { return \moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_timemodified(), $file->get_filepath(), $file->get_filename()); } }
/** * Print resource info and workaround link when JS not available. * @param object $resource * @param object $cm * @param object $course * @param stored_file $file main file * @return does not return */ function resource_print_workaround($resource, $cm, $course, $file) { global $CFG, $OUTPUT; resource_print_header($resource, $cm, $course); resource_print_heading($resource, $cm, $course, true); resource_print_intro($resource, $cm, $course, true); $resource->mainfile = $file->get_filename(); echo '<div class="resourceworkaround">'; switch (resource_get_final_display_type($resource)) { case RESOURCELIB_DISPLAY_POPUP: $path = '/' . $file->get_contextid() . '/mod_resource/content/' . $resource->revision . $file->get_filepath() . $file->get_filename(); $fullurl = file_encode_url($CFG->wwwroot . '/pluginfile.php', $path, false); $options = empty($resource->displayoptions) ? array() : unserialize($resource->displayoptions); $width = empty($options['popupwidth']) ? 620 : $options['popupwidth']; $height = empty($options['popupheight']) ? 450 : $options['popupheight']; $wh = "width={$width},height={$height},toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes"; $extra = "onclick=\"window.open('{$fullurl}', '', '{$wh}'); return false;\""; echo resource_get_clicktoopen($file, $resource->revision, $extra); break; case RESOURCELIB_DISPLAY_NEW: $extra = 'onclick="this.target=\'_blank\'"'; echo resource_get_clicktoopen($file, $resource->revision, $extra); break; case RESOURCELIB_DISPLAY_DOWNLOAD: echo resource_get_clicktodownload($file, $resource->revision); break; case RESOURCELIB_DISPLAY_OPEN: default: echo resource_get_clicktoopen($file, $resource->revision); break; } echo '</div>'; echo $OUTPUT->footer(); die; }
/** * Resize the image, if required, then generate an img tag and, if required, a link to the full-size image * @param stored_file $file the image file to process * @param int $maxwidth the maximum width allowed for the image * @param int $maxheight the maximum height allowed for the image * @return string HTML fragment to add to the label */ function label_generate_resized_image(stored_file $file, $maxwidth, $maxheight) { global $CFG; $fullurl = moodle_url::make_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename()); $link = null; $attrib = array('alt' => $file->get_filename(), 'src' => $fullurl); if ($imginfo = $file->get_imageinfo()) { // Work out the new width / height, bounded by maxwidth / maxheight $width = $imginfo['width']; $height = $imginfo['height']; if (!empty($maxwidth) && $width > $maxwidth) { $height *= (double) $maxwidth / $width; $width = $maxwidth; } if (!empty($maxheight) && $height > $maxheight) { $width *= (double) $maxheight / $height; $height = $maxheight; } $attrib['width'] = $width; $attrib['height'] = $height; // If the size has changed and the image is of a suitable mime type, generate a smaller version if ($width != $imginfo['width']) { $mimetype = $file->get_mimetype(); if ($mimetype === 'image/gif' or $mimetype === 'image/jpeg' or $mimetype === 'image/png') { require_once $CFG->libdir . '/gdlib.php'; $tmproot = make_temp_directory('mod_label'); $tmpfilepath = $tmproot . '/' . $file->get_contenthash(); $file->copy_content_to($tmpfilepath); $data = generate_image_thumbnail($tmpfilepath, $width, $height); unlink($tmpfilepath); if (!empty($data)) { $fs = get_file_storage(); $record = array('contextid' => $file->get_contextid(), 'component' => $file->get_component(), 'filearea' => $file->get_filearea(), 'itemid' => $file->get_itemid(), 'filepath' => '/', 'filename' => 's_' . $file->get_filename()); $smallfile = $fs->create_file_from_string($record, $data); // Replace the image 'src' with the resized file and link to the original $attrib['src'] = moodle_url::make_draftfile_url($smallfile->get_itemid(), $smallfile->get_filepath(), $smallfile->get_filename()); $link = $fullurl; } } } } else { // Assume this is an image type that get_imageinfo cannot handle (e.g. SVG) $attrib['width'] = $maxwidth; } $img = html_writer::empty_tag('img', $attrib); if ($link) { return html_writer::link($link, $img); } else { return $img; } }
/** * Returns the number of aliases that link to the given stored_file * * Aliases in user draft areas are not counted. * * @param stored_file $storedfile * @return int */ public function get_references_count_by_storedfile(stored_file $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(); return $this->search_references_count(self::pack_reference($params)); }
/** * Perform archiving file from stored file * * @param zip_archive $ziparch zip archive instance * @param string $archivepath file path to archive * @param stored_file $file stored_file object */ private function archive_stored($ziparch, $archivepath, $file) { $file->archive_file($ziparch, $archivepath); if (!$file->is_directory()) { return; } $baselength = strlen($file->get_filepath()); $fs = get_file_storage(); $files = $fs->get_directory_files($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), true, true); foreach ($files as $file) { $path = $file->get_filepath(); $path = substr($path, $baselength); $path = $archivepath . '/' . $path; if (!$file->is_directory()) { $path = $path . $file->get_filename(); } $file->archive_file($ziparch, $path); } }
/** * 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; }
/** * Updates all files that are referencing this file with the new contenthash * and filesize * * @param stored_file $storedfile */ public function update_references_to_storedfile(stored_file $storedfile) { global $CFG, $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(); $reference = self::pack_reference($params); $referencehash = sha1($reference); $sql = "SELECT repositoryid, id FROM {files_reference}\n WHERE referencehash = ? and reference = ?"; $rs = $DB->get_recordset_sql($sql, array($referencehash, $reference)); $now = time(); foreach ($rs as $record) { require_once $CFG->dirroot . '/repository/lib.php'; $repo = repository::get_instance($record->repositoryid); $lifetime = $repo->get_reference_file_lifetime($reference); $this->update_references($record->id, $now, $lifetime, $storedfile->get_contenthash(), $storedfile->get_filesize(), 0); } $rs->close(); }
public static function create_from_archive(gallery $gallery, \stored_file $storedfile, $formdata = array()) { global $DB; $context = $gallery->get_collection()->context; $maxitems = $gallery->get_collection()->maxitems; $count = $DB->count_records('mediagallery_item', array('galleryid' => $gallery->id)); if ($maxitems != 0 && $count >= $maxitems) { return; } $fs = get_file_storage(); $packer = get_file_packer('application/zip'); $fs->delete_area_files($context->id, 'mod_mediagallery', 'unpacktemp', 0); $storedfile->extract_to_storage($packer, $context->id, 'mod_mediagallery', 'unpacktemp', 0, '/'); $itemfiles = $fs->get_area_files($context->id, 'mod_mediagallery', 'unpacktemp', 0); $storedfile->delete(); foreach ($itemfiles as $storedfile) { if ($storedfile->get_filesize() == 0 || preg_match('#^/.DS_Store|__MACOSX/#', $storedfile->get_filepath())) { continue; } if ($maxitems != 0 && $count >= $maxitems) { break; } $filename = $storedfile->get_filename(); // Create an item. $data = new \stdClass(); $data->caption = $filename; $data->description = ''; $data->display = 1; $metafields = array('moralrights' => 1, 'originalauthor' => '', 'productiondate' => 0, 'medium' => '', 'publisher' => '', 'broadcaster' => '', 'reference' => ''); foreach ($metafields as $field => $default) { $data->{$field} = isset($formdata->{$field}) ? $formdata->{$field} : $default; } $data->galleryid = $gallery->id; if (!$count) { $data->thumbnail = 1; $count = 0; } $item = self::create($data); // Copy the file into the correct area. $fileinfo = array('contextid' => $context->id, 'component' => 'mod_mediagallery', 'filearea' => 'item', 'itemid' => $item->id, 'filepath' => '/', 'filename' => $filename); if (!$fs->get_file($context->id, 'mod_mediagallery', 'item', $item->id, '/', $filename)) { $storedfile = $fs->create_file_from_storedfile($fileinfo, $storedfile); } $item->generate_image_by_type('lowres'); $item->generate_image_by_type('thumbnail'); $count++; } $fs->delete_area_files($context->id, 'mod_mediagallery', 'unpacktemp', 0); }
/** * Based on a stored_file objects, adds either that file (if it's a file) or * all its children (if it's a directory) into the list of files to * archive. * * If a progress indicator is supplied and if this corresponds to a * directory, then it will be repeatedly called with the same values. This * allows the progress handler to respond in some way to avoid timeouts * if required. * * @param array $expandedfiles List of all files to archive (output) * @param string $archivepath Current path within archive * @param stored_file $file File object */ protected function list_files_stored(array &$expandedfiles, $archivepath, stored_file $file) { if ($file->is_directory()) { // Add a directory-creation record. $expandedfiles[$archivepath . '/'] = null; // Loop through directory contents (this is a recursive collection // of all children not just one directory). $fs = get_file_storage(); $baselength = strlen($file->get_filepath()); $files = $fs->get_directory_files($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), true, true); foreach ($files as $childfile) { // Get full pathname after original part. $path = $childfile->get_filepath(); $path = substr($path, $baselength); $path = $archivepath . '/' . $path; if ($childfile->is_directory()) { $childfile = null; } else { $path .= $childfile->get_filename(); } $expandedfiles[$path] = $childfile; } } else { // Just add it to list. $expandedfiles[$archivepath] = $file; } }
/** * Utility function for getting a file URL * * @param stored_file $file * @return string file url */ private function util_get_file_url($file) { return moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename(), false); }
static function ensure_pdf_compatible(stored_file $file) { global $CFG; $fp = $file->get_content_file_handle(); $ident = fread($fp, 10); if (substr_compare('%PDF-', $ident, 0, 5) !== 0) { return false; // This is not a PDF file at all } $ident = substr($ident, 5); // Remove the '%PDF-' part $ident = explode('\\x0A', $ident); // Truncate to first '0a' character list($major, $minor) = explode('.', $ident[0]); // Split the major / minor version $major = intval($major); $minor = intval($minor); if ($major == 0 || $minor == 0) { return false; // Not a valid PDF version number } if ($major = 1 && $minor <= 4) { return true; // We can handle this version - nothing else to do } $temparea = $CFG->dataroot . '/temp/uploadpdf'; $hash = $file->get_contenthash(); $tempsrc = $temparea . "/src-{$hash}.pdf"; $tempdst = $temparea . "/dst-{$hash}.pdf"; if (!file_exists($temparea)) { if (!mkdir($temparea, 0777, true)) { die("Unable to create temporary folder {$temparea}"); } } $file->copy_content_to($tempsrc); // Copy the file $gsexec = $CFG->gs_path; $command = "{$gsexec} -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOutputFile=\"{$tempdst}\" \"{$tempsrc}\" 2>&1"; $result = exec($command); if (!file_exists($tempdst)) { return false; // Something has gone wrong in the conversion } $file->delete(); // Delete the original file $fs = get_file_storage(); $fileinfo = array('contextid' => $file->get_contextid(), 'component' => $file->get_component(), 'filearea' => $file->get_filearea(), 'itemid' => $file->get_itemid(), 'filename' => $file->get_filename(), 'filepath' => $file->get_filepath()); $fs->create_file_from_pathname($fileinfo, $tempdst); // Create replacement file @unlink($tempsrc); // Delete the temporary files @unlink($tempdst); return true; }
/** * Perform archiving file from stored file. * * @param zip_archive $ziparch zip archive instance * @param string $archivepath file path to archive * @param stored_file $file stored_file object * @param file_progress $progress Progress indicator callback or null if not required * @return bool success */ private function archive_stored($ziparch, $archivepath, $file, file_progress $progress = null) { $result = $file->archive_file($ziparch, $archivepath); if (!$result) { return false; } if (!$file->is_directory()) { return true; } $baselength = strlen($file->get_filepath()); $fs = get_file_storage(); $files = $fs->get_directory_files($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), true, true); foreach ($files as $file) { // Record progress for each file. if ($progress) { $progress->progress(); } $path = $file->get_filepath(); $path = substr($path, $baselength); $path = $archivepath . '/' . $path; if (!$file->is_directory()) { $path = $path . $file->get_filename(); } // Ignore result here, partial zipping is ok for now. $file->archive_file($ziparch, $path); } return true; }
/** * xmldb_hotpot_move_file * * move a file or folder (within the same context) * if $file is a directory, then all subfolders and files will also be moved * if the destination file/folder already exists, then $file will be deleted * * @param stored_file $file * @param string $new_filepath * @param string $new_filename (optional, default='') * @return void, but may update filearea */ function xmldb_hotpot_move_file($file, $new_filepath, $new_filename = '') { $fs = get_file_storage(); $contextid = $file->get_contextid(); $component = $file->get_component(); $filearea = $file->get_filearea(); $itemid = $file->get_itemid(); $old_filepath = $file->get_filepath(); $old_filename = $file->get_filename(); if ($file->is_directory()) { $children = $fs->get_directory_files($contextid, $component, $filearea, $itemid, $old_filepath); $old_filepath = '/^' . preg_quote($old_filepath, '/') . '/'; foreach ($children as $child) { xmldb_hotpot_move_file($child, preg_replace($old_filepath, $new_filepath, $child->get_filepath(), 1)); } } if ($new_filename == '') { $new_filename = $old_filename; } if ($fs->file_exists($contextid, $component, $filearea, $itemid, $new_filepath, $new_filename)) { $file->delete(); // new file already exists } else { $file->rename($new_filepath, $new_filename); } }
/** * Retreive the contents of a file. That file may either be in a conventional directory of the Moodle file storage * @param file_storage $filestorage. should be null if using a conventional directory * @param stored_file $fileobj the directory to look in. null if using a conventional directory * @param string $dir the directory to look in. null if using the Moodle file storage * @param string $filename the name of the file we want * @return string the contents of the file */ public function data_preset_get_file_contents(&$filestorage, &$fileobj, $dir, $filename) { if(empty($filestorage) || empty($fileobj)) { if (substr($dir, -1)!='/') { $dir .= '/'; } return file_get_contents($dir.$filename); } else { $file = $filestorage->get_file(DATA_PRESET_CONTEXT, DATA_PRESET_COMPONENT, DATA_PRESET_FILEAREA, 0, $fileobj->get_filepath(), $filename); return $file->get_content(); } }
/** * Get the image details from a file and return them. * @param stored_file $file * @param $pagecount * @return mixed array|false */ protected static function get_image_details($file, $pagecount) { if ($imageinfo = $file->get_imageinfo()) { $imgurl = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); // Prevent browser from caching image if it has changed. $imgurl->param('ts', $file->get_timemodified()); return array($imgurl, $imageinfo['width'], $imageinfo['height'], $pagecount); } // Something went wrong. return false; }