/** * 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); }
/** * 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); } }
/** * Delete all area files (optionally limited by itemid) * @param int $contextid * @param string $filearea (all areas in context if not specified) * @param int $itemid (all files if not specified) * @return success */ public function delete_area_files($contextid, $filearea = false, $itemid = false) { global $DB; $conditions = array('contextid' => $contextid); if ($filearea !== false) { $conditions['filearea'] = $filearea; } if ($itemid !== false) { $conditions['itemid'] = $itemid; } $success = true; $file_records = $DB->get_records('files', $conditions); foreach ($file_records as $file_record) { $stored_file = new stored_file($this, $file_record); $success = $stored_file->delete() && $success; } return $success; }
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); }
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; }
/** * Shame that this was nicked from gdlib.php and that there isn't a function I could have used from there. * Creates a resized version of image and stores copy in file area * * @param context $context * @param string $component * @param string filearea * @param int $itemid * @param stored_file $originalfile * @param int $newwidth; * @param int $newheight; * @return stored_file */ public static function resize(\stored_file $originalfile, $resizefilename = false, $newwidth = false, $newheight = false, $jpgquality = 90) { if ($resizefilename === false) { $resizefilename = $originalfile->get_filename(); } if (!$newwidth && !$newheight) { return false; } $contextid = $originalfile->get_contextid(); $component = $originalfile->get_component(); $filearea = $originalfile->get_filearea(); $itemid = $originalfile->get_itemid(); $imageinfo = (object) $originalfile->get_imageinfo(); $imagefnc = ''; if (empty($imageinfo)) { return false; } // Create temporary image for processing. $tmpimage = tempnam(sys_get_temp_dir(), 'tmpimg'); \file_put_contents($tmpimage, $originalfile->get_content()); if (!$newheight) { $m = $imageinfo->height / $imageinfo->width; // Multiplier to work out $newheight. $newheight = $newwidth * $m; } else { if (!$newwidth) { $m = $imageinfo->width / $imageinfo->height; // Multiplier to work out $newwidth. $newwidth = $newheight * $m; } } $t = null; switch ($imageinfo->mimetype) { case 'image/gif': if (\function_exists('imagecreatefromgif')) { $im = \imagecreatefromgif($tmpimage); } else { \debugging('GIF not supported on this server'); unlink($tmpimage); return false; } // Guess transparent colour from GIF. $transparent = \imagecolortransparent($im); if ($transparent != -1) { $t = \imagecolorsforindex($im, $transparent); } break; case 'image/jpeg': if (\function_exists('imagecreatefromjpeg')) { $im = \imagecreatefromjpeg($tmpimage); } else { \debugging('JPEG not supported on this server'); unlink($tmpimage); return false; } // If the user uploads a jpeg them we should process as a jpeg if possible. if (\function_exists('imagejpeg')) { $imagefnc = 'imagejpeg'; $filters = null; // Not used. $quality = $jpgquality; } else { if (\function_exists('imagepng')) { $imagefnc = 'imagepng'; $filters = PNG_NO_FILTER; $quality = 1; } else { \debugging('Jpeg and png not supported on this server, please fix server configuration'); unlink($tmpimage); return false; } } break; case 'image/png': if (\function_exists('imagecreatefrompng')) { $im = \imagecreatefrompng($tmpimage); } else { \debugging('PNG not supported on this server'); unlink($tmpimage); return false; } break; default: unlink($tmpimage); return false; } unlink($tmpimage); // The default for all images other than jpegs is to try imagepng first. if (empty($imagefnc)) { if (\function_exists('imagepng')) { $imagefnc = 'imagepng'; $filters = PNG_NO_FILTER; $quality = 1; } else { if (\function_exists('imagejpeg')) { $imagefnc = 'imagejpeg'; $filters = null; // Not used. $quality = $jpgquality; } else { \debugging('Jpeg and png not supported on this server, please fix server configuration'); return false; } } } if (\function_exists('imagecreatetruecolor')) { $newimage = \imagecreatetruecolor($newwidth, $newheight); if ($imageinfo->mimetype != 'image/jpeg' and $imagefnc === 'imagepng') { if ($t) { // Transparent GIF hacking... $transparentcolour = \imagecolorallocate($newimage, $t['red'], $t['green'], $t['blue']); \imagecolortransparent($newimage, $transparentcolour); } \imagealphablending($newimage, false); $color = \imagecolorallocatealpha($newimage, 0, 0, 0, 127); \imagefill($newimage, 0, 0, $color); \imagesavealpha($newimage, true); } } else { $newimage = \imagecreate($newwidth, $newheight); } \imagecopybicubic($newimage, $im, 0, 0, 0, 0, $newwidth, $newheight, $imageinfo->width, $imageinfo->height); $fs = \get_file_storage(); $newimageparams = array('contextid' => $contextid, 'component' => $component, 'filearea' => $filearea, 'itemid' => $itemid, 'filepath' => '/'); \ob_start(); if (!$imagefnc($newimage, null, $quality, $filters)) { return false; } $data = \ob_get_clean(); \imagedestroy($newimage); $newimageparams['filename'] = $resizefilename; if ($resizefilename == $originalfile->get_filename()) { $originalfile->delete(); } $file1 = $fs->create_file_from_string($newimageparams, $data); return $file1; }