Ejemplo n.º 1
0
 /**
  * Is this filename valid (contains a unique participant ID) for import?
  *
  * @param sepl $seplment - The seplment 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 sepl_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($seplment, $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_filename(), 5);
     if (count($info) < 5) {
         return false;
     }
     $participantid = $info[1];
     $filename = $info[4];
     $plugin = $seplment->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;
 }
Ejemplo n.º 2
0
 /**
  * Check if the given file is capable of being imported by this plugin.
  * As {@link file_storage::mimetype()} now uses finfo PHP extension if available,
  * the value returned by $file->get_mimetype for a .dat file is not the same on all servers.
  * So we must made 2 checks to verify if the plugin can import the file.
  * @param stored_file $file the file to check
  * @return bool whether this plugin can import the file
  */
 public function can_import_file($file) {
     $mimetypes = array(
         mimeinfo('type', '.dat'),
         mimeinfo('type', '.zip')
     );
     return in_array($file->get_mimetype(), $mimetypes) || in_array(mimeinfo('type', $file->get_filename()), $mimetypes);
 }
 /**
  * Given a stored file, get its file name, but make
  * sure that it does not conflict with any other
  * attachments in the file pool.
  *
  * @param \stored_file $file
  * @return string
  */
 protected function resolve_file_name(\stored_file $file)
 {
     $filename = $file->get_filename();
     $pathinfo = pathinfo($filename);
     $count = 1;
     while (array_key_exists('attachments/' . $filename, $this->archivefiles)) {
         $filename = $pathinfo['filename'] . '_' . $count . '.' . $pathinfo['extension'];
         $count++;
     }
     return $filename;
 }
Ejemplo n.º 4
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.º 5
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.º 6
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.º 7
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.º 8
0
 /**
  * Export the data for the given file in relation to this document.
  *
  * @param \stored_file $file The stored file we are talking about.
  * @return array
  */
 public function export_file_for_engine($file)
 {
     $data = $this->export_for_engine();
     // Content is index in the main document.
     unset($data['content']);
     unset($data['description1']);
     unset($data['description2']);
     // Going to append the fileid to give it a unique id.
     $data['id'] = $data['id'] . '-solrfile' . $file->get_id();
     $data['type'] = \core_search\manager::TYPE_FILE;
     $data['solr_fileid'] = $file->get_id();
     $data['solr_filecontenthash'] = $file->get_contenthash();
     $data['solr_fileindexstatus'] = self::INDEXED_FILE_TRUE;
     $data['title'] = $file->get_filename();
     $data['modified'] = self::format_time_for_engine($file->get_timemodified());
     return $data;
 }
Ejemplo n.º 9
0
 /**
  * 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 (default 24 hours)
  * @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=86400 , $filter=0, $forcedownload=false, array $options = null) {
     $reference = $storedfile->get_reference();
     if ($reference{0} == '/') {
         $file = $this->root_path.substr($reference, 1, strlen($reference)-1);
     } else {
         $file = $this->root_path.$reference;
     }
     if (is_readable($file)) {
         $filename = $storedfile->get_filename();
         if ($options && isset($options['filename'])) {
             $filename = $options['filename'];
         }
         $dontdie = ($options && isset($options['dontdie']));
         send_file($file, $filename, $lifetime , $filter, false, $forcedownload, '', $dontdie);
     } else {
         send_file_not_found();
     }
 }
Ejemplo n.º 10
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);
 }
Ejemplo n.º 11
0
 /**
  * Repository method to serve the referenced file
  *
  * This method is ivoked from {@link send_stored_file()}.
  * Dropbox repository first caches the file by reading it into temporary folder and then
  * serves from there.
  *
  * @param stored_file $storedfile the file that contains the reference
  * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
  * @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=86400 , $filter=0, $forcedownload=false, array $options = null) {
     $fileinfo = $this->get_file_by_reference((object)array('reference' => $storedfile->get_reference()));
     if ($fileinfo && !empty($fileinfo->filepath) && is_readable($fileinfo->filepath)) {
         $filename = $storedfile->get_filename();
         if ($options && isset($options['filename'])) {
             $filename = $options['filename'];
         }
         $dontdie = ($options && isset($options['dontdie']));
         send_file($fileinfo->filepath, $filename, $lifetime , $filter, false, $forcedownload, '', $dontdie);
     } else {
         send_file_not_found();
     }
 }
Ejemplo n.º 12
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.º 13
0
 /**
  * Downloads the file from external repository and saves it in moodle filepool.
  * This function is different from {@link repository::sync_reference()} because it has
  * bigger request timeout and always downloads the content.
  *
  * This function is invoked when we try to unlink the file from the source and convert
  * a reference into a true copy.
  *
  * @throws exception when file could not be imported
  *
  * @param stored_file $file
  * @param int $maxbytes throw an exception if file size is bigger than $maxbytes (0 means no limit)
  */
 public function import_external_file_contents(stored_file $file, $maxbytes = 0)
 {
     if (!$file->is_external_file()) {
         // nothing to import if the file is not a reference
         return;
     } else {
         if ($file->get_repository_id() != $this->id) {
             // error
             debugging('Repository instance id does not match');
             return;
         } else {
             if ($this->has_moodle_files()) {
                 // files that are references to local files are already in moodle filepool
                 // just validate the size
                 if ($maxbytes > 0 && $file->get_filesize() > $maxbytes) {
                     $maxbytesdisplay = display_size($maxbytes);
                     throw new file_exception('maxbytesfile', (object) array('file' => $file->get_filename(), 'size' => $maxbytesdisplay));
                 }
                 return;
             } else {
                 if ($maxbytes > 0 && $file->get_filesize() > $maxbytes) {
                     // note that stored_file::get_filesize() also calls synchronisation
                     $maxbytesdisplay = display_size($maxbytes);
                     throw new file_exception('maxbytesfile', (object) array('file' => $file->get_filename(), 'size' => $maxbytesdisplay));
                 }
                 $fs = get_file_storage();
                 $contentexists = $fs->content_exists($file->get_contenthash());
                 if ($contentexists && $file->get_filesize() && $file->get_contenthash() === sha1('')) {
                     // even when 'file_storage::content_exists()' returns true this may be an empty
                     // content for the file that was not actually downloaded
                     $contentexists = false;
                 }
                 if (!$file->get_status() && $contentexists) {
                     // we already have the content in moodle filepool and it was synchronised recently.
                     // Repositories may overwrite it if they want to force synchronisation anyway!
                     return;
                 } else {
                     // attempt to get a file
                     try {
                         $fileinfo = $this->get_file($file->get_reference());
                         if (isset($fileinfo['path'])) {
                             list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($fileinfo['path']);
                             // set this file and other similar aliases synchronised
                             $file->set_synchronized($contenthash, $filesize);
                         } else {
                             throw new moodle_exception('errorwhiledownload', 'repository', '', '');
                         }
                     } catch (Exception $e) {
                         if ($contentexists) {
                             // better something than nothing. We have a copy of file. It's sync time
                             // has expired but it is still very likely that it is the last version
                         } else {
                             throw $e;
                         }
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 14
0
 /**
  * Repository method to serve file
  *
  * @param stored_file $storedfile
  * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
  * @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 = 86400, $filter = 0, $forcedownload = false, array $options = null)
 {
     $reference = unserialize($storedfile->get_reference());
     $cachedfilepath = cache_file::get($reference, array('ttl' => $this->cachedfilettl));
     if ($cachedfilepath === false) {
         // Cache the file.
         $this->set_access_key($reference->access_key);
         $this->set_access_secret($reference->access_secret);
         $path = $this->get_file($reference->path);
         $cachedfilepath = cache_file::create_from_file($reference, $path['path']);
     }
     send_file($cachedfilepath, $storedfile->get_filename(), 'default', $filter, false, $forcedownload);
 }
Ejemplo n.º 15
0
/**
 * Handles the sending of file data to the user's browser, including support for
 * byteranges etc.
 *
 * @category files
 * @global stdClass $CFG
 * @global stdClass $COURSE
 * @global moodle_session $SESSION
 * @param stored_file $stored_file local file object
 * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
 * @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 string $filename Override filename
 * @param bool $dontdie - return control to caller afterwards. this is not recommended and only used for cleanup tasks.
 *                        if this is passed as true, ignore_user_abort is called.  if you don't want your processing to continue on cancel,
 *                        you must detect this case when control is returned using connection_aborted. Please not that session is closed
 *                        and should not be reopened.
 * @return null script execution stopped unless $dontdie is true
 */
function send_stored_file($stored_file, $lifetime = 86400, $filter = 0, $forcedownload = false, $filename = null, $dontdie = false)
{
    global $CFG, $COURSE, $SESSION;
    if (!$stored_file or $stored_file->is_directory()) {
        // nothing to serve
        if ($dontdie) {
            return;
        }
        die;
    }
    if ($dontdie) {
        ignore_user_abort(true);
    }
    session_get_instance()->write_close();
    // unlock session during fileserving
    // Use given MIME type if specified, otherwise guess it using mimeinfo.
    // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
    // only Firefox saves all files locally before opening when content-disposition: attachment stated
    $filename = is_null($filename) ? $stored_file->get_filename() : $filename;
    $isFF = check_browser_version('Firefox', '1.5');
    // only FF > 1.5 properly tested
    $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' : ($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename));
    $lastmodified = $stored_file->get_timemodified();
    $filesize = $stored_file->get_filesize();
    if ($lifetime > 0 && !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
        // get unixtime of request header; clip extra junk off first
        $since = strtotime(preg_replace('/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"]));
        if ($since && $since >= $lastmodified) {
            header('HTTP/1.1 304 Not Modified');
            header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT');
            header('Cache-Control: max-age=' . $lifetime);
            header('Content-Type: ' . $mimetype);
            if ($dontdie) {
                return;
            }
            die;
        }
    }
    //do not put '@' before the next header to detect incorrect moodle configurations,
    //error should be better than "weird" empty lines for admins/users
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT');
    // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
    if (check_browser_version('MSIE')) {
        $filename = rawurlencode($filename);
    }
    if ($forcedownload) {
        header('Content-Disposition: attachment; filename="' . $filename . '"');
    } else {
        header('Content-Disposition: inline; filename="' . $filename . '"');
    }
    if ($lifetime > 0) {
        header('Cache-Control: max-age=' . $lifetime);
        header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT');
        header('Pragma: ');
        if (empty($CFG->disablebyteserving) && $mimetype != 'text/plain' && $mimetype != 'text/html') {
            header('Accept-Ranges: bytes');
            if (!empty($_SERVER['HTTP_RANGE']) && strpos($_SERVER['HTTP_RANGE'], 'bytes=') !== FALSE) {
                // byteserving stuff - for acrobat reader and download accelerators
                // see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
                // inspired by: http://www.coneural.org/florian/papers/04_byteserving.php
                $ranges = false;
                if (preg_match_all('/(\\d*)-(\\d*)/', $_SERVER['HTTP_RANGE'], $ranges, PREG_SET_ORDER)) {
                    foreach ($ranges as $key => $value) {
                        if ($ranges[$key][1] == '') {
                            //suffix case
                            $ranges[$key][1] = $filesize - $ranges[$key][2];
                            $ranges[$key][2] = $filesize - 1;
                        } else {
                            if ($ranges[$key][2] == '' || $ranges[$key][2] > $filesize - 1) {
                                //fix range length
                                $ranges[$key][2] = $filesize - 1;
                            }
                        }
                        if ($ranges[$key][2] != '' && $ranges[$key][2] < $ranges[$key][1]) {
                            //invalid byte-range ==> ignore header
                            $ranges = false;
                            break;
                        }
                        //prepare multipart header
                        $ranges[$key][0] = "\r\n--" . BYTESERVING_BOUNDARY . "\r\nContent-Type: {$mimetype}\r\n";
                        $ranges[$key][0] .= "Content-Range: bytes {$ranges[$key][1]}-{$ranges[$key][2]}/{$filesize}\r\n\r\n";
                    }
                } else {
                    $ranges = false;
                }
                if ($ranges) {
                    byteserving_send_file($stored_file->get_content_file_handle(), $mimetype, $ranges, $filesize);
                }
            }
        } else {
            /// Do not byteserve (disabled, strings, text and html files).
            header('Accept-Ranges: none');
        }
    } else {
        // Do not cache files in proxies and browsers
        if (strpos($CFG->wwwroot, 'https://') === 0) {
            //https sites - watch out for IE! KB812935 and KB316431
            header('Cache-Control: max-age=10');
            header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT');
            header('Pragma: ');
        } else {
            //normal http - prevent caching at all cost
            header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0');
            header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT');
            header('Pragma: no-cache');
        }
        header('Accept-Ranges: none');
        // Do not allow byteserving when caching disabled
    }
    if (empty($filter)) {
        if ($mimetype == 'text/plain') {
            header('Content-Type: Text/plain; charset=utf-8');
            //add encoding
        } else {
            header('Content-Type: ' . $mimetype);
        }
        header('Content-Length: ' . $filesize);
        //flush the buffers - save memory and disable sid rewrite
        //this also disables zlib compression
        prepare_file_content_sending();
        // send the contents
        $stored_file->readfile();
    } else {
        // Try to put the file through filters
        if ($mimetype == 'text/html') {
            $options = new stdClass();
            $options->noclean = true;
            $options->nocache = true;
            // temporary workaround for MDL-5136
            $text = $stored_file->get_content();
            $text = file_modify_html_header($text);
            $output = format_text($text, FORMAT_HTML, $options, $COURSE->id);
            header('Content-Length: ' . strlen($output));
            header('Content-Type: text/html');
            //flush the buffers - save memory and disable sid rewrite
            //this also disables zlib compression
            prepare_file_content_sending();
            // send the contents
            echo $output;
        } else {
            if ($mimetype == 'text/plain' and $filter == 1) {
                // only filter text if filter all files is selected
                $options = new stdClass();
                $options->newlines = false;
                $options->noclean = true;
                $text = $stored_file->get_content();
                $output = '<pre>' . format_text($text, FORMAT_MOODLE, $options, $COURSE->id) . '</pre>';
                header('Content-Length: ' . strlen($output));
                header('Content-Type: text/html; charset=utf-8');
                //add encoding
                //flush the buffers - save memory and disable sid rewrite
                //this also disables zlib compression
                prepare_file_content_sending();
                // send the contents
                echo $output;
            } else {
                // Just send it out raw
                header('Content-Length: ' . $filesize);
                header('Content-Type: ' . $mimetype);
                //flush the buffers - save memory and disable sid rewrite
                //this also disables zlib compression
                prepare_file_content_sending();
                // send the contents
                $stored_file->readfile();
            }
        }
    }
    if ($dontdie) {
        return;
    }
    die;
    //no more chars to output!!!
}
Ejemplo n.º 16
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.º 17
0
 /**
  * Synchronize the references.
  *
  * @param stored_file $file Stored file.
  * @return boolean
  */
 public function sync_reference(stored_file $file)
 {
     if ($file->get_referencelastsync() + DAYSECS > time()) {
         // Synchronise not more often than once a day.
         return false;
     }
     $c = new curl();
     $reference = unserialize(self::convert_to_valid_reference($file->get_reference()));
     $url = $reference->downloadurl;
     if (file_extension_in_typegroup($file->get_filename(), 'web_image')) {
         $path = $this->prepare_file('');
         $result = $c->download_one($url, null, array('filepath' => $path, 'timeout' => $CFG->repositorysyncimagetimeout));
         $info = $c->get_info();
         if ($result === true && isset($info['http_code']) && $info['http_code'] == 200) {
             $fs = get_file_storage();
             list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($path);
             $file->set_synchronized($contenthash, $filesize);
             return true;
         }
     }
     $c->get($url, null, array('timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true, 'nobody' => true));
     $info = $c->get_info();
     if (isset($info['http_code']) && $info['http_code'] == 200 && array_key_exists('download_content_length', $info) && $info['download_content_length'] >= 0) {
         $filesize = (int) $info['download_content_length'];
         $file->set_synchronized(null, $filesize);
         return true;
     }
     $file->set_missingsource();
     return true;
 }
Ejemplo n.º 18
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.º 19
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.º 20
0
 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);
 }
Ejemplo n.º 21
0
 /**
  * Copies a file from somewhere else in moodle
  * to the portfolio temporary working directory
  * associated with this export
  *
  * @param stored_file $oldfile existing stored file object
  * @return stored_file|bool new file object
  */
 public function copy_existing_file($oldfile)
 {
     if (array_key_exists($oldfile->get_contenthash(), $this->newfilehashes)) {
         return $this->newfilehashes[$oldfile->get_contenthash()];
     }
     $fs = get_file_storage();
     $file_record = $this->new_file_record_base($oldfile->get_filename());
     if ($dir = $this->get('format')->get_file_directory()) {
         $file_record->filepath = '/' . $dir . '/';
     }
     try {
         $newfile = $fs->create_file_from_storedfile($file_record, $oldfile->get_id());
         $this->newfilehashes[$newfile->get_contenthash()] = $newfile;
         return $newfile;
     } catch (file_exception $e) {
         return false;
     }
 }
Ejemplo n.º 22
0
function emarking_create_anonymous_page_from_storedfile(stored_file $file, $student)
{
    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, $info);
    $imagemime = exif_imagetype($tmppath);
    if ($imagemime == IMAGETYPE_PNG) {
        $image = imagecreatefrompng($tmppath);
    } elseif ($imagemime == IMAGETYPE_JPEG) {
        $image = imagecreatefromjpeg($tmppath);
    } else {
        throw new Exception('Unsupported file type for pages');
    }
    if (!$image) {
        throw new Exception('Could not read image from ' . $info[0] . ' ' . $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 ($imagemime == IMAGETYPE_PNG) {
        if (!imagepng($image, $tmppath)) {
            throw new Exception('Could not save image as PNG to ' . $tmppath);
        }
    } elseif ($imagemime == IMAGETYPE_JPEG) {
        if (!imagejpeg($image, $tmppath, 100)) {
            throw new Exception('Could not save image as JPEG to ' . $tmppath);
        }
    } else {
        throw new Exception('Unsupported file type for saving page');
    }
    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' => $student->id, 'author' => $student->firstname . ' ' . $student->lastname, '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);
    if (!$fileinfo) {
        throw new Exception('Could not create anonymous version of a stored file');
    }
    return $fileinfo;
}
Ejemplo n.º 23
0
/**
 * 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;
}
Ejemplo n.º 24
0
 /**
  * Return the link to a file
  *
  * @param stored_file $file information for existing file
  * @param array $options array of options to pass. can contain:
  *              attributes => hash of existing html attributes (eg title, height, width, etc)
  * @return string
  */
 public static function file_output($file, $options = null)
 {
     $id = '';
     if (!is_array($options)) {
         $options = array();
     }
     if (!array_key_exists('entry', $options)) {
         $options['entry'] = true;
     }
     if (!empty($options['entry'])) {
         $path = 'portfolio:' . self::file_id_prefix() . $file->get_id();
     } else {
         $path = self::get_file_directory() . $file->get_filename();
     }
     $attributes = array();
     if (!empty($options['attributes']) && is_array($options['attributes'])) {
         $attributes = $options['attributes'];
     }
     $attributes['rel'] = 'enclosure';
     return self::make_tag($file, $path, $attributes);
 }
Ejemplo n.º 25
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.º 26
0
 /**
  *  Gets a file relative to this file in the repository and sends it to the browser.
  *
  * @param stored_file $mainfile The main file we are trying to access relative files for.
  * @param string $relativepath the relative path to the file we are trying to access.
  */
 public function send_relative_file(stored_file $mainfile, $relativepath)
 {
     global $CFG;
     // Check if this repository is allowed to use relative linking.
     $allowlinks = $this->supports_relative_file();
     if (!empty($allowlinks)) {
         // Get path to the mainfile.
         $mainfilepath = $mainfile->get_source();
         // Strip out filename from the path.
         $filename = $mainfile->get_filename();
         $basepath = strstr($mainfilepath, $filename, true);
         $fullrelativefilepath = realpath($this->get_rootpath() . $basepath . $relativepath);
         // Sanity check to make sure this path is inside this repository and the file exists.
         if (strpos($fullrelativefilepath, realpath($this->get_rootpath())) === 0 && file_exists($fullrelativefilepath)) {
             send_file($fullrelativefilepath, basename($relativepath), null, 0);
         }
     }
     send_file_not_found();
 }
Ejemplo n.º 27
0
 /**
  * Gets the file data
  *
  * @param stored_file $file
  * @param int $entryid Attachment entry id
  */
 public function __construct($file, $entryid)
 {
     global $CFG;
     $this->file = $file;
     $this->filename = $file->get_filename();
     $this->url = file_encode_url($CFG->wwwroot . '/pluginfile.php', '/' . SYSCONTEXTID . '/blog/attachment/' . $entryid . '/' . $this->filename);
 }
Ejemplo n.º 28
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.º 29
0
 /**
  * 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)
 {
     if ($this->has_moodle_files()) {
         $fs = get_file_storage();
         $params = file_storage::unpack_reference($storedfile->get_reference(), true);
         $srcfile = null;
         if (is_array($params)) {
             $srcfile = $fs->get_file($params['contextid'], $params['component'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']);
         }
         if (empty($options)) {
             $options = array();
         }
         if (!isset($options['filename'])) {
             $options['filename'] = $storedfile->get_filename();
         }
         if (!$srcfile) {
             send_file_not_found();
         } else {
             send_stored_file($srcfile, $lifetime, $filter, $forcedownload, $options);
         }
     } else {
         throw new coding_exception("Repository plugin must implement send_file() method.");
     }
 }
Ejemplo n.º 30
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;
 }