rework FileDir::makePathfield() is mode is 'dropdown' to show all directories correctly (depth limited); fixes #1044

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2022-07-07 14:45:50 +02:00
parent a7b91eb1ed
commit e6a6f6f9de

View File

@@ -1,4 +1,5 @@
<?php <?php
namespace Froxlor; namespace Froxlor;
use Froxlor\Database\Database; use Froxlor\Database\Database;
@@ -96,14 +97,14 @@ class FileDir
$subdir = self::makeCorrectDir($subdir); $subdir = self::makeCorrectDir($subdir);
$subdirs = array(); $subdirs = array();
if ($within_homedir || ! $allow_notwithinhomedir) { if ($within_homedir || !$allow_notwithinhomedir) {
$subdirlen = strlen($subdir); $subdirlen = strlen($subdir);
$offset = 0; $offset = 0;
while ($offset < $subdirlen) { while ($offset < $subdirlen) {
$offset = strpos($subdir, '/', $offset); $offset = strpos($subdir, '/', $offset);
$subdirelem = substr($subdir, 0, $offset); $subdirelem = substr($subdir, 0, $offset);
$offset ++; $offset++;
array_push($subdirs, self::makeCorrectDir($homeDir . $subdirelem)); array_push($subdirs, self::makeCorrectDir($homeDir . $subdirelem));
} }
} else { } else {
@@ -113,7 +114,7 @@ class FileDir
$subdirs = array_unique($subdirs); $subdirs = array_unique($subdirs);
sort($subdirs); sort($subdirs);
foreach ($subdirs as $sdir) { foreach ($subdirs as $sdir) {
if (! is_dir($sdir)) { if (!is_dir($sdir)) {
$sdir = self::makeCorrectDir($sdir); $sdir = self::makeCorrectDir($sdir);
self::safe_exec('mkdir -p ' . escapeshellarg($sdir)); self::safe_exec('mkdir -p ' . escapeshellarg($sdir));
// place index // place index
@@ -247,7 +248,7 @@ class FileDir
*/ */
public static function makeCorrectFile($filename) public static function makeCorrectFile($filename)
{ {
if (! isset($filename) || trim($filename) == '') { if (!isset($filename) || trim($filename) == '') {
$error = 'Given filename for function ' . __FUNCTION__ . ' is empty.' . "\n"; $error = 'Given filename for function ' . __FUNCTION__ . ' is empty.' . "\n";
$error .= 'This is very dangerous and should not happen.' . "\n"; $error .= 'This is very dangerous and should not happen.' . "\n";
$error .= 'Please inform the Froxlor team about this issue so they can fix it.'; $error .= 'Please inform the Froxlor team about this issue so they can fix it.';
@@ -278,7 +279,7 @@ class FileDir
{ {
if (is_string($dir) && strlen($dir) > 0) { if (is_string($dir) && strlen($dir) > 0) {
$dir = trim($dir); $dir = trim($dir);
if (substr($dir, - 1, 1) != '/') { if (substr($dir, -1, 1) != '/') {
$dir .= '/'; $dir .= '/';
} }
if (substr($dir, 0, 1) != '/') { if (substr($dir, 0, 1) != '/') {
@@ -355,7 +356,7 @@ class FileDir
$destination = substr($destination, 1); $destination = substr($destination, 1);
} }
if (substr($destination, - 1, 1) == ' ') { if (substr($destination, -1, 1) == ' ') {
$destination = substr($destination, 0, strlen($destination) - 1); $destination = substr($destination, 0, strlen($destination) - 1);
} }
@@ -390,7 +391,7 @@ class FileDir
// but dirList holds the paths with starting slash // but dirList holds the paths with starting slash
// so we just add one here to get the correct // so we just add one here to get the correct
// default path selected, #225 // default path selected, #225
if (substr($value, 0, 1) != '/' && ! $dom) { if (substr($value, 0, 1) != '/' && !$dom) {
$value = '/' . $value; $value = '/' . $value;
} }
@@ -408,34 +409,22 @@ class FileDir
natcasesort($dirList); natcasesort($dirList);
if (sizeof($dirList) > 0) { if (sizeof($dirList) > 0) {
if (sizeof($dirList) <= 100) { $_field = '';
$_field = ''; foreach ($dirList as $dir) {
foreach ($dirList as $dir) { if (strpos($dir, $path) === 0) {
if (strpos($dir, $path) === 0) { $dir = substr($dir, strlen($path));
$dir = substr($dir, strlen($path)); // docroot cut off of current directory == empty -> directory is the docroot
// docroot cut off of current directory == empty -> directory is the docroot if (empty($dir)) {
if (empty($dir)) { $dir = '/';
$dir = '/';
}
$dir = self::makeCorrectDir($dir);
} }
$_field .= \Froxlor\UI\HTML::makeoption($dir, $dir, $value); $dir = self::makeCorrectDir($dir);
} }
$field = array( $_field .= \Froxlor\UI\HTML::makeoption($dir, $dir, $value);
'type' => 'select',
'value' => $_field
);
} else {
// remove starting slash we added
// for the Dropdown, #225
$value = substr($value, 1);
// $field = $lng['panel']['toomanydirs'];
$field = array(
'type' => 'text',
'value' => htmlspecialchars($value),
'note' => $lng['panel']['toomanydirs']
);
} }
$field = array(
'type' => 'select',
'value' => $_field
);
} else { } else {
// $field = $lng['panel']['dirsmissing']; // $field = $lng['panel']['dirsmissing'];
// $field = '<input type="hidden" name="path" value="/" />'; // $field = '<input type="hidden" name="path" value="/" />';
@@ -489,22 +478,31 @@ class FileDir
$filter = function ($file, $key, $iterator) use ($exclude) { $filter = function ($file, $key, $iterator) use ($exclude) {
if (in_array($file->getFilename(), $exclude)) { if (in_array($file->getFilename(), $exclude)) {
return false; return false;
} elseif (substr($file->getFilename(), 0, 1) == '.') {
// also hide hidden folders
return false;
} }
return true; return true;
}; };
// create RecursiveIteratorIterator // create RecursiveIteratorIterator
$its = new \RecursiveIteratorIterator(new \RecursiveCallbackFilterIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), $filter)); $its = new \RecursiveIteratorIterator(
new \RecursiveCallbackFilterIterator(
new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
$filter
),
\RecursiveIteratorIterator::LEAVES_ONLY,
\RecursiveIteratorIterator::CATCH_GET_CHILD
);
// we can limit the recursion-depth, but will it be helpful or // we can limit the recursion-depth, but will it be helpful or
// will people start asking "why do I only see 2 subdirectories, i want to use /a/b/c" // will people start asking "why do I only see 2 subdirectories, i want to use /a/b/c"
// let's keep this in mind and see whether it will be useful // let's keep this in mind and see whether it will be useful
// @TODO $its->setMaxDepth(2);
// $its->setMaxDepth(2);
// check every file // check every file
foreach ($its as $fullFileName => $it) { foreach ($its as $fullFileName => $it) {
if ($it->isDir() && (fileowner($fullFileName) == $uid || filegroup($fullFileName) == $gid)) { if ($it->isDir() && (fileowner($fullFileName) == $uid || filegroup($fullFileName) == $gid)) {
$_fileList[] = self::makeCorrectDir(dirname($fullFileName)); $_fileList[] = self::makeCorrectDir($fullFileName);
} }
} }
$_fileList[] = $path; $_fileList[] = $path;
@@ -525,7 +523,7 @@ class FileDir
*/ */
public static function isFreeBSD($exact = false) public static function isFreeBSD($exact = false)
{ {
if (($exact && PHP_OS == 'FreeBSD') || (! $exact && stristr(PHP_OS, 'BSD'))) { if (($exact && PHP_OS == 'FreeBSD') || (!$exact && stristr(PHP_OS, 'BSD'))) {
return true; return true;
} }
return false; return false;