Permalink
Browse files

MDL-38570 administration: Temporary file deletion

Added new function "cron_delete_from_temp" to delete old files and
directories under $CFG->tempdir during cron run. Unit test included.
  • Loading branch information...
Tim Gus
Tim Gus committed Jul 30, 2013
1 parent ee78814 commit 179961e8a46d886de6ab865c2ef8cea26f619ef1
Showing with 203 additions and 0 deletions.
  1. +48 −0 lib/cronlib.php
  2. +155 −0 lib/tests/cronlib_test.php
View
@@ -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;
+}
View
@@ -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);
+ }
+}

0 comments on commit 179961e

Please sign in to comment.