diff --git a/admin/cli/install.php b/admin/cli/install.php index 1ff43fefafe..1e5837f4963 100644 --- a/admin/cli/install.php +++ b/admin/cli/install.php @@ -442,6 +442,7 @@ if ($interactive) { } } $CFG->tempdir = $CFG->dataroot.'/temp'; +$CFG->backuptempdir = $CFG->tempdir.'/backup'; $CFG->cachedir = $CFG->dataroot.'/cache'; $CFG->localcachedir = $CFG->dataroot.'/localcache'; diff --git a/admin/tool/recyclebin/classes/category_bin.php b/admin/tool/recyclebin/classes/category_bin.php index 2acb3b2c679..26d8b537a68 100644 --- a/admin/tool/recyclebin/classes/category_bin.php +++ b/admin/tool/recyclebin/classes/category_bin.php @@ -207,9 +207,9 @@ class category_bin extends base_bin { // Get the backup file. $file = reset($files); - // Get a temp directory name and create it. + // Get a backup temp directory name and create it. $tempdir = \restore_controller::get_tempdir_name($context->id, $user->id); - $fulltempdir = make_temp_directory('/backup/' . $tempdir); + $fulltempdir = make_backup_temp_directory($tempdir); // Extract the backup to tmpdir. $fb = get_file_packer('application/vnd.moodle.backup'); diff --git a/admin/tool/recyclebin/classes/course_bin.php b/admin/tool/recyclebin/classes/course_bin.php index 67e1a21eccd..e935d691b72 100644 --- a/admin/tool/recyclebin/classes/course_bin.php +++ b/admin/tool/recyclebin/classes/course_bin.php @@ -211,9 +211,9 @@ class course_bin extends base_bin { // Get the backup file. $file = reset($files); - // Get a temp directory name and create it. + // Get a backup temp directory name and create it. $tempdir = \restore_controller::get_tempdir_name($context->id, $user->id); - $fulltempdir = make_temp_directory('/backup/' . $tempdir); + $fulltempdir = make_backup_temp_directory($tempdir); // Extract the backup to tempdir. $fb = get_file_packer('application/vnd.moodle.backup'); diff --git a/admin/tool/uploadcourse/classes/course.php b/admin/tool/uploadcourse/classes/course.php index ed3adea4a6a..c23c25ffbae 100644 --- a/admin/tool/uploadcourse/classes/course.php +++ b/admin/tool/uploadcourse/classes/course.php @@ -347,7 +347,7 @@ class tool_uploadcourse_course { /** * Get the directory of the object to restore. * - * @return string|false|null subdirectory in $CFG->tempdir/backup/..., false when an error occured + * @return string|false|null subdirectory in $CFG->backuptempdir/..., false when an error occured * and null when there is simply nothing. */ protected function get_restore_content_dir() { diff --git a/admin/tool/uploadcourse/classes/helper.php b/admin/tool/uploadcourse/classes/helper.php index 2873f3b783f..370d13a8220 100644 --- a/admin/tool/uploadcourse/classes/helper.php +++ b/admin/tool/uploadcourse/classes/helper.php @@ -227,7 +227,7 @@ class tool_uploadcourse_helper { } // If we don't use the cache, or if we do and not set, or the directory doesn't exist any more. - if (!$usecache || (($backupid = $cache->get($cachekey)) === false || !is_dir("$CFG->tempdir/backup/$backupid"))) { + if (!$usecache || (($backupid = $cache->get($cachekey)) === false || !is_dir(get_backup_temp_directory($backupid)))) { // Use null instead of false because it would consider that the cache key has not been set. $backupid = null; @@ -236,7 +236,7 @@ class tool_uploadcourse_helper { // Extracting the backup file. $packer = get_file_packer('application/vnd.moodle.backup'); $backupid = restore_controller::get_tempdir_name(SITEID, $USER->id); - $path = "$CFG->tempdir/backup/$backupid/"; + $path = make_backup_temp_directory($backupid, false); $result = $packer->extract_to_pathname($backupfile, $path); if (!$result) { $errors['invalidbackupfile'] = new lang_string('invalidbackupfile', 'tool_uploadcourse'); diff --git a/admin/tool/uploadcourse/classes/processor.php b/admin/tool/uploadcourse/classes/processor.php index 8963f7eee5e..8f55eef78b2 100644 --- a/admin/tool/uploadcourse/classes/processor.php +++ b/admin/tool/uploadcourse/classes/processor.php @@ -259,7 +259,7 @@ class tool_uploadcourse_processor { /** * Get the directory of the object to restore. * - * @return string subdirectory in $CFG->tempdir/backup/... + * @return string subdirectory in $CFG->backuptempdir/... */ protected function get_restore_content_dir() { $backupfile = null; diff --git a/backup/controller/restore_controller.class.php b/backup/controller/restore_controller.class.php index 86cb17f45ce..2e994f44def 100644 --- a/backup/controller/restore_controller.class.php +++ b/backup/controller/restore_controller.class.php @@ -32,7 +32,7 @@ */ class restore_controller extends base_controller { - protected $tempdir; // Directory under tempdir/backup awaiting restore + protected $tempdir; // Directory under $CFG->backuptempdir awaiting restore protected $restoreid; // Unique identificator for this restore protected $courseid; // courseid where restore is going to happen @@ -68,7 +68,7 @@ class restore_controller extends base_controller { * while loading the plan, as well as for future use. (You can change it * for a different one later using set_progress.) * - * @param string $tempdir Directory under tempdir/backup awaiting restore + * @param string $tempdir Directory under $CFG->backuptempdir awaiting restore * @param int $courseid Course id where restore is going to happen * @param bool $interactive backup::INTERACTIVE_YES[true] or backup::INTERACTIVE_NO[false] * @param int $mode backup::MODE_[ GENERAL | HUB | IMPORT | SAMESITE ] diff --git a/backup/controller/tests/controller_test.php b/backup/controller/tests/controller_test.php index c34ff288cac..0488185998b 100644 --- a/backup/controller/tests/controller_test.php +++ b/backup/controller/tests/controller_test.php @@ -110,7 +110,7 @@ class core_backup_controller_testcase extends advanced_testcase { global $CFG; // Make a backup. - check_dir_exists($CFG->tempdir . '/backup'); + make_backup_temp_directory(''); $bc = new backup_controller(backup::TYPE_1ACTIVITY, $this->moduleid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $this->userid); $backupid = $bc->get_backupid(); @@ -159,7 +159,7 @@ class core_backup_controller_testcase extends advanced_testcase { $foldername = 'deadlock'; $fp = get_file_packer('application/vnd.moodle.backup'); - $tempdir = $CFG->dataroot . '/temp/backup/' . $foldername; + $tempdir = make_backup_temp_directory($foldername); $files = $fp->extract_to_pathname($CFG->dirroot . '/backup/controller/tests/fixtures/deadlock.mbz', $tempdir); $this->setAdminUser(); diff --git a/backup/converter/convertlib.php b/backup/converter/convertlib.php index ef37f5ea3ca..1fdcf1dcd7c 100644 --- a/backup/converter/convertlib.php +++ b/backup/converter/convertlib.php @@ -148,7 +148,7 @@ abstract class base_converter implements loggable { public function get_workdir_path() { global $CFG; - return "$CFG->tempdir/backup/$this->workdir"; + return make_backup_temp_directory($this->workdir); } /** @@ -157,7 +157,7 @@ abstract class base_converter implements loggable { public function get_tempdir_path() { global $CFG; - return "$CFG->tempdir/backup/$this->tempdir"; + return make_backup_temp_directory($this->tempdir); } /// public static methods ////////////////////////////////////////////////// diff --git a/backup/converter/imscc11/backuplib.php b/backup/converter/imscc11/backuplib.php index 2d749bda4f8..e3f07d85d75 100644 --- a/backup/converter/imscc11/backuplib.php +++ b/backup/converter/imscc11/backuplib.php @@ -139,7 +139,7 @@ class imscc11_backup_convert extends backup_execution_step { require_once($CFG->dirroot . '/backup/cc/cc_includes.php'); - $tempdir = $CFG->tempdir . '/backup/' . uniqid('', true); + $tempdir = $CFG->backuptempdir . '/' . uniqid('', true); if (mkdir($tempdir, $CFG->directorypermissions, true)) { diff --git a/backup/converter/moodle1/lib.php b/backup/converter/moodle1/lib.php index 6e8382a392c..8722184d410 100644 --- a/backup/converter/moodle1/lib.php +++ b/backup/converter/moodle1/lib.php @@ -89,7 +89,8 @@ class moodle1_converter extends base_converter { public static function detect_format($tempdir) { global $CFG; - $filepath = $CFG->tempdir . '/backup/' . $tempdir . '/moodle.xml'; + $tempdirpath = make_backup_temp_directory($tempdir, false); + $filepath = $tempdirpath . '/moodle.xml'; if (file_exists($filepath)) { // looks promising, lets load some information $handle = fopen($filepath, 'r'); diff --git a/backup/converter/moodle1/tests/moodle1_converter_test.php b/backup/converter/moodle1/tests/moodle1_converter_test.php index 6502ef3c953..68589da2692 100644 --- a/backup/converter/moodle1/tests/moodle1_converter_test.php +++ b/backup/converter/moodle1/tests/moodle1_converter_test.php @@ -35,6 +35,9 @@ class core_backup_moodle1_converter_testcase extends advanced_testcase { /** @var string the name of the directory containing the unpacked Moodle 1.9 backup */ protected $tempdir; + /** @var string the full name of the directory containing the unpacked Moodle 1.9 backup */ + protected $tempdirpath; + /** @var string saved hash of an icon file used during testing */ protected $iconhash; @@ -42,39 +45,40 @@ class core_backup_moodle1_converter_testcase extends advanced_testcase { global $CFG; $this->tempdir = convert_helper::generate_id('unittest'); - check_dir_exists("$CFG->tempdir/backup/$this->tempdir/course_files/sub1"); - check_dir_exists("$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/7"); + $this->tempdirpath = make_backup_temp_directory($this->tempdir); + check_dir_exists("$this->tempdirpath/course_files/sub1"); + check_dir_exists("$this->tempdirpath/moddata/unittest/4/7"); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/moodle.xml", - "$CFG->tempdir/backup/$this->tempdir/moodle.xml" + "$this->tempdirpath/moodle.xml" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", - "$CFG->tempdir/backup/$this->tempdir/course_files/file1.gif" + "$this->tempdirpath/course_files/file1.gif" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", - "$CFG->tempdir/backup/$this->tempdir/course_files/sub1/file2.gif" + "$this->tempdirpath/course_files/sub1/file2.gif" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", - "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/file1.gif" + "$this->tempdirpath/moddata/unittest/4/file1.gif" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", - "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/icon.gif" + "$this->tempdirpath/moddata/unittest/4/icon.gif" ); - $this->iconhash = file_storage::hash_from_path($CFG->tempdir.'/backup/'.$this->tempdir.'/moddata/unittest/4/icon.gif'); + $this->iconhash = file_storage::hash_from_path($this->tempdirpath.'/moddata/unittest/4/icon.gif'); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", - "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/7/icon.gif" + "$this->tempdirpath/moddata/unittest/4/7/icon.gif" ); } protected function tearDown() { global $CFG; if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete("$CFG->tempdir/backup/$this->tempdir"); + fulldelete($this->tempdirpath); } } @@ -563,7 +567,7 @@ as it is parsed from the backup file.

dirroot/backup/converter/moodle1/tests/fixtures/questions.xml", - "$CFG->tempdir/backup/$this->tempdir/moodle.xml" + "$this->tempdirpath/moodle.xml" ); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->convert(); diff --git a/backup/import.php b/backup/import.php index 57be4943d7a..4cc57345f1e 100644 --- a/backup/import.php +++ b/backup/import.php @@ -140,7 +140,7 @@ if ($backup->get_stage() == backup_ui::STAGE_FINAL) { // Check whether the backup directory still exists. If missing, something // went really wrong in backup, throw error. Note that backup::MODE_IMPORT // backups don't store resulting files ever - $tempdestination = $CFG->tempdir . '/backup/' . $backupid; + $tempdestination = make_backup_temp_directory($backupid, false); if (!file_exists($tempdestination) || !is_dir($tempdestination)) { print_error('unknownbackupexporterror'); // shouldn't happen ever } diff --git a/backup/moodle2/tests/moodle2_test.php b/backup/moodle2/tests/moodle2_test.php index 971a35db8f1..c4f9e2c7f24 100644 --- a/backup/moodle2/tests/moodle2_test.php +++ b/backup/moodle2/tests/moodle2_test.php @@ -127,8 +127,7 @@ class core_backup_moodle2_testcase extends advanced_testcase { // Extract backup file. $backupid = 'abc'; - $backuppath = $CFG->tempdir . '/backup/' . $backupid; - check_dir_exists($backuppath); + $backuppath = make_backup_temp_directory($backupid); get_file_packer('application/vnd.moodle.backup')->extract_to_pathname( __DIR__ . '/fixtures/availability_26_format.mbz', $backuppath); @@ -972,8 +971,7 @@ class core_backup_moodle2_testcase extends advanced_testcase { foreach ($backupfiles as $backupfile) { // Extract backup file. $backupid = $backupfile; - $backuppath = $CFG->tempdir . '/backup/' . $backupid; - check_dir_exists($backuppath); + $backuppath = make_backup_temp_directory($backupid); get_file_packer('application/vnd.moodle.backup')->extract_to_pathname( __DIR__ . "/fixtures/$backupfile.mbz", $backuppath); diff --git a/backup/restorefile.php b/backup/restorefile.php index be9ae4a8fb7..2a745a829e1 100644 --- a/backup/restorefile.php +++ b/backup/restorefile.php @@ -72,7 +72,7 @@ if (is_null($course)) { $browser = get_file_browser(); // check if tmp dir exists -$tmpdir = $CFG->tempdir . '/backup'; +$tmpdir = make_backup_temp_directory('', false); if (!check_dir_exists($tmpdir, true, true)) { throw new restore_controller_exception('cannot_create_backup_temp_dir'); } diff --git a/backup/util/factories/backup_factory.class.php b/backup/util/factories/backup_factory.class.php index 38c72a89168..6b0a1b0be9b 100644 --- a/backup/util/factories/backup_factory.class.php +++ b/backup/util/factories/backup_factory.class.php @@ -60,9 +60,9 @@ abstract class backup_factory { // Create file_logger, observing $CFG->backup_file_logger_level // defaulting to $dfltloglevel - check_dir_exists($CFG->tempdir . '/backup', true, true); // need to ensure that temp/backup already exists + $backuptempdir = make_backup_temp_directory(''); // Need to ensure that $CFG->backuptempdir already exists. $fllevel = isset($CFG->backup_file_logger_level) ? $CFG->backup_file_logger_level : $dfltloglevel; - $enabledloggers[] = new file_logger($fllevel, true, true, $CFG->tempdir . '/backup/' . $backupid . '.log'); + $enabledloggers[] = new file_logger($fllevel, true, true, $backuptempdir . '/' . $backupid . '.log'); // Create database_logger, observing $CFG->backup_database_logger_level and defaulting to LOG_WARNING // and pointing to the backup_logs table diff --git a/backup/util/helper/backup_file_manager.class.php b/backup/util/helper/backup_file_manager.class.php index 876423dd619..c985aa54c6d 100644 --- a/backup/util/helper/backup_file_manager.class.php +++ b/backup/util/helper/backup_file_manager.class.php @@ -43,7 +43,8 @@ class backup_file_manager { public static function get_backup_storage_base_dir($backupid) { global $CFG; - return $CFG->tempdir . '/backup/' . $backupid . '/files'; + $backupiddir = make_backup_temp_directory($backupid); + return $backupiddir . '/files'; } /** diff --git a/backup/util/helper/backup_general_helper.class.php b/backup/util/helper/backup_general_helper.class.php index fd5a935d360..e84b6f81a18 100644 --- a/backup/util/helper/backup_general_helper.class.php +++ b/backup/util/helper/backup_general_helper.class.php @@ -121,7 +121,8 @@ abstract class backup_general_helper extends backup_helper { $info = new stdclass(); // Final information goes here - $moodlefile = $CFG->tempdir . '/backup/' . $tempdir . '/moodle_backup.xml'; + $backuptempdir = make_backup_temp_directory('', false); + $moodlefile = $backuptempdir . '/' . $tempdir . '/moodle_backup.xml'; if (!file_exists($moodlefile)) { // Shouldn't happen ever, but... throw new backup_helper_exception('missing_moodle_backup_xml_file', $moodlefile); } @@ -267,7 +268,7 @@ abstract class backup_general_helper extends backup_helper { // Extract moodle_backup.xml. $tmpname = 'info_from_mbz_' . time() . '_' . random_string(4); - $tmpdir = $CFG->tempdir . '/backup/' . $tmpname; + $tmpdir = make_backup_temp_directory($tmpname); $fp = get_file_packer('application/vnd.moodle.backup'); $extracted = $fp->extract_to_pathname($filepath, $tmpdir, array('moodle_backup.xml'), $progress); diff --git a/backup/util/helper/backup_helper.class.php b/backup/util/helper/backup_helper.class.php index a5a7faa0fb5..fa3bc79cf7c 100644 --- a/backup/util/helper/backup_helper.class.php +++ b/backup/util/helper/backup_helper.class.php @@ -33,8 +33,8 @@ abstract class backup_helper { * Given one backupid, create all the needed dirs to have one backup temp dir available */ static public function check_and_create_backup_dir($backupid) { - global $CFG; - if (!check_dir_exists($CFG->tempdir . '/backup/' . $backupid, true, true)) { + $backupiddir = make_backup_temp_directory($backupid, false); + if (empty($backupiddir)) { throw new backup_helper_exception('cannot_create_backup_temp_dir'); } } @@ -49,8 +49,8 @@ abstract class backup_helper { * @param \core\progress\base $progress Optional progress reporting object */ static public function clear_backup_dir($backupid, \core\progress\base $progress = null) { - global $CFG; - if (!self::delete_dir_contents($CFG->tempdir . '/backup/' . $backupid, '', $progress)) { + $backupiddir = make_backup_temp_directory($backupid, false); + if (!self::delete_dir_contents($backupiddir, '', $progress)) { throw new backup_helper_exception('cannot_empty_backup_temp_dir'); } return true; @@ -66,9 +66,9 @@ abstract class backup_helper { * @param \core\progress\base $progress Optional progress reporting object */ static public function delete_backup_dir($backupid, \core\progress\base $progress = null) { - global $CFG; + $backupiddir = make_backup_temp_directory($backupid, false); self::clear_backup_dir($backupid, $progress); - return rmdir($CFG->tempdir . '/backup/' . $backupid); + return rmdir($backupiddir); } /** @@ -157,13 +157,12 @@ abstract class backup_helper { * @param \core\progress\base $progress Optional progress reporting object */ static public function delete_old_backup_dirs($deletefrom, \core\progress\base $progress = null) { - global $CFG; - $status = true; - // Get files and directories in the temp backup dir witout descend - $list = get_directory_list($CFG->tempdir . '/backup', '', false, true, true); + // Get files and directories in the backup temp dir without descend. + $backuptempdir = make_backup_temp_directory(''); + $list = get_directory_list($backuptempdir, '', false, true, true); foreach ($list as $file) { - $file_path = $CFG->tempdir . '/backup/' . $file; + $file_path = $backuptempdir . '/' . $file; $moddate = filemtime($file_path); if ($status && $moddate < $deletefrom) { //If directory, recurse diff --git a/backup/util/helper/convert_helper.class.php b/backup/util/helper/convert_helper.class.php index e5d21b8fbaf..98e1ed0eafa 100644 --- a/backup/util/helper/convert_helper.class.php +++ b/backup/util/helper/convert_helper.class.php @@ -131,15 +131,12 @@ abstract class convert_helper { * @return boolean true if moodle2 format detected, false otherwise */ public static function detect_moodle2_format($tempdir) { - global $CFG; - - $dirpath = $CFG->tempdir . '/backup/' . $tempdir; - $filepath = $dirpath . '/moodle_backup.xml'; - + $dirpath = make_backup_temp_directory($tempdir, false); if (!is_dir($dirpath)) { throw new convert_helper_exception('tmp_backup_directory_not_found', $dirpath); } + $filepath = $dirpath . '/moodle_backup.xml'; if (!file_exists($filepath)) { return false; } diff --git a/backup/util/plan/backup_plan.class.php b/backup/util/plan/backup_plan.class.php index 954ecb06c5b..e3db201acad 100644 --- a/backup/util/plan/backup_plan.class.php +++ b/backup/util/plan/backup_plan.class.php @@ -37,13 +37,12 @@ class backup_plan extends base_plan implements loggable { * Constructor - instantiates one object of this class */ public function __construct($controller) { - global $CFG; - if (! $controller instanceof backup_controller) { throw new backup_plan_exception('wrong_backup_controller_specified'); } + $backuptempdir = make_backup_temp_directory(''); $this->controller = $controller; - $this->basepath = $CFG->tempdir . '/backup/' . $controller->get_backupid(); + $this->basepath = $backuptempdir . '/' . $controller->get_backupid(); $this->excludingdactivities = false; parent::__construct('backup_plan'); } diff --git a/backup/util/plan/restore_plan.class.php b/backup/util/plan/restore_plan.class.php index 3f2ce6386da..185556d05ae 100644 --- a/backup/util/plan/restore_plan.class.php +++ b/backup/util/plan/restore_plan.class.php @@ -49,8 +49,9 @@ class restore_plan extends base_plan implements loggable { if (! $controller instanceof restore_controller) { throw new restore_plan_exception('wrong_restore_controller_specified'); } + $backuptempdir = make_backup_temp_directory(''); $this->controller = $controller; - $this->basepath = $CFG->tempdir . '/backup/' . $controller->get_tempdir(); + $this->basepath = $backuptempdir . '/' . $controller->get_tempdir(); $this->preloaded = false; $this->decoder = new restore_decode_processor($this->get_restoreid(), $this->get_info()->original_wwwroot, $CFG->wwwroot); $this->missingmodules = false; diff --git a/backup/util/ui/restore_ui_stage.class.php b/backup/util/ui/restore_ui_stage.class.php index 2917c727f7d..20457e02226 100644 --- a/backup/util/ui/restore_ui_stage.class.php +++ b/backup/util/ui/restore_ui_stage.class.php @@ -288,9 +288,9 @@ class restore_ui_stage_confirm extends restore_ui_independent_stage implements f * @throws restore_ui_exception */ public function process() { - global $CFG; + $backuptempdir = make_backup_temp_directory(''); if ($this->filename) { - $archivepath = $CFG->tempdir . '/backup/' . $this->filename; + $archivepath = $backuptempdir . '/' . $this->filename; if (!file_exists($archivepath)) { throw new restore_ui_exception('invalidrestorefile'); } @@ -316,13 +316,14 @@ class restore_ui_stage_confirm extends restore_ui_independent_stage implements f * @return bool */ protected function extract_file_to_dir($source) { - global $CFG, $USER; + global $USER; $this->filepath = restore_controller::get_tempdir_name($this->contextid, $USER->id); + $backuptempdir = make_backup_temp_directory('', false); $fb = get_file_packer('application/vnd.moodle.backup'); $result = $fb->extract_to_pathname($source, - $CFG->tempdir . '/backup/' . $this->filepath . '/', null, $this); + $backuptempdir . '/' . $this->filepath . '/', null, $this); // If any progress happened, end it. if ($this->startedprogress) { @@ -473,8 +474,9 @@ class restore_ui_stage_destination extends restore_ui_independent_stage { * @throws restore_ui_exception */ public function process() { - global $CFG, $DB; - if (!file_exists("$CFG->tempdir/backup/".$this->filepath) || !is_dir("$CFG->tempdir/backup/".$this->filepath)) { + global $DB; + $filepathdir = make_backup_temp_directory($this->filepath, false); + if (!file_exists($filepathdir) || !is_dir($filepathdir)) { throw new restore_ui_exception('invalidrestorepath'); } if (optional_param('searchcourses', false, PARAM_BOOL)) { diff --git a/blocks/community/communitycourse.php b/blocks/community/communitycourse.php index bc13ad2b550..67f024b490a 100644 --- a/blocks/community/communitycourse.php +++ b/blocks/community/communitycourse.php @@ -75,7 +75,8 @@ $cancelrestore = optional_param('cancelrestore', false, PARAM_INT); if ($usercandownload and $cancelrestore and confirm_sesskey()) { $filename = optional_param('filename', '', PARAM_ALPHANUMEXT); //delete temp file - unlink($CFG->tempdir . '/backup/' . $filename . ".mbz"); + $backuptempdir = make_backup_temp_directory(''); + unlink($backuptempdir . '/' . $filename . ".mbz"); } /// Download diff --git a/config-dist.php b/config-dist.php index e3156b05f85..afb9c1c57e3 100644 --- a/config-dist.php +++ b/config-dist.php @@ -434,10 +434,16 @@ $CFG->admin = 'admin'; // Localcachedir is intended for server clusters, it does not have to be shared by cluster nodes. // The directories must not be accessible via web. // -// $CFG->tempdir = '/var/www/moodle/temp'; // Directory MUST BE SHARED by all clsuter nodes. +// $CFG->tempdir = '/var/www/moodle/temp'; // Directory MUST BE SHARED by all cluster nodes. // $CFG->cachedir = '/var/www/moodle/cache'; // Directory MUST BE SHARED by all cluster nodes, locking required. // $CFG->localcachedir = '/var/local/cache'; // Intended for local node caching. // +// It is possible to specify a different backup temp directory, use local fast filesystem +// for normal web servers. Server clusters MUST use shared filesystem for backuptempdir! +// The directory must not be accessible via web. +// +// $CFG->backuptempdir = '/var/www/moodle/backuptemp'; // Directory MUST BE SHARED by all cluster nodes. +// // Some filesystems such as NFS may not support file locking operations. // Locking resolves race conditions and is strongly recommended for production servers. // $CFG->preventfilelocking = false; diff --git a/course/tests/restore_test.php b/course/tests/restore_test.php index 2569205aaff..470e03b13da 100644 --- a/course/tests/restore_test.php +++ b/course/tests/restore_test.php @@ -45,7 +45,7 @@ class core_course_restore_testcase extends advanced_testcase { * @return string */ protected function backup_course($courseid, $userid = 2) { - globaL $CFG; + $backuptempdir = make_backup_temp_directory(''); $packer = get_file_packer('application/vnd.moodle.backup'); $bc = new backup_controller(backup::TYPE_1COURSE, $courseid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, @@ -53,7 +53,7 @@ class core_course_restore_testcase extends advanced_testcase { $bc->execute_plan(); $results = $bc->get_results(); - $results['backup_destination']->extract_to_pathname($packer, "$CFG->tempdir/backup/core_course_testcase"); + $results['backup_destination']->extract_to_pathname($packer, "$backuptempdir/core_course_testcase"); $bc->destroy(); unset($bc); diff --git a/install.php b/install.php index e7f8de7c7cf..be4f20aabd7 100644 --- a/install.php +++ b/install.php @@ -163,6 +163,7 @@ $CFG->wwwroot = install_guess_wwwroot(); // can not be changed - pp $CFG->httpswwwroot = $CFG->wwwroot; $CFG->dataroot = $config->dataroot; $CFG->tempdir = $CFG->dataroot.'/temp'; +$CFG->backuptempdir = $CFG->tempdir.'/backup'; $CFG->cachedir = $CFG->dataroot.'/cache'; $CFG->localcachedir = $CFG->dataroot.'/localcache'; $CFG->admin = $config->admin; diff --git a/lib/classes/hub/publication.php b/lib/classes/hub/publication.php index 29c51e672cc..f0f48d946ba 100644 --- a/lib/classes/hub/publication.php +++ b/lib/classes/hub/publication.php @@ -375,9 +375,9 @@ class publication { global $CFG, $USER; require_once($CFG->libdir . "/filelib.php"); - make_temp_directory('backup'); + $backuptempdir = make_backup_temp_directory(''); $filename = md5(time() . '-' . $hubcourseid . '-'. $USER->id . '-'. random_string(20)); - $path = $CFG->tempdir.'/backup/'.$filename.".mbz"; + $path = $backuptempdir.'/'.$filename.".mbz"; api::download_course_backup($hubcourseid, $path); diff --git a/lib/classes/task/file_temp_cleanup_task.php b/lib/classes/task/file_temp_cleanup_task.php index 0b0253ac3b2..7166872e660 100644 --- a/lib/classes/task/file_temp_cleanup_task.php +++ b/lib/classes/task/file_temp_cleanup_task.php @@ -38,13 +38,13 @@ class file_temp_cleanup_task extends scheduled_task { } /** - * Do the job. - * Throw exceptions on errors (the job will be retried). + * Do the job, given the target directory. + * + * @param string $tmpdir The directory hosting the candidate stale temp files. */ - public function execute() { + protected function execute_on($tmpdir) { global $CFG; - $tmpdir = $CFG->tempdir; // Default to last weeks time. $time = time() - ($CFG->tempdatafoldercleanup * 3600); @@ -96,4 +96,23 @@ class file_temp_cleanup_task extends scheduled_task { } } + /** + * Do the job. + * Throw exceptions on errors (the job will be retried). + */ + public function execute() { + global $CFG; + + // The directories hosting the candidate stale temp files eventually are $CFG->tempdir and $CFG->backuptempdir. + + // Do the job on each of the directories above. + // Let's start with $CFG->tempdir. + $this->execute_on($CFG->tempdir); + + // Run on $CFG->backuptempdir too, if different from the default one, '$CFG->tempdir/backup'. + if (realpath(dirname($CFG->backuptempdir)) !== $CFG->tempdir) { + // The $CFG->backuptempdir setting is different from the default '$CFG->tempdir/backup'. + $this->execute_on($CFG->backuptempdir); + } + } } diff --git a/lib/setup.php b/lib/setup.php index 29cf769bf73..8ee0219486f 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -36,6 +36,7 @@ * - $CFG->dataroot - Path to moodle data files directory on server's filesystem. * - $CFG->dirroot - Path to moodle's library folder on server's filesystem. * - $CFG->libdir - Path to moodle's library folder on server's filesystem. + * - $CFG->backuptempdir - Path to moodle's backup temp file directory on server's filesystem. * - $CFG->tempdir - Path to moodle's temp file directory on server's filesystem. * - $CFG->cachedir - Path to moodle's cache directory on server's filesystem (shared by cluster nodes). * - $CFG->localcachedir - Path to moodle's local cache directory (not shared by cluster nodes). @@ -192,6 +193,11 @@ if (!isset($CFG->tempdir)) { $CFG->tempdir = "$CFG->dataroot/temp"; } +// Allow overriding of backuptempdir but be backwards compatible +if (!isset($CFG->backuptempdir)) { + $CFG->backuptempdir = "$CFG->tempdir/backup"; +} + // Allow overriding of cachedir but be backwards compatible if (!isset($CFG->cachedir)) { $CFG->cachedir = "$CFG->dataroot/cache"; diff --git a/lib/setuplib.php b/lib/setuplib.php index 8e9e9e16d06..7a07e1d023f 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -1661,6 +1661,42 @@ function make_request_directory($exceptiononerror = true) { return make_unique_writable_directory($basedir, $exceptiononerror); } +/** + * Get the full path of a directory under $CFG->backuptempdir. + * + * @param string $directory the relative path of the directory under $CFG->backuptempdir + * @return string|false Returns full path to directory given a valid string; otherwise, false. + */ +function get_backup_temp_directory($directory) { + global $CFG; + if (($directory === null) || ($directory === false)) { + return false; + } + return "$CFG->backuptempdir/$directory"; +} + +/** + * Create a directory under $CFG->backuptempdir and make sure it is writable. + * + * Do not use for storing generic temp files - see make_temp_directory() instead for this purpose. + * + * Backup temporary files must be on a shared storage. + * + * @param string $directory the relative path of the directory to be created under $CFG->backuptempdir + * @param bool $exceptiononerror throw exception if error encountered + * @return string|false Returns full path to directory if successful, false if not; may throw exception + */ +function make_backup_temp_directory($directory, $exceptiononerror = true) { + global $CFG; + if ($CFG->backuptempdir !== "$CFG->tempdir/backup") { + check_dir_exists($CFG->backuptempdir, true, true); + protect_directory($CFG->backuptempdir); + } else { + protect_directory($CFG->tempdir); + } + return make_writable_directory("$CFG->backuptempdir/$directory", $exceptiononerror); +} + /** * Create a directory under tempdir and make sure it is writable. * diff --git a/lib/testing/classes/util.php b/lib/testing/classes/util.php index 533200850a6..176700bb286 100644 --- a/lib/testing/classes/util.php +++ b/lib/testing/classes/util.php @@ -813,6 +813,7 @@ abstract class testing_util { } make_temp_directory(''); + make_backup_temp_directory(''); make_cache_directory(''); make_localcache_directory(''); // Purge all data from the caches. This is required for consistency between tests. diff --git a/lib/tests/cronlib_test.php b/lib/tests/cronlib_test.php index 47ee55cd736..8db487a3af7 100644 --- a/lib/tests/cronlib_test.php +++ b/lib/tests/cronlib_test.php @@ -147,7 +147,7 @@ class cronlib_testcase extends basic_testcase { public function test_cron_delete_from_temp($nodes, $expected) { global $CFG; - $tmpdir = $CFG->tempdir; + $tmpdir = realpath($CFG->tempdir); foreach ($nodes as $data) { if ($data->isdir) { @@ -168,7 +168,12 @@ class cronlib_testcase extends basic_testcase { $actual = array(); for ($iter->rewind(); $iter->valid(); $iter->next()) { - if (!$iter->isDot()) { + $isvalid = true; + $isvalid = $isvalid && !$iter->isDot(); + // Remove the default $CFG->tempdir/backup directory and $CFG->tempdir/.htaccess file from this comparison. + $isvalid = $isvalid && !($iter->isDir() && ($iter->getRealpath() === "{$tmpdir}/backup")); + $isvalid = $isvalid && !($iter->isFile() && ($iter->getRealpath() === "{$tmpdir}/.htaccess")); + if ($isvalid) { $actual[] = $iter->getRealPath(); } } diff --git a/lib/tests/scheduled_task_test.php b/lib/tests/scheduled_task_test.php index adc9b4143c1..10ce44be662 100644 --- a/lib/tests/scheduled_task_test.php +++ b/lib/tests/scheduled_task_test.php @@ -415,9 +415,10 @@ class core_scheduled_task_testcase extends advanced_testcase { */ public function test_file_temp_cleanup_task() { global $CFG; + $backuptempdir = make_backup_temp_directory(''); // Create directories. - $dir = $CFG->tempdir . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'backup01' . DIRECTORY_SEPARATOR . 'courses'; + $dir = $backuptempdir . DIRECTORY_SEPARATOR . 'backup01' . DIRECTORY_SEPARATOR . 'courses'; mkdir($dir, 0777, true); // Create files to be checked and then deleted. @@ -440,11 +441,11 @@ class core_scheduled_task_testcase extends advanced_testcase { // Change the time modified on modules.xml. touch($file02, time() - (8 * 24 * 3600)); // Change the time modified on the courses directory. - touch($CFG->tempdir . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'backup01' . DIRECTORY_SEPARATOR . + touch($backuptempdir . DIRECTORY_SEPARATOR . 'backup01' . DIRECTORY_SEPARATOR . 'courses', time() - (8 * 24 * 3600)); // Run the scheduled task to remove the file and directory. $task->execute(); - $filesarray = scandir($CFG->tempdir . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'backup01'); + $filesarray = scandir($backuptempdir . DIRECTORY_SEPARATOR . 'backup01'); // There should only be two items in the array, '.' and '..'. $this->assertEquals(2, count($filesarray)); @@ -464,8 +465,8 @@ class core_scheduled_task_testcase extends advanced_testcase { $task->execute(); $filesarray = scandir($CFG->tempdir); // All of the files and directories should be deleted. - // There should only be two items in the array, '.' and '..'. - $this->assertEquals(2, count($filesarray)); + // There should only be three items in the array, '.', '..' and '.htaccess'. + $this->assertEquals([ '.', '..', '.htaccess' ], $filesarray); } /** diff --git a/lib/upgradelib.php b/lib/upgradelib.php index 0c1071a5122..13ab17aa791 100644 --- a/lib/upgradelib.php +++ b/lib/upgradelib.php @@ -1717,6 +1717,9 @@ function install_core($version, $verbose) { remove_dir($CFG->tempdir.'', true); make_temp_directory('', true); + remove_dir($CFG->backuptempdir.'', true); + make_backup_temp_directory('', true); + remove_dir($CFG->dataroot.'/muc', true); make_writable_directory($CFG->dataroot.'/muc', true); diff --git a/mod/quiz/tests/tags_test.php b/mod/quiz/tests/tags_test.php index 161e07b1d14..38c70682c8d 100644 --- a/mod/quiz/tests/tags_test.php +++ b/mod/quiz/tests/tags_test.php @@ -41,8 +41,7 @@ class mod_quiz_tags_testcase extends advanced_testcase { $this->setAdminUser(); $backupid = 'abc'; - $backuppath = $CFG->tempdir . '/backup/' . $backupid; - check_dir_exists($backuppath); + $backuppath = make_backup_temp_directory($backupid); get_file_packer('application/vnd.moodle.backup')->extract_to_pathname( __DIR__ . "/fixtures/random_by_tag_quiz.mbz", $backuppath); diff --git a/mod/upgrade.txt b/mod/upgrade.txt index 1edbcadddd5..495cdb303a7 100644 --- a/mod/upgrade.txt +++ b/mod/upgrade.txt @@ -1,6 +1,11 @@ This files describes API changes in /mod/* - activity modules, information provided here is intended especially for developers. +=== 3.5 === + +Required changes in code: +* use new make_backup_temp_directory() + === 3.4 === * Navigation between activities via a previous and next link was added to Boost, Clean and Bootstrapbase. This