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
 /**
  * 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.º 3
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);
    }
}
 /**
  * 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.º 5
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.º 6
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);
     }
 }