MDL-52217 repository: prepare_file should use per-request directory

The repository API defaults has a function, prepare_file, which is
responsible for creating a unique file to be used during the current
request.

This is usually used in the repository's get_file() function to store the
file before it is used elsewhere in the API to save the file to the
filestorage API.
It is also sometimes used to temporarily store credentials for the lifetime
of the session.

In all cases, this file is only expected to exist for the duration of the
session.

Switching to use of a per-request directory using make_request_directory()
ensures that the tempdir does not grow without control.

This commit also adds an upgrade step to remove all old temp directories
created by any repository currently installed.
This commit is contained in:
Andrew Nicols 2016-01-29 12:12:48 +08:00
parent 2f45a11ac4
commit a9e12347b7
4 changed files with 30 additions and 8 deletions

View File

@ -4916,5 +4916,23 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2016020201.00);
}
if ($oldversion < 2016021500.00) {
$root = $CFG->tempdir . '/download';
if (is_dir($root)) {
// Fetch each repository type - include all repos, not just enabled.
$repositories = $DB->get_records('repository', array(), '', 'type');
foreach ($repositories as $id => $repository) {
$directory = $root . '/repository_' . $repository->type;
if (is_dir($directory)) {
fulldelete($directory);
}
}
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2016021500.00);
}
return true;
}

View File

@ -1663,18 +1663,16 @@ abstract class repository implements cacheable_object {
}
/**
* Decide where to save the file, can be overwriten by subclass
* Get a unique file path in which to save the file.
*
* The filename returned will be removed at the end of the request and
* should not be relied upon to exist in subsequent requests.
*
* @param string $filename file name
* @return file path
*/
public function prepare_file($filename) {
global $CFG;
$dir = make_temp_directory('download/'.get_class($this).'/');
while (empty($filename) || file_exists($dir.$filename)) {
$filename = uniqid('', true).'_'.time().'.tmp';
}
return $dir.$filename;
return sprintf('%s/%s', make_request_directory(), $filename);
}
/**

View File

@ -3,6 +3,12 @@ information provided here is intended especially for developers. Full
details of the repository API are available on Moodle docs:
http://docs.moodle.org/dev/Repository_API
=== 3.1 ===
* The prepare_file() function will now return a file in a per-request directory which will
be automatically cleaned at the end of the request.
No modifications should be required as a result of this change.
=== 2.8 ===
* Repositories working with Moodle files must replace serialize() with json_encode() in the

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2016021100.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2016021500.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.