parseCleanURL(); $currentPath = ltrim($currentPath, '/'); $currentPath = str_replace(['../', './'], '', $currentPath); $fullPath = $baseDir . '/' . $currentPath; $webCurrentPath = '/files' . ($currentPath ? '/' . $currentPath : ''); $indexerFilesDir = $scriptDir . '/.indexer_files'; $zipCacheDir = $indexerFilesDir . '/zip_cache'; $indexCacheDir = $indexerFilesDir . '/index_cache'; $iconsDir = $indexerFilesDir . '/icons'; $localApiDir = $indexerFilesDir . '/local_api'; $localStyleDir = $localApiDir . '/style'; $configFile = $indexerFilesDir . '/config.json'; $localExtensionMapFile = $localApiDir . '/extensionMap.json'; $localIconsFile = $localApiDir . '/icons.json'; $config = loadConfiguration(); $cacheType = isset($config['main']['cache_type']) ? $config['main']['cache_type'] : 'sqlite'; $disableFileDownloads = isset($config['main']['disable_file_downloads']) ? $config['main']['disable_file_downloads'] : false; $disableFolderDownloads = isset($config['main']['disable_folder_downloads']) ? $config['main']['disable_folder_downloads'] : false; $iconType = isset($config['main']['icon_type']) ? $config['main']['icon_type'] : 'default'; $denyList = parseDenyAllowList(isset($config['main']['deny_list']) ? $config['main']['deny_list'] : ''); $allowList = parseDenyAllowList(isset($config['main']['allow_list']) ? $config['main']['allow_list'] : ''); $conflictingRules = findConflictingRules($denyList, $allowList); $cacheInstance = initializeCache(); runCacheCleanup(); if (!empty($currentPath)) { if ($router->isFileRequest($currentPath)) { $router->handleFileRequest($currentPath); exit; } if ($router->isFolderRequest($currentPath)) { if (isset($_GET['download']) && $_GET['download'] === 'archive') { $router->handleFolderRequest($currentPath); exit; } $router->handleFolderRequest($currentPath); } else { http_response_code(404); exit('Path not found'); } } function parseDenyAllowList($listString) { if (empty(trim($listString))) { return []; } $items = array_map('trim', explode(',', $listString)); $parsedList = []; foreach ($items as $item) { if (empty($item)) continue; $rule = [ 'original' => $item, 'path' => '', 'type' => 'exact', 'target' => 'both' ]; if (substr($item, -2) === '/*') { $rule['type'] = 'folder_recursive'; $rule['path'] = substr($item, 0, -2); $rule['target'] = 'folder'; } elseif (substr($item, -1) === '*' && substr($item, -2) !== '/*') { if (strpos($item, '.') !== false && strrpos($item, '.') > strrpos($item, '/')) { $rule['type'] = 'wildcard'; $rule['path'] = $item; $rule['target'] = 'file'; } else { $rule['type'] = 'wildcard'; $rule['path'] = substr($item, 0, -1); $rule['target'] = 'folder'; } } elseif (strpos($item, '*') !== false) { $rule['type'] = 'wildcard'; $rule['path'] = $item; $rule['target'] = 'file'; } else { $rule['type'] = 'exact'; $rule['path'] = $item; if (strpos(basename($item), '.') !== false) { $rule['target'] = 'file'; } else { $rule['target'] = 'folder'; } } $parsedList[] = $rule; } return $parsedList; } function findConflictingRules($denyList, $allowList) { $conflicts = []; foreach ($denyList as $denyRule) { foreach ($allowList as $allowRule) { if ($denyRule['path'] === $allowRule['path'] && $denyRule['type'] === $allowRule['type']) { $conflicts[] = [ 'deny' => $denyRule['original'], 'allow' => $allowRule['original'] ]; } } } return $conflicts; } function pathMatchesRule($relativePath, $rule, $isFolder = false) { $rulePath = $rule['path']; if ($rule['type'] === 'exact') { return $relativePath === $rulePath; } if ($rule['type'] === 'wildcard') { if ($rule['target'] === 'file' && !$isFolder) { if (strpos($rulePath, '/') !== false) { $lastSlashPos = strrpos($rulePath, '/'); $directory = substr($rulePath, 0, $lastSlashPos); $pattern = substr($rulePath, $lastSlashPos + 1); $fileDir = dirname($relativePath); $fileName = basename($relativePath); $directory = rtrim($directory, '/'); $fileDir = rtrim($fileDir, '/'); if ($fileDir === $directory) { if (strpos($pattern, '.') === 0) { $extension = substr($pattern, 1, -1); $fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); return $fileExtension === $extension; } else { $regexPattern = str_replace('*', '.*', preg_quote($pattern, '/')); return preg_match('/^' . $regexPattern . '$/i', $fileName); } } } } elseif ($rule['target'] === 'folder') { if ($isFolder) { $pathParts = explode('/', $relativePath); $topLevelFolder = $pathParts[0]; if (count($pathParts) === 1 && strpos($topLevelFolder, $rulePath) === 0) { return true; } return false; } else { $fileDir = dirname($relativePath); if ($fileDir === '.') $fileDir = ''; if (strpos($fileDir, '/') === false) { return strpos($fileDir, $rulePath) === 0; } return false; } } } if ($rule['type'] === 'folder_recursive') { if ($relativePath === $rulePath) { return true; } return strpos($relativePath, $rulePath . '/') === 0; } return false; } function isPathDenied($relativePath, $isFolder = false) { global $denyList, $conflictingRules; foreach ($denyList as $rule) { $isConflicting = false; foreach ($conflictingRules as $conflict) { if ($conflict['deny'] === $rule['original']) { $isConflicting = true; break; } } if ($isConflicting) continue; if (pathMatchesRule($relativePath, $rule, $isFolder)) { return true; } } return false; } function isPathAllowed($relativePath, $isFolder = false) { global $allowList, $conflictingRules; foreach ($allowList as $rule) { $isConflicting = false; foreach ($conflictingRules as $conflict) { if ($conflict['allow'] === $rule['original']) { $isConflicting = true; break; } } if ($isConflicting) continue; if (pathMatchesRule($relativePath, $rule, $isFolder)) { return true; } } return false; } function isContentAllowedByWildcard($relativePath, $isFolder = false) { global $allowList, $conflictingRules; foreach ($allowList as $rule) { $isConflicting = false; foreach ($conflictingRules as $conflict) { if ($conflict['allow'] === $rule['original']) { $isConflicting = true; break; } } if ($isConflicting) continue; if ($rule['type'] === 'wildcard' && $rule['target'] === 'folder') { if (strpos($relativePath, $rule['path']) === 0) { return true; } } } return false; } function isFolderAccessible($currentPath) { global $denyList, $allowList, $conflictingRules, $config; if (isset($config['main']['index_all']) && $config['main']['index_all']) { return true; } foreach ($allowList as $rule) { $isConflicting = false; foreach ($conflictingRules as $conflict) { if ($conflict['allow'] === $rule['original']) { $isConflicting = true; break; } } if ($isConflicting) continue; if (pathMatchesRule($currentPath, $rule, true)) { return true; } } foreach ($denyList as $rule) { $isConflicting = false; foreach ($conflictingRules as $conflict) { if ($conflict['deny'] === $rule['original']) { $isConflicting = true; break; } } if ($isConflicting) continue; if ($rule['type'] === 'folder_recursive') { if ($currentPath === $rule['path'] || strpos($currentPath, $rule['path'] . '/') === 0) { return false; } } elseif ($rule['type'] === 'wildcard' && $rule['target'] === 'folder') { $pathParts = explode('/', $currentPath); $topLevelFolder = $pathParts[0]; if (strpos($topLevelFolder, $rule['path']) === 0) { if ($currentPath === $topLevelFolder) { return false; } } } elseif ($rule['type'] === 'exact') { if ($currentPath === $rule['path']) { return false; } } } return true; } function shouldIndexFile($filename, $extension) { global $config, $currentPath; $relativePath = $currentPath ? $currentPath . '/' . basename($filename) : basename($filename); if (empty($extension) || trim($extension) === '') { $indexNonDescript = isset($config['exclusions']['index_non-descript-files']) ? $config['exclusions']['index_non-descript-files'] : true; if (!$indexNonDescript) { return false; } if (isPathDenied($relativePath, false)) { if (isPathAllowed($relativePath, false)) { return true; } return false; } if (isContentAllowedByWildcard($relativePath, false)) { return true; } if (isPathAllowed($relativePath, false)) { return true; } if (isset($config['main']['index_all']) && $config['main']['index_all']) { return true; } if (strpos(basename($filename), '.') === 0) { if (!isset($config['main']['index_hidden']) || !$config['main']['index_hidden']) { return false; } } return true; } if (isPathDenied($relativePath, false)) { if (isPathAllowed($relativePath, false)) { return true; } return false; } if (isContentAllowedByWildcard($relativePath, false)) { return true; } if (isPathAllowed($relativePath, false)) { return true; } if (isset($config['main']['index_all']) && $config['main']['index_all']) { return true; } if (strpos(basename($filename), '.') === 0) { if (!isset($config['main']['index_hidden']) || !$config['main']['index_hidden']) { return false; } } $settingKey = getExtensionSetting($extension, 'indexing'); if ($settingKey !== null) { return isset($config['exclusions'][$settingKey]) ? $config['exclusions'][$settingKey] : true; } return true; } function shouldIndexFolder($foldername) { global $config, $currentPath; $relativePath = $currentPath ? $currentPath . '/' . basename($foldername) : basename($foldername); if (basename($foldername) === '.indexer_files') { if (isset($config['main']['index_all']) && $config['main']['index_all']) { return true; } return false; } if (isPathDenied($relativePath, true)) { if (isPathAllowed($relativePath, true)) { return true; } return false; } if (isContentAllowedByWildcard($relativePath, true)) { return true; } if (isPathAllowed($relativePath, true)) { return true; } if (isset($config['main']['index_all']) && $config['main']['index_all']) { return true; } if (strpos(basename($foldername), '.') === 0) { if (!isset($config['main']['index_hidden']) || !$config['main']['index_hidden']) { return false; } } return isset($config['exclusions']['index_folders']) ? $config['exclusions']['index_folders'] : true; } function isFileAccessible($filePath, $currentPath, $extension) { global $config, $disableFileDownloads; if (!isFolderAccessible($currentPath)) { return false; } $fileName = basename($filePath); $relativePath = $currentPath ? $currentPath . '/' . $fileName : $fileName; if (isPathDenied($relativePath, false)) { if (!isPathAllowed($relativePath, false)) { return false; } } if (!shouldIndexFile($filePath, $extension)) { return false; } return true; } function loadConfiguration() { global $configFile; if (file_exists($configFile)) { $configData = json_decode(file_get_contents($configFile), true); if ($configData !== null) { return $configData; } } return []; } function getExtensionSetting($extension, $type = 'indexing') { if (empty($extension) || trim($extension) === '') { if ($type === 'indexing') { return 'index_non-descript-files'; } elseif ($type === 'viewing') { return 'view_non-descript-files'; } return null; } $extensionMappings = loadLocalExtensionMappings(); if ($extensionMappings === null) { return null; } $extension = strtolower($extension); if ($type === 'indexing' && isset($extensionMappings['indexing'][$extension])) { return $extensionMappings['indexing'][$extension]; } elseif ($type === 'viewing' && isset($extensionMappings['viewing'][$extension])) { return $extensionMappings['viewing'][$extension]; } return null; } function loadLocalExtensionMappings() { global $localExtensionMapFile; if (!file_exists($localExtensionMapFile)) { return null; } $mappingData = file_get_contents($localExtensionMapFile); $mappings = json_decode($mappingData, true); return $mappings ?: null; } function loadLocalIconMappings() { global $localIconsFile; if (!file_exists($localIconsFile)) { return []; } $mappingData = file_get_contents($localIconsFile); $mappings = json_decode($mappingData, true); return $mappings ?: []; } function getIconPath($type, $extension = '') { global $webPath, $iconsDir, $iconType, $scriptDir; if ($iconType === 'disabled') { return null; } if ($iconType === 'emoji') { return null; } if ($iconType === 'minimal') { $iconFilename = ($type === 'folder') ? 'folder.png' : 'non-descript-default-file.png'; $iconPath = $iconsDir . '/' . $iconFilename; if (file_exists($iconPath)) { $relativePath = str_replace($scriptDir, '', $iconPath); return $webPath . $relativePath; } return null; } if ($iconType === 'default') { if ($type === 'folder') { $iconInfo = getIconFromLocal($type, $extension); if ($iconInfo !== null) { $relativePath = str_replace($scriptDir, '', $iconInfo['path']); return $webPath . $relativePath; } } if ($type === 'file') { if (empty($extension) || trim($extension) === '') { $iconFilename = 'non-descript-default-file.png'; $iconPath = $iconsDir . '/' . $iconFilename; if (file_exists($iconPath)) { $relativePath = str_replace($scriptDir, '', $iconPath); return $webPath . $relativePath; } return null; } $iconMappings = loadLocalIconMappings(); if ($iconMappings && is_array($iconMappings)) { $extension = strtolower($extension); if (!isset($iconMappings[$extension])) { $iconFilename = 'non-descript-default-file.png'; $iconPath = $iconsDir . '/' . $iconFilename; if (file_exists($iconPath)) { $relativePath = str_replace($scriptDir, '', $iconPath); return $webPath . $relativePath; } return null; } } $iconInfo = getIconFromLocal($type, $extension); if ($iconInfo !== null) { $relativePath = str_replace($scriptDir, '', $iconInfo['path']); return $webPath . $relativePath; } } } return null; } function getIconFromLocal($type, $extension = '') { global $iconsDir; $iconMappings = loadLocalIconMappings(); if ($type === 'folder') { $iconFile = isset($iconMappings['folder']) ? $iconMappings['folder'] : 'folder.png'; } else { $extension = strtolower($extension); $iconFile = isset($iconMappings[$extension]) ? $iconMappings[$extension] : 'non-descript-default-file.png'; } $iconPath = $iconsDir . '/' . $iconFile; if (!file_exists($iconPath)) { if ($type === 'folder') { $iconFile = 'folder.png'; } else { $iconFile = 'non-descript-default-file.png'; } $iconPath = $iconsDir . '/' . $iconFile; if (!file_exists($iconPath)) { return null; } } return [ 'filename' => $iconFile, 'path' => $iconPath, 'size' => filesize($iconPath), 'last_modified' => filemtime($iconPath) ]; } function isFileViewable($extension) { global $config; if (empty($extension) || trim($extension) === '') { $viewNonDescript = isset($config['viewable_files']['view_non-descript-files']) ? $config['viewable_files']['view_non-descript-files'] : false; return $viewNonDescript; } $settingKey = getExtensionSetting($extension, 'viewing'); if ($settingKey !== null) { return isset($config['viewable_files'][$settingKey]) ? $config['viewable_files'][$settingKey] : false; } return false; } function cleanupOldTempFiles() { global $zipCacheDir; if (!is_dir($zipCacheDir)) return; $files = glob($zipCacheDir . '/*'); $fiveMinutesAgo = time() - 300; foreach ($files as $file) { if (filemtime($file) < $fiveMinutesAgo) { if (is_dir($file)) { deleteDirectory($file); } else { unlink($file); } } } } function deleteDirectory($dir) { if (!is_dir($dir)) return; $files = glob($dir . '/*'); foreach ($files as $file) { if (is_dir($file)) { deleteDirectory($file); } else { unlink($file); } } rmdir($dir); } function getDirectorySize($path) { $size = 0; if (is_dir($path)) { $files = scandir($path); foreach ($files as $file) { if ($file == '.' || $file == '..') continue; $filePath = $path . '/' . $file; if (is_dir($filePath)) { $size += getDirectorySize($filePath); } else { $size += filesize($filePath); } } } return $size; } $cacheInstance = null; function initializeCache() { global $cacheInstance, $cacheType, $indexCacheDir; if ($cacheInstance === null) { $cacheInstance = new IndexerCache($cacheType, $indexCacheDir); } return $cacheInstance; } function getCacheData($path) { $cache = initializeCache(); return $cache->get($path, 'directory'); } function setCacheData($path, $data) { $cache = initializeCache(); $cache->set($path, 'directory', $data); } function runCacheCleanup() { $cache = initializeCache(); $cache->cleanup(); } function copyDirectoryExcludePhp($source, $destination) { global $currentPath; if (!is_dir($source)) return false; if (!is_dir($destination)) { mkdir($destination, 0755, true); } $files = scandir($source); foreach ($files as $file) { if ($file == '.' || $file == '..') continue; $sourcePath = $source . '/' . $file; $destPath = $destination . '/' . $file; if (is_dir($sourcePath)) { if (shouldIndexFolder($sourcePath)) { copyDirectoryExcludePhp($sourcePath, $destPath); } } else { $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (shouldIndexFile($sourcePath, $extension)) { copy($sourcePath, $destPath); } } } return true; } function addDirectoryToZip($zip, $dir, $zipPath = '') { $files = scandir($dir); foreach ($files as $file) { if ($file == '.' || $file == '..') continue; $filePath = $dir . '/' . $file; $zipFilePath = $zipPath ? $zipPath . '/' . $file : $file; if (is_dir($filePath)) { $zip->addEmptyDir($zipFilePath); addDirectoryToZip($zip, $filePath, $zipFilePath); } else { $zip->addFile($filePath, $zipFilePath); } } } function getFileUrl($path, $filename) { global $router, $disableFileDownloads; $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if (isFileViewable($extension)) { return $router->generateFileURL($path, $filename, 'view', 'default'); } else { if ($disableFileDownloads) { return '#'; } return $router->generateFileURL($path, $filename, 'download'); } } function getSortUrl($sortBy, $currentSort, $currentDir, $currentPath) { global $router; return $router->generateSortURL($sortBy, $currentSort, $currentDir, $currentPath); } function getBreadcrumbs($currentPath) { global $router; return $router->generateBreadcrumbs($currentPath); } function getBaseUrl($currentPath, $webPath) { if (empty($currentPath)) { return $webPath . '/'; } else { return $webPath . '/' . $currentPath . '/'; } } function generateSharePopup($shareType, $shareFile, $currentPath) { global $router, $webPath; if ($shareType === 'view') { if (is_dir($GLOBALS['fullPath'] . '/' . $shareFile)) { $shareUrl = $router->generateFolderURL($currentPath, $shareFile, 'view'); $popupTitle = 'Share Folder Link'; $popupText = 'Copy the following URL to share folder'; } else { $shareUrl = $router->generateFileURL($currentPath, $shareFile, 'view', 'default'); $popupTitle = 'Share File Link'; $popupText = 'Copy the following URL to view file'; } } elseif ($shareType === 'folder') { $shareUrl = $router->generateFolderURL($currentPath, '', 'view'); $popupTitle = 'Share Folder Location'; $popupText = 'Copy the following URL to share the folder containing'; } elseif ($shareType === 'download') { $isFolder = is_dir($GLOBALS['fullPath'] . '/' . $shareFile); if ($isFolder) { $shareUrl = $router->generateFolderURL($currentPath, $shareFile, 'download'); } else { $shareUrl = $router->generateFileURL($currentPath, $shareFile, 'download'); } $popupTitle = 'Share Download Link'; $popupText = 'Copy the following URL to download'; } $absoluteShareUrl = getAbsoluteUrl($shareUrl); $closeParams = $_GET; unset($closeParams['share_popup']); unset($closeParams['share_file']); $closeUrl = $router->generateFolderURL($currentPath, '', 'view'); if ($closeParams) { $closeUrl .= '?' . http_build_query($closeParams); } return '
'; } function getFileActionMenu($file, $currentPath) { global $disableFileDownloads, $router, $webPath; $extension = $file['extension']; $fileName = $file['name']; $isViewable = isFileViewable($extension); $showActions = isset($_GET['action']) && $_GET['action'] === $fileName; $menu = ' '; return $menu; } function getFolderActionMenu($folder, $currentPath) { global $disableFolderDownloads, $router, $webPath; $folderName = $folder['name']; $showActions = isset($_GET['action']) && $_GET['action'] === $folderName; $menu = ' '; return $menu; } function formatBytes($size) { if ($size === null) return '-'; $units = ['B', 'KB', 'MB', 'GB']; for ($i = 0; $size > 1024 && $i < count($units) - 1; $i++) { $size /= 1024; } return round($size, 1) . ' ' . $units[$i]; } function getSortParams() { $sortBy = $_GET['sort'] ?? 'name'; $sortDir = $_GET['dir'] ?? 'asc'; $validSorts = ['name', 'size', 'modified', 'type']; $validDirs = ['asc', 'desc']; if (!in_array($sortBy, $validSorts)) $sortBy = 'name'; if (!in_array($sortDir, $validDirs)) $sortDir = 'asc'; return ['sort' => $sortBy, 'dir' => $sortDir]; } function sortItems($items, $sortBy, $sortDir) { usort($items, function($a, $b) use ($sortBy, $sortDir) { $result = 0; switch ($sortBy) { case 'name': $result = strcasecmp($a['name'], $b['name']); break; case 'size': $result = $a['size'] <=> $b['size']; break; case 'modified': $result = $a['modified'] <=> $b['modified']; break; case 'type': $aExt = isset($a['extension']) ? $a['extension'] : ($a['is_dir'] ? 'folder' : ''); $bExt = isset($b['extension']) ? $b['extension'] : ($b['is_dir'] ? 'folder' : ''); $result = strcasecmp($aExt, $bExt); break; } return $sortDir === 'desc' ? -$result : $result; }); return $items; } function getSortIndicator($column, $currentSort, $currentDir) { if ($column !== $currentSort) { return ''; } return $currentDir === 'asc' ? ' ↑' : ' ↓'; } function parseMarkdown($text) { $text = str_replace(["\r\n", "\r"], "\n", $text); $codeBlocks = []; $inlineCodes = []; $text = preg_replace_callback('/```([a-zA-Z0-9\-_]*)\n?(.*?)\n?```/s', function($matches) use (&$codeBlocks) { $id = count($codeBlocks); $placeholder = "XCODEBLOCKREPLACEX" . $id . "XCODEBLOCKREPLACEX"; $codeBlocks[$placeholder] = trim($matches[2]); return "\n" . $placeholder . "\n"; }, $text); $text = preg_replace_callback('/`([^`\n]+?)`/', function($matches) use (&$inlineCodes) { $id = count($inlineCodes); $placeholder = "XINLINECODEREPLACEX" . $id . "XINLINECODEREPLACEX"; $inlineCodes[$placeholder] = $matches[1]; return $placeholder; }, $text); $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); $text = preg_replace('/^###### (.+?)$/m', '$1', $text); $text = preg_replace('/^(\s*)[\*\-\+] (.+?)$/m', '$1
' . $paragraph . '
'; } } $text = implode("\n\n", $result); foreach ($codeBlocks as $placeholder => $content) { $escapedContent = htmlspecialchars($content, ENT_QUOTES, 'UTF-8'); $codeHtml = '' . $escapedContent . '
';
$text = str_replace($placeholder, $codeHtml, $text);
}
foreach ($inlineCodes as $placeholder => $content) {
$escapedContent = htmlspecialchars($content, ENT_QUOTES, 'UTF-8');
$codeHtml = '' . $escapedContent . '
';
$text = str_replace($placeholder, $codeHtml, $text);
}
return $text;
}
function getAbsoluteUrl($relativeUrl) {
global $config;
if (isset($config['main']['access_url']) && !empty($config['main']['access_url'])) {
$baseUrl = rtrim($config['main']['access_url'], '/');
if (strpos($relativeUrl, '/') === 0) {
return $baseUrl . $relativeUrl;
} else {
$currentDir = dirname($_SERVER['REQUEST_URI']);
if ($currentDir === '/' || $currentDir === '\\') {
return $baseUrl . '/' . $relativeUrl;
} else {
return $baseUrl . rtrim($currentDir, '/') . '/' . $relativeUrl;
}
}
}
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
if (strpos($relativeUrl, '/') === 0) {
return $protocol . '://' . $host . $relativeUrl;
} else {
$currentDir = dirname($_SERVER['REQUEST_URI']);
return $protocol . '://' . $host . rtrim($currentDir, '/') . '/' . $relativeUrl;
}
}
if (!is_dir($fullPath)) {
http_response_code(404);
die('Directory not found');
}
if (!isFolderAccessible($currentPath)) {
http_response_code(403);
header('Location: ' . $_SERVER['SCRIPT_NAME']);
exit;
}
$sortParams = getSortParams();
$sortBy = $sortParams['sort'];
$sortDir = $sortParams['dir'];
$cacheKey = $currentPath . '_sort_' . $sortBy . '_' . $sortDir;
$cachedData = getCacheData($cacheKey);
if ($cachedData !== null) {
$directories = $cachedData['directories'];
$files = $cachedData['files'];
} else {
$items = scandir($fullPath);
$directories = [];
$files = [];
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$itemPath = $fullPath . '/' . $item;
$itemInfo = [
'name' => $item,
'modified' => filemtime($itemPath),
'is_dir' => is_dir($itemPath)
];
if ($itemInfo['is_dir']) {
if (shouldIndexFolder(($currentPath ? $currentPath . '/' : '') . $item)) {
$itemInfo['size'] = getDirectorySize($itemPath);
$directories[] = $itemInfo;
}
} else {
$extension = strtolower(pathinfo($item, PATHINFO_EXTENSION));
if (shouldIndexFile(($currentPath ? $currentPath . '/' : '') . $item, $extension)) {
$itemInfo['size'] = filesize($itemPath);
$itemInfo['extension'] = $extension;
$files[] = $itemInfo;
}
}
}
$directories = sortItems($directories, $sortBy, $sortDir);
$files = sortItems($files, $sortBy, $sortDir);
setCacheData($cacheKey, [
'directories' => $directories,
'files' => $files
]);
}
?>