/** * Perform a file format conversion on the specified document. * * @param stored_file $file the file we want to preview * @param string $format The desired format - e.g. 'pdf'. Formats are specified by file extension. * @return stored_file|bool false if unable to create the conversion, stored file otherwise */ protected function create_converted_document(stored_file $file, $format) { global $CFG; if (empty($CFG->pathtounoconv) || !file_is_executable(trim($CFG->pathtounoconv))) { // No conversions are possible, sorry. return false; } $fileextension = core_text::strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION)); if (!self::is_format_supported_by_unoconv($fileextension)) { return false; } if (!self::is_format_supported_by_unoconv($format)) { return false; } // Copy the file to the local tmp dir. $tmp = make_request_directory(); $localfilename = $file->get_filename(); // Safety. $localfilename = clean_param($localfilename, PARAM_FILE); $filename = $tmp . '/' . $localfilename; $file->copy_content_to($filename); $newtmpfile = pathinfo($filename, PATHINFO_FILENAME) . '.' . $format; // Safety. $newtmpfile = $tmp . '/' . clean_param($newtmpfile, PARAM_FILE); $cmd = escapeshellcmd(trim($CFG->pathtounoconv)) . ' ' . escapeshellarg('-f') . ' ' . escapeshellarg($format) . ' ' . escapeshellarg('-o') . ' ' . escapeshellarg($newtmpfile) . ' ' . escapeshellarg($filename); $e = file_exists($filename); $output = null; $currentdir = getcwd(); chdir($tmp); $result = exec($cmd, $output); chdir($currentdir); if (!file_exists($newtmpfile)) { return false; } $context = context_system::instance(); $record = array('contextid' => $context->id, 'component' => 'core', 'filearea' => 'documentconversion', 'itemid' => 0, 'filepath' => '/' . $format . '/', 'filename' => $file->get_contenthash()); return $this->create_file_from_pathname($record, $newtmpfile); }
/** * Perform a file format conversion on the specified document. * * @param stored_file $file the file we want to preview * @param string $format The desired format - e.g. 'pdf'. Formats are specified by file extension. * @return stored_file|bool false if unable to create the conversion, stored file otherwise */ protected function create_converted_document(stored_file $file, $format) { global $CFG; if (empty($CFG->pathtounoconv) || !file_is_executable(trim($CFG->pathtounoconv))) { // No conversions are possible, sorry. return false; } $fileextension = core_text::strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION)); if (!self::is_format_supported_by_unoconv($fileextension)) { return false; } if (!self::is_format_supported_by_unoconv($format)) { return false; } // Copy the file to the tmp dir. $uniqdir = "core_file/conversions/" . uniqid($file->get_id() . "-", true); $tmp = make_temp_directory($uniqdir); $localfilename = $file->get_filename(); // Safety. $localfilename = clean_param($localfilename, PARAM_FILE); $filename = $tmp . '/' . $localfilename; try { // This function can either return false, or throw an exception so we need to handle both. if ($file->copy_content_to($filename) === false) { throw new file_exception('storedfileproblem', 'Could not copy file contents to temp file.'); } } catch (file_exception $fe) { remove_dir($uniqdir); throw $fe; } $newtmpfile = pathinfo($filename, PATHINFO_FILENAME) . '.' . $format; // Safety. $newtmpfile = $tmp . '/' . clean_param($newtmpfile, PARAM_FILE); $cmd = escapeshellcmd(trim($CFG->pathtounoconv)) . ' ' . escapeshellarg('-f') . ' ' . escapeshellarg($format) . ' ' . escapeshellarg('-o') . ' ' . escapeshellarg($newtmpfile) . ' ' . escapeshellarg($filename); $output = null; $currentdir = getcwd(); chdir($tmp); $result = exec($cmd, $output); chdir($currentdir); if (!file_exists($newtmpfile)) { remove_dir($uniqdir); // Cleanup. return false; } $context = context_system::instance(); $record = array('contextid' => $context->id, 'component' => 'core', 'filearea' => 'documentconversion', 'itemid' => 0, 'filepath' => '/' . $format . '/', 'filename' => $file->get_contenthash()); $convertedfile = $this->create_file_from_pathname($record, $newtmpfile); // Cleanup. remove_dir($uniqdir); return $convertedfile; }
/** * 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; } }
/** * Generates a preview for the stored image file * * @param stored_file $file the image we want to preview * @param string $mode preview mode, eg. 'thumb' * @return string|bool false if a problem occurs, the thumbnail image data otherwise */ protected function create_imagefile_preview(stored_file $file, $mode) { global $CFG; require_once $CFG->libdir . '/gdlib.php'; $tmproot = make_temp_directory('thumbnails'); $tmpfilepath = $tmproot . '/' . $file->get_contenthash(); $file->copy_content_to($tmpfilepath); if ($mode === 'tinyicon') { $data = generate_image_thumbnail($tmpfilepath, 24, 24); } else { if ($mode === 'thumb') { $data = generate_image_thumbnail($tmpfilepath, 90, 90); } else { throw new file_exception('storedfileproblem', 'Invalid preview mode requested'); } } unlink($tmpfilepath); return $data; }
/** * Check to see if PDF is version 1.4 (or below); if not: use ghostscript to convert it * @param stored_file $file * @return string path to copy or converted pdf (false == fail) */ public 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. } $temparea = \make_temp_directory('assignfeedback_editpdf'); $hash = $file->get_contenthash(); // Use the contenthash to make sure the temp files have unique names. $tempsrc = $temparea . "/src-{$hash}.pdf"; $tempdst = $temparea . "/dst-{$hash}.pdf"; if ($major = 1 && $minor <= 4) { // PDF is valid version - just create a copy we can use. $file->copy_content_to($tempdst); // Copy the file. return $tempdst; } $file->copy_content_to($tempsrc); // Copy the file. $gsexec = \get_config('assignfeedback_editpdf', 'gspath'); $command = "{$gsexec} -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOutputFile=\"{$tempdst}\" \"{$tempsrc}\""; //$command = escapeshellcmd($command); exec($command); @unlink($tempsrc); if (!file_exists($tempdst)) { // Something has gone wrong in the conversion. return false; } return $tempdst; }
/** * Check to see if PDF is version 1.4 (or below); if not: use ghostscript to convert it * @param stored_file $file * @return string path to copy or converted pdf (false == fail) */ public static function ensure_pdf_compatible(\stored_file $file) { global $CFG; $temparea = \make_temp_directory('assignfeedback_editpdf'); $hash = $file->get_contenthash(); // Use the contenthash to make sure the temp files have unique names. $tempsrc = $temparea . "/src-{$hash}.pdf"; $tempdst = $temparea . "/dst-{$hash}.pdf"; $file->copy_content_to($tempsrc); // Copy the file. $pdf = new pdf(); $pagecount = 0; try { $pagecount = $pdf->load_pdf($tempsrc); } catch (\Exception $e) { // PDF was not valid - try running it through ghostscript to clean it up. $pagecount = 0; } $pdf->Close(); // PDF loaded and never saved/outputted needs to be closed. if ($pagecount > 0) { // Page is valid and can be read by tcpdf. return $tempsrc; } $gsexec = \escapeshellarg($CFG->pathtogs); $tempdstarg = \escapeshellarg($tempdst); $tempsrcarg = \escapeshellarg($tempsrc); $command = "{$gsexec} -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOutputFile={$tempdstarg} {$tempsrcarg}"; exec($command); @unlink($tempsrc); if (!file_exists($tempdst)) { // Something has gone wrong in the conversion. return false; } $pdf = new pdf(); $pagecount = 0; try { $pagecount = $pdf->load_pdf($tempdst); } catch (\Exception $e) { // PDF was not valid - try running it through ghostscript to clean it up. $pagecount = 0; } $pdf->Close(); // PDF loaded and never saved/outputted needs to be closed. if ($pagecount <= 0) { @unlink($tempdst); // Could not parse the converted pdf. return false; } return $tempdst; }
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; }