Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 39 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * A scheduled task.
  19   *
  20   * @package    core
  21   * @copyright  2013 onwards Martin Dougiamas  http://dougiamas.com
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace core\task;
  25  
  26  /**
  27   * Simple task to delete temp files older than 1 week.
  28   */
  29  class file_temp_cleanup_task extends scheduled_task {
  30  
  31      /**
  32       * Get a descriptive name for this task (shown to admins).
  33       *
  34       * @return string
  35       */
  36      public function get_name() {
  37          return get_string('tasktempfilecleanup', 'admin');
  38      }
  39  
  40      /**
  41       * Do the job, given the target directory.
  42       *
  43       * @param string $tmpdir The directory hosting the candidate stale temp files.
  44       */
  45      protected function execute_on($tmpdir) {
  46          global $CFG;
  47  
  48          // Default to last weeks time.
  49          $time = time() - ($CFG->tempdatafoldercleanup * 3600);
  50  
  51          $dir = new \RecursiveDirectoryIterator($tmpdir);
  52          // Show all child nodes prior to their parent.
  53          $iter = new \RecursiveIteratorIterator($dir, \RecursiveIteratorIterator::CHILD_FIRST);
  54  
  55          // An array of the full path (key) and date last modified.
  56          $modifieddateobject = array();
  57  
  58          // Get the time modified for each directory node. Nodes will be updated
  59          // once a file is deleted, so we need a list of the original values.
  60          for ($iter->rewind(); $iter->valid(); $iter->next()) {
  61              $node = $iter->getRealPath();
  62              if (!is_readable($node)) {
  63                  continue;
  64              }
  65              $modifieddateobject[$node] = $iter->getMTime();
  66          }
  67  
  68          // Now loop through again and remove old files and directories.
  69          for ($iter->rewind(); $iter->valid(); $iter->next()) {
  70              $node = $iter->getRealPath();
  71              if (!isset($modifieddateobject[$node]) || !is_readable($node)) {
  72                  continue;
  73              }
  74  
  75              // Check if file or directory is older than the given time.
  76              if ($modifieddateobject[$node] < $time) {
  77                  if ($iter->isDir() && !$iter->isDot()) {
  78                      // Don't attempt to delete the directory if it isn't empty.
  79                      if (!glob($node. DIRECTORY_SEPARATOR . '*')) {
  80                          if (@rmdir($node) === false) {
  81                              mtrace("Failed removing directory '$node'.");
  82                          }
  83                      }
  84                  }
  85                  if ($iter->isFile()) {
  86                      if (@unlink($node) === false) {
  87                          mtrace("Failed removing file '$node'.");
  88                      }
  89                  }
  90              } else {
  91                  // Return the time modified to the original date only for real files.
  92                  if ($iter->isDir() && !$iter->isDot()) {
  93                      try {
  94                          @touch($node, $modifieddateobject[$node]);
  95                      } catch (\Throwable $t) {
  96                          null;
  97                      }
  98                  }
  99              }
 100          }
 101      }
 102  
 103      /**
 104       * Do the job.
 105       * Throw exceptions on errors (the job will be retried).
 106       */
 107      public function execute() {
 108          global $CFG;
 109  
 110          // The directories hosting the candidate stale temp files eventually are $CFG->tempdir and $CFG->backuptempdir.
 111  
 112          // Do the job on each of the directories above.
 113          // Let's start with $CFG->tempdir.
 114          $this->execute_on($CFG->tempdir);
 115  
 116          // Run on $CFG->backuptempdir too, if different from the default one, '$CFG->tempdir/backup'.
 117          if (realpath(dirname($CFG->backuptempdir)) !== realpath($CFG->tempdir)) {
 118              // The $CFG->backuptempdir setting is different from the default '$CFG->tempdir/backup'.
 119              $this->execute_on($CFG->backuptempdir);
 120          }
 121      }
 122  }