Ejemplo n.º 1
0
 /**
  * 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());
     }
 }
Ejemplo n.º 2
0
 /**
  * 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();
 }
Ejemplo n.º 3
0
/**
 * 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);
}
Ejemplo n.º 4
0
/**
 * 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;
    }
}
Ejemplo n.º 5
0
/**
 * 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);
    }
}
Ejemplo n.º 6
0
 /**
  * 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));
 }
Ejemplo n.º 7
0
 /**
  * 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();
 }
Ejemplo n.º 8
0
 /**
  * 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);
     }
 }
Ejemplo n.º 9
0
 /**
  * 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);
 }
 /**
  * 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;
     }
 }
Ejemplo n.º 11
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;
 }
Ejemplo n.º 12
0
 /**
  * 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;
 }
Ejemplo n.º 13
0
 /**
  * Get location for given mdl_file.id entry
  * @param $fileid
  */
 protected function getLocation(\stored_file $file)
 {
     global $CFG, $DB;
     // To handle atm:course:legacy, mod_folder:content, mod_resource:content
     if ($file->get_component() == 'course' && $file->get_filearea() == 'legacy') {
         return "Legacy course files: " . $CFG->wwwroot . "/files/index.php?contextid=" . $file->get_contextid();
     }
     if ($file->get_component() == 'mod_folder' && $file->get_filearea() == 'content') {
         $context = $DB->get_record('context', array('id' => $file->get_contextid()));
         return "Folder resource: " . $CFG->wwwroot . "/mod/folder/view.php?id=" . $context->instanceid;
     }
     if ($file->get_component() == 'mod_resource' && $file->get_filearea() == 'content') {
         $context = $DB->get_record('context', array('id' => $file->get_contextid()));
         return "Resource: " . $CFG->wwwroot . "/mod/resource/view.php?id=" . $context->instanceid;
     }
 }
Ejemplo n.º 14
0
 /**
  * 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);
 }
Ejemplo n.º 15
0
 /**
  * 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;
 }
Ejemplo n.º 16
0
 /**
  * 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;
 }
Ejemplo n.º 17
0
 /**
  * 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;
 }