diff --git a/tinyfilemanager.php b/tinyfilemanager.php index 2c8101c..cd93465 100644 --- a/tinyfilemanager.php +++ b/tinyfilemanager.php @@ -97,7 +97,7 @@ $allowed_upload_extensions = ''; $favicon_path = ''; // Files and folders to excluded from listing -// e.g. array('myfile.html', 'personal-folder', '*.php', ...) +// e.g. array('myfile.html', 'personal-folder', '*.php', '/path/to/folder', ...) $exclude_items = array(); // Online office Docs Viewer @@ -151,6 +151,9 @@ if (is_readable($config_file)) { // External CDN resources that can be used in the HTML (replace for GDPR compliance) $external = array( + 'css-photoswipe' => '', + 'js-photoswipe-lightbox' => 'https://cdn.jsdelivr.net/npm/photoswipe@5.4.3/dist/photoswipe-lightbox.esm.js', + 'js-photoswipe-module' => 'https://cdn.jsdelivr.net/npm/photoswipe@5.4.3/dist/photoswipe.esm.js', 'css-bootstrap' => '', 'css-dropzone' => '', 'css-font-awesome' => '', @@ -459,7 +462,7 @@ unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style /*************************** ACTIONS ***************************/ // file proxy -if (isset($_GET['proxy_file'])) { +if (isset($_GET['proxy_file'])) { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET'); @@ -467,14 +470,14 @@ if (isset($_GET['proxy_file'])) { if (substr($path, 0, 1) !== '/') { die('Invalid file path.'); } - if ($path === '/') - return '/'; + if ($path === '/') { + return '/'; + } return realpath($path); } - // get file path - $filePath = isset($_GET['path'])?$_GET['path']:"/"; - + // get file path + $filePath = isset($_GET['path']) ? $_GET['path'] : "/"; $filePath = sanitizePath($filePath); if ($filePath === false || !file_exists($filePath)) { @@ -488,16 +491,45 @@ if (isset($_GET['proxy_file'])) { echo generateDirectoryListing($filePath, $fileList); exit; } else { - // if it is image or vedio file ,return the immage file content if (!is_readable($filePath)) { http_response_code(403); die("File is not readable."); } $mimeType = mime_content_type($filePath); header('Content-Type: ' . $mimeType); - header('Content-Length: ' . filesize($filePath)); - readfile($filePath); - exit; + $fileSize = filesize($filePath); + header("Accept-Ranges: bytes"); + if (isset($_SERVER['HTTP_RANGE'])) { + list(, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2); + list($start, $end) = explode("-", $range); + $start = intval($start); + $end = ($end === '') ? $fileSize - 1 : intval($end); + + if ($start > $end || $start >= $fileSize || $end >= $fileSize) { + header("HTTP/1.1 416 Range Not Satisfiable"); + header("Content-Range: bytes */$fileSize"); + exit; + } + + $length = $end - $start + 1; + $file = fopen($filePath, 'rb'); + fseek($file, $start); + + header("HTTP/1.1 206 Partial Content"); + header("Content-Length: $length"); + header("Content-Range: bytes $start-$end/$fileSize"); + + while (!feof($file) && ($p = ftell($file)) <= $end) { + echo fread($file, min(1024 * 16, $end - $p + 1)); + flush(); + } + fclose($file); + exit; + } else { + header("Content-Length: $fileSize"); + readfile($filePath); + exit; + } } } @@ -1407,7 +1439,7 @@ $objects = is_readable($path) ? scandir($path) : array(); $folders = array(); $files = array(); $current_path = array_slice(explode("/", $path), -1)[0]; -if (is_array($objects) && fm_is_exclude_items($current_path)) { +if (is_array($objects) && fm_is_exclude_items($current_path, $path)) { foreach ($objects as $file) { if ($file == '.' || $file == '..') { continue; @@ -1416,9 +1448,9 @@ if (is_array($objects) && fm_is_exclude_items($current_path)) { continue; } $new_path = $path . '/' . $file; - if (@is_file($new_path) && fm_is_exclude_items($file)) { + if (@is_file($new_path) && fm_is_exclude_items($file, $new_path)) { $files[] = $file; - } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file)) { + } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file, $new_path)) { $folders[] = $file; } } @@ -1535,6 +1567,212 @@ if (isset($_GET['upload']) && !FM_READONLY) { exit; } +//album form +if (isset($_GET['photoalbum']) && !FM_READONLY) { + fm_show_header(); // HEADER + fm_show_nav_path(FM_PATH); // current path + //get the allowed file extensions + +/** + * create Thumbnail + * + * @param string $filePath Original image path + * @param string $thumbnailPath Thumbnail save path + * @param array $size Original image size + */ +function createThumbnail($filePath, $thumbnailPath, $size) { + // Check if thumbnail already exists + if (file_exists($thumbnailPath)) { + return; + } + + // Determine which imagecreatefrom function to use + $createFunc = null; + switch (strtolower(pathinfo($filePath, PATHINFO_EXTENSION))) { + case 'jpg': + case 'jpeg': + case 'jfif': + $createFunc = 'imagecreatefromjpeg'; + break; + case 'png': + $createFunc = 'imagecreatefrompng'; + break; + case 'gif': + $createFunc = 'imagecreatefromgif'; + break; + case 'webp': + $createFunc = 'imagecreatefromwebp'; + break; + case 'bmp': + $createFunc = 'imagecreatefrombmp'; + break; + } + + if ($createFunc && function_exists($createFunc)) { + $sourceImage = @$createFunc($filePath); + if ($sourceImage === false) { + return; // Skip if image cannot be loaded + } + + // Create thumbnail + $thumbWidth = 110; + $thumbHeight = 90; + $thumbImage = imagecreatetruecolor($thumbWidth, $thumbHeight); + + // Handle transparent background + imagealphablending($thumbImage, false); + imagesavealpha($thumbImage, true); + $transparent = imagecolorallocatealpha($thumbImage, 255, 255, 255, 127); + imagefilledrectangle($thumbImage, 0, 0, $thumbWidth, $thumbHeight, $transparent); + + // Scale the image + if (!imagecopyresampled($thumbImage, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $size[0], $size[1])) { + imagedestroy($sourceImage); + imagedestroy($thumbImage); + return; + } + + // Save the thumbnail + $saveFunc = null; + switch (strtolower(pathinfo($filePath, PATHINFO_EXTENSION))) { + case 'jpg': + case 'jpeg': + case 'jfif': + $saveFunc = 'imagejpeg'; + break; + case 'png': + $saveFunc = 'imagepng'; + break; + case 'gif': + $saveFunc = 'imagegif'; + break; + case 'webp': + $saveFunc = 'imagewebp'; + break; + case 'bmp': + $saveFunc = 'imagebmp'; + break; + } + + if ($saveFunc && function_exists($saveFunc)) { + $saveFunc($thumbImage, $thumbnailPath); + } + + // Clean up resources + imagedestroy($sourceImage); + imagedestroy($thumbImage); + } +} + +function generateThumbnails($dir) { + $images = []; + + // Check if the directory is "thumbnails", skip unnecessary processing + $isThumbnailsDir = (basename($dir) === 'thumbnails'); + + // Get all files in the directory + $files = scandir($dir); + if ($files === false) { + return $images; + } + + // If not "thumbnails", create a thumbnails directory + if (!$isThumbnailsDir) { + $thumbnailsDir = $dir . '/thumbnails'; + if (!is_dir($thumbnailsDir) && !mkdir($thumbnailsDir, 0755, true)) { + echo "Error: Unable to create thumbnails directory '$thumbnailsDir'
"; + return false; + } + } + + // Iterate over the files in the directory + foreach ($files as $file) { + if ($file === '.' || $file === '..') { + continue; // Ignore current and parent directories + } + + $filePath = $dir . '/' . $file; + + // Check if it's a supported image file + if (is_file($filePath) && preg_match('/\.(jpg|jpeg|png|gif|jfif|bmp|webp)$/i', $file)) { + $size = @getimagesize($filePath); + if ($size === false) { + continue; // Skip if image info cannot be obtained + } + + // Add image info to the results array + $fileName = basename($filePath); + $images[] = ['src' => $fileName, 'width' => $size[0], 'height' => $size[1]]; + + // If not "thumbnails" directory, create thumbnails + if (!$isThumbnailsDir) { + $thumbnailPath = $thumbnailsDir . '/' . $fileName; + createThumbnail($filePath, $thumbnailPath, $size); + } + } + } + + return $images; +} + + + ?> + + +

+ + +

+ + + + + +:
  • :
  • -
  • File size:
  • -
  • MIME-type:
  • +
  • :
  • +
  • :
  • +
  • :
  • '?'); $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { - try{ + try { $owner_id = fileowner($path . '/' . $f); - if($owner_id != 0) { + if ($owner_id != 0) { $owner_info = posix_getpwuid($owner_id); - if ($owner_info) { - $owner = $owner_info; - } - } - + if ($owner_info) { + $owner = $owner_info; + } + } $group_id = filegroup($path . '/' . $f); $group_info = posix_getgrgid($group_id); if ($group_info) { - $group = $group_info; - } - - } catch(Exception $e){ - error_log("exception:" . $e->getMessage()); + $group = $group_info; + } + } catch (Exception $e) { + error_log("exception:" . $e->getMessage()); } } - ?> @@ -2284,7 +2520,7 @@ $all_files_size = 0; @@ -2308,26 +2544,23 @@ $all_files_size = 0; $owner = array('name' => '?'); $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { - try{ + try { $owner_id = fileowner($path . '/' . $f); - if($owner_id != 0) { + if ($owner_id != 0) { $owner_info = posix_getpwuid($owner_id); - if ($owner_info) { - $owner = $owner_info; - } - } - + if ($owner_info) { + $owner = $owner_info; + } + } $group_id = filegroup($path . '/' . $f); $group_info = posix_getgrgid($group_id); if ($group_info) { - $group = $group_info; - } - - } catch(Exception $e){ - error_log("exception:" . $e->getMessage()); + $group = $group_info; + } + } catch (Exception $e) { + error_log("exception:" . $e->getMessage()); } } - ?> @@ -2747,12 +2980,13 @@ function fm_get_display_path($file_path) /** * Check file is in exclude list - * @param string $file + * @param string $name The name of the file/folder + * @param string $path The full path of the file/folder * @return bool */ -function fm_is_exclude_items($file) +function fm_is_exclude_items($name, $path) { - $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (isset($exclude_items) and sizeof($exclude_items)) { unset($exclude_items); } @@ -2761,7 +2995,7 @@ function fm_is_exclude_items($file) if (version_compare(PHP_VERSION, '7.0.0', '<')) { $exclude_items = unserialize($exclude_items); } - if (!in_array($file, $exclude_items) && !in_array("*.$ext", $exclude_items)) { + if (!in_array($name, $exclude_items) && !in_array("*.$ext", $exclude_items) && !in_array($path, $exclude_items)) { return true; } return false; @@ -3840,6 +4074,9 @@ function fm_show_nav_path($path) +