112 lines
3.5 KiB
PHP
112 lines
3.5 KiB
PHP
<?php
|
|
header('Content-Type: text/html; charset=utf-8');
|
|
$conf = @include __DIR__ . '/../../inc/config.php';
|
|
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES|ENT_SUBSTITUTE,'UTF-8'); }
|
|
|
|
if (!is_array($conf) || !isset($conf['projectdb'])) {
|
|
echo 'Invalid config.php (expected return array with key projectdb)'; exit;
|
|
}
|
|
|
|
$cfg = $conf['projectdb'];
|
|
$prefix = (string)($cfg['prefix'] ?? '');
|
|
|
|
$attempts=[]; $pdo=null;
|
|
$mkPdo=function(array $cfg) use(&$attempts){
|
|
$host = $cfg['db_host'] ?? null;
|
|
$socket = $cfg['db_socket'] ?? null;
|
|
$name = $cfg['db_name'] ?? '';
|
|
$user = $cfg['db_user'] ?? '';
|
|
$pass = $cfg['db_pass'] ?? '';
|
|
$charset = $cfg['db_charset'] ?? 'utf8mb4';
|
|
$port = (int)($cfg['db_port'] ?? 3306);
|
|
|
|
$dsn = $socket
|
|
? "mysql:unix_socket={$socket};dbname={$name};charset={$charset}"
|
|
: "mysql:host=".($host?:'127.0.0.1').";port={$port};dbname={$name};charset={$charset}";
|
|
|
|
try{
|
|
$pdo = new PDO($dsn,$user,$pass,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES=>false]);
|
|
$attempts[]=['dsn'=>$dsn,'ok'=>true];
|
|
return $pdo;
|
|
}catch(Throwable $e){
|
|
$attempts[]=['dsn'=>$dsn,'ok'=>false,'error'=>$e->getMessage()];
|
|
return null;
|
|
}
|
|
};
|
|
|
|
if (is_array($cfg)) $pdo=$mkPdo($cfg);
|
|
|
|
$tables = [
|
|
$prefix.'templates',
|
|
$prefix.'sections',
|
|
$prefix.'blocks',
|
|
$prefix.'snippets',
|
|
$prefix.'template_items',
|
|
$prefix.'section_items',
|
|
];
|
|
|
|
$tblStatus=[];
|
|
if ($pdo){
|
|
foreach($tables as $t){
|
|
try{ $pdo->query("SELECT 1 FROM {$t} LIMIT 1"); $tblStatus[$t]='ok'; }
|
|
catch(Throwable $e){ $tblStatus[$t]='missing/invalid: '.$e->getMessage(); }
|
|
}
|
|
}
|
|
?>
|
|
<!doctype html>
|
|
<html lang="de">
|
|
<meta charset="utf-8">
|
|
<title>DB-Doctor</title>
|
|
<style>
|
|
body{font:14px/1.5 system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;background:#f8fafc;color:#0f172a;margin:0;padding:24px;}
|
|
.nav a{display:inline-block;margin-right:8px;padding:8px 12px;border:1px solid #e5e7eb;border-radius:8px;background:#fff;text-decoration:none;color:#0f172a}
|
|
.nav .active{background:#eef2ff;border-color:#c7d2fe;}
|
|
.card{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:16px;margin:16px 0;}
|
|
table{border-collapse:collapse;width:100%;}
|
|
th,td{border-bottom:1px solid #e5e7eb;padding:8px 6px;text-align:left;}
|
|
.ok{color:#166534} .bad{color:#991b1b}
|
|
code{background:#0b1020;color:#e5e7eb;padding:2px 6px;border-radius:6px}
|
|
</style>
|
|
|
|
<h1>DB-Doctor</h1>
|
|
|
|
<div class="card">
|
|
<h3>Verbindungsversuche</h3>
|
|
<table>
|
|
<tr><th>DSN</th><th>Ergebnis</th><th>Detail</th></tr>
|
|
<?php foreach($attempts as $a): ?>
|
|
<tr>
|
|
<td><code><?=h($a['dsn'])?></code></td>
|
|
<td><?= !empty($a['ok']) ? '<span class="ok">OK</span>' : '<span class="bad">FAIL</span>' ?></td>
|
|
<td><?= h($a['error'] ?? '') ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Tabellen-Check (Templates-Schema)</h3>
|
|
<table>
|
|
<tr><th>Tabelle</th><th>Status</th></tr>
|
|
<?php foreach($tables as $t): ?>
|
|
<tr>
|
|
<td><code><?=h($t)?></code></td>
|
|
<td>
|
|
<?php $s=$tblStatus[$t]??'not checked';
|
|
echo ($s==='ok') ? '<span class="ok">OK</span>' : '<span class="bad">'.h($s).'</span>'; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Rohdaten</h3>
|
|
<pre><?=h(json_encode([
|
|
'prefix'=>$prefix,
|
|
'hasPdo'=>!!$pdo,
|
|
'configKeys'=>array_keys($conf),
|
|
], JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES))?></pre>
|
|
</div>
|
|
</html>
|