summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2014-01-19 11:05:28 -0800
committerAndreas Gohr <andi@splitbrain.org>2014-01-19 11:05:28 -0800
commit5838057a4fe97e039cc70bf30da3619cb9072c74 (patch)
tree10cf98cca3552f88d3209ebd60088ce916fd10f1
parentca605ff6763b98b580278988791dc5e57fc05a74 (diff)
parentd8cf4dd43ecd37c371acf9bc6c17998b65d42ba4 (diff)
downloadrpg-5838057a4fe97e039cc70bf30da3619cb9072c74.tar.gz
rpg-5838057a4fe97e039cc70bf30da3619cb9072c74.tar.bz2
Merge pull request #494 from splitbrain/recursivedelete
Recursive delete function
-rw-r--r--_test/tests/inc/io_rmdir.test.php219
-rw-r--r--inc/io.php50
2 files changed, 269 insertions, 0 deletions
diff --git a/_test/tests/inc/io_rmdir.test.php b/_test/tests/inc/io_rmdir.test.php
new file mode 100644
index 000000000..3de57fa86
--- /dev/null
+++ b/_test/tests/inc/io_rmdir.test.php
@@ -0,0 +1,219 @@
+<?php
+
+class io_rmdir_test extends DokuWikiTest {
+
+ function test_nopes(){
+ // set up test dir
+ $dir = io_mktmpdir();
+ $top = dirname($dir);
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+
+ // switch into it
+ $this->assertTrue(chdir($dir));
+ $this->assertEquals($dir, getcwd());
+
+
+ $this->assertFalse(io_rmdir('', false));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir('', true));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir(null, false));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir(null, true));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir(false, false));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir(false, true));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir(array(), false));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFalse(io_rmdir(array(), true));
+ clearstatcache();
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ $this->assertFileNotExists("$dir/this/does/not/exist");
+ $this->assertTrue(io_rmdir("$dir/this/does/not/exist"));
+ clearstatcache();
+ $this->assertFileNotExists("$dir/this/does/not/exist");
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+ }
+
+
+ function test_empty_single(){
+ // set up test dir
+ $dir = io_mktmpdir();
+ $top = dirname($dir);
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+
+ // delete successfully
+ $this->assertTrue(io_rmdir($dir, false));
+
+ // check result
+ clearstatcache();
+ $this->assertFalse(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ // same again with deletefiles
+
+ // set up test dir
+ $dir = io_mktmpdir();
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+
+ // delete successfully
+ $this->assertTrue(io_rmdir($dir, true));
+
+ // check result
+ clearstatcache();
+ $this->assertFalse(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+ }
+
+
+ function test_empty_hierarchy(){
+ // setup hierachy and test it exists
+ $dir = io_mktmpdir();
+ $top = dirname($dir);
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(io_mkdir_p("$dir/foo/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foo/bar/baz"));
+ $this->assertTrue(io_mkdir_p("$dir/foobar/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foobar/bar/baz"));
+
+ // delete successfully
+ $this->assertTrue(io_rmdir($dir, false));
+
+ // check result
+ clearstatcache();
+ $this->assertFalse(is_dir("$dir/foo/bar/baz"));
+ $this->assertFalse(is_dir("$dir/foobar/bar/baz"));
+ $this->assertFalse(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ // same again with deletefiles
+
+ // setup hierachy and test it exists
+ $dir = io_mktmpdir();
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(io_mkdir_p("$dir/foo/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foo/bar/baz"));
+ $this->assertTrue(io_mkdir_p("$dir/foobar/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foobar/bar/baz"));
+
+ // delete successfully
+ $this->assertTrue(io_rmdir($dir, true));
+
+ // check result
+ clearstatcache();
+ $this->assertFalse(is_dir("$dir/foo/bar/baz"));
+ $this->assertFalse(is_dir("$dir/foobar/bar/baz"));
+ $this->assertFalse(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+ }
+
+ function test_full_single(){
+ // set up test dir
+ $dir = io_mktmpdir();
+ $top = dirname($dir);
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+
+ // put file
+ $this->assertTrue(io_saveFile("$dir/testfile.txt", 'foobar'));
+ $this->assertFileExists("$dir/testfile.txt");
+
+ // delete unsuccessfully
+ $this->assertFalse(io_rmdir($dir, false));
+
+ // check result
+ clearstatcache();
+ $this->assertFileExists("$dir/testfile.txt");
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ // same again with deletefiles
+
+ // delete successfully
+ $this->assertTrue(io_rmdir($dir, true));
+
+ // check result
+ clearstatcache();
+ $this->assertFileNotExists("$dir/testfile.txt");
+ $this->assertFalse(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+ }
+
+ function test_full_hierarchy(){
+ // setup hierachy and test it exists
+ $dir = io_mktmpdir();
+ $top = dirname($dir);
+ $this->assertTrue($dir !== false);
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(io_mkdir_p("$dir/foo/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foo/bar/baz"));
+ $this->assertTrue(io_mkdir_p("$dir/foobar/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foobar/bar/baz"));
+
+ // put files
+ $this->assertTrue(io_saveFile("$dir/testfile.txt", 'foobar'));
+ $this->assertFileExists("$dir/testfile.txt");
+ $this->assertTrue(io_saveFile("$dir/foo/testfile.txt", 'foobar'));
+ $this->assertFileExists("$dir/foo/testfile.txt");
+ $this->assertTrue(io_saveFile("$dir/foo/bar/baz/testfile.txt", 'foobar'));
+ $this->assertFileExists("$dir/foo/bar/baz/testfile.txt");
+
+ // delete unsuccessfully
+ $this->assertFalse(io_rmdir($dir, false));
+
+ // check result
+ clearstatcache();
+ $this->assertFileExists("$dir/testfile.txt");
+ $this->assertFileExists("$dir/foo/testfile.txt");
+ $this->assertFileExists("$dir/foo/bar/baz/testfile.txt");
+ $this->assertTrue(is_dir("$dir/foo/bar/baz"));
+ $this->assertTrue(is_dir("$dir/foobar/bar/baz"));
+ $this->assertTrue(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+
+ // delete successfully
+ $this->assertTrue(io_rmdir($dir, true));
+
+ // check result
+ clearstatcache();
+ $this->assertFileNotExists("$dir/testfile.txt");
+ $this->assertFileNotExists("$dir/foo/testfile.txt");
+ $this->assertFileNotExists("$dir/foo/bar/baz/testfile.txt");
+ $this->assertFalse(is_dir("$dir/foo/bar/baz"));
+ $this->assertFalse(is_dir("$dir/foobar/bar/baz"));
+ $this->assertFalse(is_dir($dir));
+ $this->assertTrue(is_dir($top));
+ }
+
+} \ No newline at end of file
diff --git a/inc/io.php b/inc/io.php
index eff0279ac..892f93759 100644
--- a/inc/io.php
+++ b/inc/io.php
@@ -401,6 +401,56 @@ function io_mkdir_p($target){
}
/**
+ * Recursively delete a directory
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $path
+ * @param bool $removefiles defaults to false which will delete empty directories only
+ * @return bool
+ */
+function io_rmdir($path, $removefiles = false) {
+ if(!is_string($path) || $path == "") return false;
+ if(!file_exists($path)) return true; // it's already gone or was never there, count as success
+
+ if(is_dir($path) && !is_link($path)) {
+ $dirs = array();
+ $files = array();
+
+ if(!$dh = @opendir($path)) return false;
+ while($f = readdir($dh)) {
+ if($f == '..' || $f == '.') continue;
+
+ // collect dirs and files first
+ if(is_dir("$path/$f") && !is_link("$path/$f")) {
+ $dirs[] = "$path/$f";
+ } else if($removefiles) {
+ $files[] = "$path/$f";
+ } else {
+ return false; // abort when non empty
+ }
+
+ }
+ closedir($dh);
+
+ // now traverse into directories first
+ foreach($dirs as $dir) {
+ if(!io_rmdir($dir, $removefiles)) return false; // abort on any error
+ }
+
+ // now delete files
+ foreach($files as $file) {
+ if(!@unlink($file)) return false; //abort on any error
+ }
+
+ // remove self
+ return @rmdir($path);
+ } else if($removefiles) {
+ return @unlink($path);
+ }
+ return false;
+}
+
+/**
* Creates a directory using FTP
*
* This is used when the safemode workaround is enabled