This commit is contained in:
2025-12-04 22:33:05 +01:00
parent 316175e158
commit 9dee06cdd6
145 changed files with 16865 additions and 88 deletions

View File

@@ -0,0 +1,9 @@
<?php
header('Content-Type: application/json; charset=utf-8');
$path = realpath(__DIR__ . '/../../inc/config.php');
$out = ['path_expected'=>$path,'exists'=>false,'readable'=>false,'type'=>null,'keys'=>[], 'notes'=>[]];
if (is_file($path)) { $out['exists']=true; $out['readable']=is_readable($path);
try { $cfg = require $path; $out['type']=gettype($cfg); if (is_array($cfg)) { $out['keys']=array_keys($cfg); } }
catch (Throwable $e) { $out['notes'][] = $e->getMessage(); }
} else { $out['notes'][]='file not found'; }
echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

118
public/tools/db-doctor.php Normal file
View File

@@ -0,0 +1,118 @@
<?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['templates'])) {
echo 'Invalid config.php (expected return array with keys templates/project)'; exit;
}
$profile = $_GET['profile'] ?? 'templates';
$cfg = ($profile==='project') ? ($conf['project'] ?? null) : $conf['templates'];
$prefix = (string)(($profile==='project') ? ($conf['project']['prefix'] ?? '') : ($conf['templates']['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 (<?=h($profile)?>)</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 <small style="font-weight:400;color:#475569">(Profil: <?=h($profile)?>)</small></h1>
<div class="nav">
<a href="?profile=templates" class="<?= $profile==='templates'?'active':'' ?>">Templates</a>
<a href="?profile=project" class="<?= $profile==='project' ?'active':'' ?>">Project</a>
</div>
<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>