From 15ba94e132d9e166e932aa100efb0a29dd45916a Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 29 Jan 2016 12:12:48 +0800 Subject: [PATCH] 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. --- lib/db/upgrade.php | 17 +++++++++++++++++ repository/lib.php | 12 +++++------- repository/upgrade.txt | 6 ++++++ version.php | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 40b21c78743..befd583d866 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -4608,6 +4608,23 @@ function xmldb_main_upgrade($oldversion) { // Moodle v3.0.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2015111602.07) { + $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, 2015111602.07); + } return true; } diff --git a/repository/lib.php b/repository/lib.php index fdf9c3dd9b4..3892f09e7f0 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -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); } /** diff --git a/repository/upgrade.txt b/repository/upgrade.txt index e47ba3be344..c87421c6368 100644 --- a/repository/upgrade.txt +++ b/repository/upgrade.txt @@ -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.0.3 === + +* 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 diff --git a/version.php b/version.php index d19a95843a4..6a30775b9f1 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015111602.06; // 20151116 = branching date YYYYMMDD - do not modify! +$version = 2015111602.07; // 20151116 = branching date YYYYMMDD - do not modify! // RR = release increments - 00 in DEV branches. // .XX = incremental changes.