Skip to content

Commit

Permalink
MDL-58334 repositories: Offline downloads
Browse files Browse the repository at this point in the history
Support an optional param for offline downloads for repositories supporting external links (googledrive and skydrive).

Part of MDL-58220
  • Loading branch information
Damyon Wiese committed Apr 3, 2017
1 parent fa78244 commit d5bb9f1
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 39 deletions.
70 changes: 37 additions & 33 deletions lib/filelib.php
Original file line number Diff line number Diff line change
Expand Up @@ -3856,9 +3856,11 @@ public function refresh() {
* @param string $relativepath
* @param bool $forcedownload
* @param null|string $preview the preview mode, defaults to serving the original file
* @param boolean $offline If offline is requested - don't serve a redirect to an external file, return a file suitable for viewing
* offline (e.g. mobile app).
* @todo MDL-31088 file serving improments
*/
function file_pluginfile($relativepath, $forcedownload, $preview = null) {
function file_pluginfile($relativepath, $forcedownload, $preview = null, $offline = false) {
global $DB, $CFG, $USER;
// relative path must start with '/'
if (!$relativepath) {
Expand All @@ -3882,6 +3884,8 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {

$fs = get_file_storage();

$sendfileoptions = ['preview' => $preview, 'offline' => $offline];

// ========================================================================================================================
if ($component === 'blog') {
// Blog file serving
Expand Down Expand Up @@ -3934,7 +3938,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
send_file_not_found();
}

send_stored_file($file, 10*60, 0, true, array('preview' => $preview)); // download MUST be forced - security!
send_stored_file($file, 10*60, 0, true, $sendfileoptions); // download MUST be forced - security!

// ========================================================================================================================
} else if ($component === 'grade') {
Expand All @@ -3951,7 +3955,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'feedback' and $context->contextlevel == CONTEXT_COURSE) {
//TODO: nobody implemented this yet in grade edit form!!
Expand All @@ -3968,7 +3972,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);
} else {
send_file_not_found();
}
Expand All @@ -3989,7 +3993,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, true, array('preview' => $preview));
send_stored_file($file, 60*60, 0, true, $sendfileoptions);

} else {
send_file_not_found();
Expand All @@ -4011,14 +4015,14 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close();
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);
} else if ($filearea === 'userbadge' and $context->contextlevel == CONTEXT_USER) {
if (!$file = $fs->get_file($context->id, 'badges', 'userbadge', $badge->id, '/', $filename.'.png')) {
send_file_not_found();
}

\core\session\manager::write_close();
send_stored_file($file, 60*60, 0, true, array('preview' => $preview));
send_stored_file($file, 60*60, 0, true, $sendfileoptions);
}
// ========================================================================================================================
} else if ($component === 'calendar') {
Expand All @@ -4045,7 +4049,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_USER) {

Expand Down Expand Up @@ -4073,7 +4077,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, true, array('preview' => $preview));
send_stored_file($file, 0, 0, true, $sendfileoptions);

} else if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_COURSE) {

Expand Down Expand Up @@ -4120,7 +4124,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else {
send_file_not_found();
Expand Down Expand Up @@ -4174,7 +4178,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
send_file($imagefile, basename($imagefile), 60*60*24*14);
}

$options = array('preview' => $preview);
$options = $sendfileoptions;
if (empty($CFG->forcelogin) && empty($CFG->forceloginforprofileimage)) {
// Profile images should be cache-able by both browsers and proxies according
// to $CFG->forcelogin and $CFG->forceloginforprofileimage.
Expand All @@ -4200,7 +4204,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security!
send_stored_file($file, 0, 0, true, $sendfileoptions); // must force download - security!

} else if ($filearea === 'profile' and $context->contextlevel == CONTEXT_USER) {

Expand Down Expand Up @@ -4247,7 +4251,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security!
send_stored_file($file, 0, 0, true, $sendfileoptions); // must force download - security!

} else if ($filearea === 'profile' and $context->contextlevel == CONTEXT_COURSE) {
$userid = (int)array_shift($args);
Expand Down Expand Up @@ -4285,7 +4289,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security!
send_stored_file($file, 0, 0, true, $sendfileoptions); // must force download - security!

} else if ($filearea === 'backup' and $context->contextlevel == CONTEXT_USER) {
require_login();
Expand All @@ -4306,7 +4310,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security!
send_stored_file($file, 0, 0, true, $sendfileoptions); // must force download - security!

} else {
send_file_not_found();
Expand Down Expand Up @@ -4339,7 +4343,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);
} else {
send_file_not_found();
}
Expand All @@ -4362,7 +4366,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'section') {
if ($CFG->forcelogin) {
Expand All @@ -4384,7 +4388,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else {
send_file_not_found();
Expand Down Expand Up @@ -4413,7 +4417,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
if (($file = $fs->get_file($cohortcontext->id, 'cohort', 'description', $cohort->id, $filepath, $filename))
&& !$file->is_directory()) {
\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60 * 60, 0, $forcedownload, $sendfileoptions);
}
}

Expand Down Expand Up @@ -4445,7 +4449,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'icon') {
$filename = array_pop($args);
Expand All @@ -4460,7 +4464,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, false, array('preview' => $preview));
send_stored_file($file, 60*60, 0, false, $sendfileoptions);

} else {
send_file_not_found();
Expand All @@ -4485,7 +4489,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else {
send_file_not_found();
Expand All @@ -4504,7 +4508,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 0, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'section' and $context->contextlevel == CONTEXT_COURSE) {
require_login($course);
Expand All @@ -4519,7 +4523,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close();
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'activity' and $context->contextlevel == CONTEXT_MODULE) {
require_login($course, false, $cm);
Expand All @@ -4532,7 +4536,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close();
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);

} else if ($filearea === 'automated' and $context->contextlevel == CONTEXT_COURSE) {
// Backup files that were generated by the automated backup systems.
Expand All @@ -4547,7 +4551,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 0, 0, $forcedownload, $sendfileoptions);

} else {
send_file_not_found();
Expand All @@ -4556,7 +4560,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
// ========================================================================================================================
} else if ($component === 'question') {
require_once($CFG->libdir . '/questionlib.php');
question_pluginfile($course, $context, 'question', $filearea, $args, $forcedownload);
question_pluginfile($course, $context, 'question', $filearea, $args, $forcedownload, $sendfileoptions);
send_file_not_found();

// ========================================================================================================================
Expand Down Expand Up @@ -4593,7 +4597,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

\core\session\manager::write_close(); // Unlock session during file serving.
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);
}

// ========================================================================================================================
Expand Down Expand Up @@ -4625,17 +4629,17 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
}

// finally send the file
send_stored_file($file, null, 0, false, array('preview' => $preview));
send_stored_file($file, null, 0, false, $sendfileoptions);
}

$filefunction = $component.'_pluginfile';
$filefunctionold = $modname.'_pluginfile';
if (function_exists($filefunction)) {
// if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
$filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
$filefunction($course, $cm, $context, $filearea, $args, $forcedownload, $sendfileoptions);
} else if (function_exists($filefunctionold)) {
// if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
$filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
$filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload, $sendfileoptions);
}

send_file_not_found();
Expand Down Expand Up @@ -4676,7 +4680,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
$filefunction = $component.'_pluginfile';
if (function_exists($filefunction)) {
// if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
$filefunction($course, $birecord, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
$filefunction($course, $birecord, $context, $filearea, $args, $forcedownload, $sendfileoptions);
}

send_file_not_found();
Expand All @@ -4697,7 +4701,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
$filefunction = $component.'_pluginfile';
if (function_exists($filefunction)) {
// if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
$filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
$filefunction($course, $cm, $context, $filearea, $args, $forcedownload, $sendfileoptions);
}

send_file_not_found();
Expand Down
5 changes: 4 additions & 1 deletion pluginfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@
$relativepath = get_file_argument();
$forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
$preview = optional_param('preview', null, PARAM_ALPHANUM);
// Offline means download the file from the repository and serve it, even if it was an external link.
// The repository may have to export the file to an offline format.
$offline = optional_param('offline', 0, PARAM_BOOL);

file_pluginfile($relativepath, $forcedownload, $preview);
file_pluginfile($relativepath, $forcedownload, $preview, $offline);
12 changes: 10 additions & 2 deletions repository/googledocs/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownloa
$storedfile->get_filepath(),
$storedfile->get_filename());

if ($info->is_writable()) {
if (empty($options['offline']) && $info->is_writable()) {
// Add the current user as an OAuth writer.
$systemauth = \core\oauth2\api::get_system_oauth_client($this->issuer);

Expand Down Expand Up @@ -613,7 +613,15 @@ public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownloa
$this->add_temp_writer_to_file($systemservice, $source->id, $useremail);
}

if ($source->link) {
if (!empty($options['offline'])) {
$downloaded = $this->get_file($storedfile->get_reference(), $storedfile->get_filename());

$filename = $storedfile->get_filename();
if (isset($downloaded['newfilename'])) {
$filename = $downloaded['newfilename'];
}
send_file($downloaded['path'], $filename, $lifetime, $filter, false, $forcedownload, '', false, $options);
} else if ($source->link) {
redirect($source->link);
} else {
$details = 'File is missing source link';
Expand Down
9 changes: 6 additions & 3 deletions repository/skydrive/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownloa
$storedfile->get_filepath(),
$storedfile->get_filename());

if ($info->is_writable()) {
if (empty($options['offline']) && $info->is_writable()) {
// Add the current user as an OAuth writer.
$systemauth = \core\oauth2\api::get_system_oauth_client($this->issuer);

Expand Down Expand Up @@ -563,7 +563,11 @@ public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownloa
$this->add_temp_writer_to_file($systemservice, $source->id, $useremail);
}

if ($source->link) {
if (!empty($options['offline'])) {
$downloaded = $this->get_file($storedfile->get_reference(), $storedfile->get_filename());
$filename = $storedfile->get_filename();
send_file($downloaded['path'], $filename, $lifetime, $filter, false, $forcedownload, '', false, $options);
} else if ($source->link) {
redirect($source->link);
} else {
$details = 'File is missing source link';
Expand Down Expand Up @@ -820,7 +824,6 @@ public function reference_file_selected($reference, $context, $component, $filea
// then set the permissions so anyone with the share link can view,
// finally update the reference to contain the share link if it was not
// already there (and point to new file id if we copied).
var_dump($reference);
$systemauth = \core\oauth2\api::get_system_oauth_client($this->issuer);

if ($systemauth === false) {
Expand Down

0 comments on commit d5bb9f1

Please sign in to comment.