From 10f33b6fdc940eb9518fbb1f2f0a234cf118d4ea Mon Sep 17 00:00:00 2001 From: Brendan Heywood Date: Wed, 28 Oct 2020 16:08:11 +1100 Subject: [PATCH] MDL-69975 core: Fix paths longer than 260 chars on windows Also, ensure that remove_dir() only processes directories, because sometimes it was being called by shutdown managers with files, leading to PHP warnings. Co-authored-by: Eloy Lafuente (stronk7) Co-authored-by: Jun Pataleta --- lib/moodlelib.php | 2 +- lib/setuplib.php | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 4f543ea91afae..590777eb8e14b 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -9862,7 +9862,7 @@ function rename_to_unused_name(string $filepath, string $prefix = '_temp_') { * @return bool success, true also if dir does not exist */ function remove_dir($dir, $contentonly=false) { - if (!file_exists($dir)) { + if (!is_dir($dir)) { // Nothing to do. return true; } diff --git a/lib/setuplib.php b/lib/setuplib.php index b28c58a63264e..9bfb3e36064f8 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -1498,8 +1498,9 @@ function make_unique_writable_directory($basedir, $exceptiononerror = true) { } do { - // Generate a new (hopefully unique) directory name. - $uniquedir = $basedir . DIRECTORY_SEPARATOR . \core\uuid::generate(); + // Let's use uniqid() because it's "unique enough" (microtime based). The loop does handle repetitions. + // Windows and old PHP don't like very long paths, so try to keep this shorter. See MDL-69975. + $uniquedir = $basedir . DIRECTORY_SEPARATOR . uniqid(); } while ( // Ensure that basedir is still writable - if we do not check, we could get stuck in a loop here. is_writable($basedir) && @@ -1635,7 +1636,12 @@ function get_request_storage_directory($exceptiononerror = true, bool $forcecrea $createnewdirectory = $forcecreate || !$writabledirectoryexists; if ($createnewdirectory) { - $basedir = "{$CFG->localrequestdir}/{$CFG->siteidentifier}"; + + // Let's add the first chars of siteidentifier only. This is to help separate + // paths on systems which host multiple moodles. We don't use the full id + // as Windows and old PHP don't like very long paths. See MDL-69975. + $basedir = $CFG->localrequestdir . '/' . substr($CFG->siteidentifier, 0, 4); + make_writable_directory($basedir); protect_directory($basedir);