Merge branch 'MDL-38570-master' of https://github.com/timgus/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 10 Sep 2013 03:13:29 +0000 (11:13 +0800)
committerDan Poltawski <dan@moodle.com>
Tue, 10 Sep 2013 03:13:29 +0000 (11:13 +0800)
lib/cronlib.php
lib/tests/cronlib_test.php [new file with mode: 0644]

index 41c7bb2..2cce5c2 100644 (file)
@@ -170,6 +170,9 @@ function cron_run() {
             mtrace(' Cleaned up read notifications');
         }
 
+        mtrace(' Deleting temporary files...');
+        cron_delete_from_temp();
+
         mtrace("...finished clean-up tasks");
 
     } // End of occasional clean-up tasks
@@ -767,3 +770,48 @@ function notify_login_failures() {
 
     return true;
 }
+
+/**
+ * Delete files and directories older than one week from directory provided by $CFG->tempdir.
+ *
+ * @exception Exception Failed reading/accessing file or directory
+ * @return bool True on successful file and directory deletion; otherwise, false on failure
+ */
+function cron_delete_from_temp() {
+    global $CFG;
+
+    $tmpdir = $CFG->tempdir;
+    // Default to last weeks time.
+    $time = strtotime('-1 week');
+
+    try {
+        $dir = new RecursiveDirectoryIterator($tmpdir);
+        // Show all child nodes prior to their parent.
+        $iter = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
+
+        for ($iter->rewind(); $iter->valid(); $iter->next()) {
+            $node = $iter->getPathname();
+            if (!is_readable($node)) {
+                continue;
+            }
+            // Check if file or directory is older than the given time.
+            if ($iter->getMTime() < $time) {
+                if ($iter->isDir() && !$iter->isDot()) {
+                    if (@rmdir($node) === false) {
+                        mtrace("Failed removing directory '$node'.");
+                    }
+                }
+                if ($iter->isFile()) {
+                    if (@unlink($node) === false) {
+                        mtrace("Failed removing file '$node'.");
+                    }
+                }
+            }
+        }
+    } catch (Exception $e) {
+        mtrace('Failed reading/accessing file or directory.');
+        return false;
+    }
+
+    return true;
+}
diff --git a/lib/tests/cronlib_test.php b/lib/tests/cronlib_test.php
new file mode 100644 (file)
index 0000000..fe60c88
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for the cron.
+ *
+ * @package   core
+ * @category  test
+ * @copyright 2013 Tim Gusak <tim.gusak@remote-learner.net>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->libdir.'/cronlib.php');
+
+class cronlib_testcase extends basic_testcase {
+
+    /**
+     * Data provider for cron_delete_from_temp.
+     *
+     * @return array Provider data
+     */
+    public function cron_delete_from_temp_provider() {
+        global $CFG;
+        $time = time();
+
+        $weekstime = $time - strtotime('1 week');
+        $beforeweekstime = $time - strtotime('1 week') - 1;
+        $afterweekstime = $time + strtotime('1 week') + 1;
+
+        $node1 = new stdClass();
+        $node1->path = '/dir1/dir1_1/dir1_2/dir1_3/';
+        $node1->time = 1;
+        $node1->isdir = true;
+
+        $node2 = new stdClass();
+        $node2->path = '/dir1/dir1_4/';
+        $node2->time = $time;
+        $node2->isdir = true;
+
+        $node3 = new stdClass();
+        $node3->path = '/dir2/';
+        $node3->isdir = true;
+        $node3->time = $time - $weekstime;
+
+        $node4 = new stdClass();
+        $node4->path = '/dir3/';
+        $node4->isdir = true;
+        $node4->time = $time - $afterweekstime;
+
+        $node5 = new stdClass();
+        $node5->path = '/dir1/dir1_1/dir1_2/file1';
+        $node5->isdir = false;
+        $node5->time = $beforeweekstime;
+
+        $node6 = new stdClass();
+        $node6->path = '/dir1/dir1_1/dir1_2/file2';
+        $node6->isdir = false;
+        $node6->time = $time;
+
+        $node7 = new stdClass();
+        $node7->path = '/dir1/dir1_4/file1';
+        $node7->isdir = false;
+        $node7->time = $time - $afterweekstime;
+
+        $node8 = new stdClass();
+        $node8->path = '/dir1/dir1_4/file2';
+        $node8->isdir = false;
+        $node8->time = $time;
+
+        $node9 = new stdClass();
+        $node9->path = '/file1';
+        $node9->isdir = false;
+        $node9->time = $time;
+
+        $node10 = new stdClass();
+        $node10->path = '/file2';
+        $node10->isdir = false;
+        $node10->time = $time - $afterweekstime;
+
+        $data = array(
+                array(
+                    array($node1, $node2, $node3, $node4, $node5, $node6, $node7, $node8, $node9, $node10),
+                    array(
+                        "$CFG->tempdir/dir1",
+                        "$CFG->tempdir/dir1/dir1_1",
+                        "$CFG->tempdir/dir1/dir1_1/dir1_2",
+                        "$CFG->tempdir/dir1/dir1_1/dir1_2/file2",
+                        "$CFG->tempdir/dir1/dir1_4",
+                        "$CFG->tempdir/dir1/dir1_4/file2",
+                        "$CFG->tempdir/dir2",
+                        "$CFG->tempdir/file1",
+                    )
+                ),
+                array(
+                    array(),
+                    array()
+                )
+        );
+
+        return $data;
+    }
+
+    /**
+     * Test removing files and directories from tempdir.
+     *
+     * @dataProvider cron_delete_from_temp_provider
+     * @param array $nodes List of files and directories
+     * @param array $expected The expected results
+     */
+    public function test_cron_delete_from_temp($nodes, $expected) {
+        global $CFG;
+
+        $tmpdir = $CFG->tempdir;
+
+        foreach ($nodes as $data) {
+            if ($data->isdir) {
+                mkdir($tmpdir.$data->path, $CFG->directorypermissions, true);
+            }
+            touch($tmpdir.$data->path, $data->time);
+        }
+
+        cron_delete_from_temp();
+
+        $dir = new RecursiveDirectoryIterator($tmpdir);
+        $iter = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
+
+        $actual = array();
+        for ($iter->rewind(); $iter->valid(); $iter->next()) {
+            if (!$iter->isDot()) {
+                $actual[] = $iter->getPathname();
+            }
+        }
+
+        // Sort results to guarantee actual order.
+        sort($actual);
+
+        $this->assertEquals($expected, $actual);
+    }
+}