Skip to content

Commit

Permalink
Update delete_files() helper function. Fixes #3015
Browse files Browse the repository at this point in the history
  • Loading branch information
michalsn committed Jun 24, 2020
1 parent e9de841 commit 24ea615
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 18 deletions.
41 changes: 25 additions & 16 deletions system/Helpers/filesystem_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,39 +160,48 @@ function write_file(string $path, string $data, string $mode = 'wb'): bool
* @param string $path File path
* @param boolean $del_dir Whether to delete any directories found in the path
* @param boolean $htdocs Whether to skip deleting .htaccess and index page files
* @param integer $_level Current directory depth level (default: 0; internal use only)
* @param boolean $hidden Whether to include hidden files (files beginning with a period)
*
* @return boolean
*/
function delete_files(string $path, bool $del_dir = false, bool $htdocs = false, int $_level = 0): bool
function delete_files(string $path, bool $del_dir = false, bool $htdocs = false, bool $hidden = false): bool
{
// Trim the trailing slash
$path = rtrim($path, '/\\');
$path = realpath($path) ?: $path;
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

try
{
$current_dir = opendir($path);

while (false !== ($filename = @readdir($current_dir)))
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
) as $object)
{
if ($filename !== '.' && $filename !== '..')
$filename = $object->getFilename();

if (! $hidden && $filename[0] === '.')
{
continue;
}
elseif (! $htdocs || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename))
{
if (is_dir($path . DIRECTORY_SEPARATOR . $filename) && $filename[0] !== '.')
$isDir = $object->isDir();

if ($isDir && $del_dir)
{
delete_files($path . DIRECTORY_SEPARATOR . $filename, $del_dir, $htdocs, $_level + 1);
@rmdir($object->getPathname());
continue;
}
elseif ($htdocs !== true || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename))

if (! $isDir)
{
@unlink($path . DIRECTORY_SEPARATOR . $filename);
@unlink($object->getPathname());
}
}
}

closedir($current_dir);

return ($del_dir === true && $_level > 0) ? @rmdir($path) : true;
return true;
}
catch (\Exception $fe)
catch (\Exception $e)
{
return false;
}
Expand Down
27 changes: 25 additions & 2 deletions tests/system/Helpers/FilesystemHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public function testDeleteFilesDefaultsToOneLevelDeep()
delete_files(vfsStream::url('root'));

$this->assertFalse($vfs->hasChild('simpleFile'));
$this->assertFalse($vfs->hasChild('.hidden'));
$this->assertTrue($vfs->hasChild('.hidden'));
$this->assertTrue($vfs->hasChild('foo'));
$this->assertTrue($vfs->hasChild('boo'));
$this->assertTrue($vfs->hasChild('AnEmptyFolder'));
Expand All @@ -143,7 +143,7 @@ public function testDeleteFilesHandlesRecursion()
delete_files(vfsStream::url('root'), true);

$this->assertFalse($vfs->hasChild('simpleFile'));
$this->assertFalse($vfs->hasChild('.hidden'));
$this->assertTrue($vfs->hasChild('.hidden'));
$this->assertFalse($vfs->hasChild('foo'));
$this->assertFalse($vfs->hasChild('boo'));
$this->assertFalse($vfs->hasChild('AnEmptyFolder'));
Expand All @@ -162,6 +162,29 @@ public function testDeleteFilesLeavesHTFiles()
delete_files(vfsStream::url('root'), true, true);

$this->assertFalse($vfs->hasChild('simpleFile'));
$this->assertTrue($vfs->hasChild('.hidden'));
$this->assertFalse($vfs->hasChild('foo'));
$this->assertFalse($vfs->hasChild('boo'));
$this->assertFalse($vfs->hasChild('AnEmptyFolder'));
$this->assertTrue($vfs->hasChild('.htaccess'));
$this->assertTrue($vfs->hasChild('index.html'));
$this->assertTrue($vfs->hasChild('index.php'));
}

public function testDeleteFilesIncludingHidden()
{
$structure = array_merge($this->structure, [
'.htaccess' => 'Deny All',
'index.html' => 'foo',
'index.php' => 'blah',
]);

$vfs = vfsStream::setup('root', null, $structure);

delete_files(vfsStream::url('root'), true, true, true);

$this->assertFalse($vfs->hasChild('simpleFile'));
$this->assertFalse($vfs->hasChild('.hidden'));
$this->assertFalse($vfs->hasChild('foo'));
$this->assertFalse($vfs->hasChild('boo'));
$this->assertFalse($vfs->hasChild('AnEmptyFolder'));
Expand Down

0 comments on commit 24ea615

Please sign in to comment.