MDL-69975 core: Fix paths longer than 260 chars on windows
authorBrendan Heywood <brendan@catalyst-au.net>
Wed, 28 Oct 2020 05:08:11 +0000 (16:08 +1100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Sun, 1 Nov 2020 10:09:39 +0000 (11:09 +0100)
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) <stronk7@moodle.org>
Co-authored-by: Jun Pataleta <jun@moodle.com>
lib/moodlelib.php
lib/setuplib.php

index 4f543ea..590777e 100644 (file)
@@ -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) {
  * @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;
     }
         // Nothing to do.
         return true;
     }
index b28c58a..9bfb3e3 100644 (file)
@@ -1498,8 +1498,9 @@ function make_unique_writable_directory($basedir, $exceptiononerror = true) {
     }
 
     do {
     }
 
     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) &&
     } 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) {
     $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);
 
         make_writable_directory($basedir);
         protect_directory($basedir);