Finish an archive update in one go and translate Kantarci Reisen into Turkish
The request that swaps the files now ends with a plain page instead of running on through the framework with old code in memory and new code on disk - that is what answered with a 500 after a successful update. The page calls the second step itself with a one-time key: migrations, clean-up, maintenance off, back to the system screen (ADR 112). Turkish is complete in the fixed template texts and form messages. Two language switches on one page get distinct landmark names. Kantarci Reisen gets a Turkish version of every page, the header, footer, menu and enquiry form, with a DE · TR switch; the reset script applies it. The DM Sans 600 files are needed after all and are committed with fonts.css. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8aee38bde8
commit
47292c7266
14 files changed
+617
-11
No files matched your search
@@ -174,13 +174,14 @@ final class SystemController extends AbstractController
|
||||
|
||||
return $this->redirectToRoute('admin_system');
|
||||
}
|
||||
// Alles, was nach dem Dateitausch noch gebraucht wird, steht vorher fest: Danach darf diese
|
||||
// Anfrage keinen Code mehr nachladen (siehe sendAndStop).
|
||||
$abschluss = '/'.trim($this->adminPath, '/').'/system/abschliessen?token=';
|
||||
$ergebnis = $this->archive->run($request->request->getString('target') ?: null);
|
||||
$request->getSession()->set('update_steps', $ergebnis['steps']);
|
||||
if ($ergebnis['migrate'] ?? false) {
|
||||
$this->addFlash('success', 'Die Dateien sind ersetzt. Jetzt noch die Migrationen - der Knopf steht oben.');
|
||||
|
||||
return $this->redirectToRoute('admin_system');
|
||||
$this->sendAndStop((string) $ergebnis['fassung'], $abschluss.$ergebnis['token'], $ergebnis['steps']);
|
||||
}
|
||||
$request->getSession()->set('update_steps', $ergebnis['steps']);
|
||||
$this->addFlash($ergebnis['ok'] ? 'success' : 'error', $ergebnis['ok']
|
||||
? 'Es war nichts einzuspielen.'
|
||||
: 'Das Update ist nicht durchgelaufen. Die Schritte stehen unten.');
|
||||
@@ -188,6 +189,73 @@ final class SystemController extends AbstractController
|
||||
return $this->redirectToRoute('admin_system');
|
||||
}
|
||||
|
||||
/**
|
||||
* Der zweite Schritt des Archivupdates, aufgerufen von der Zwischenseite selbst (ADR 112).
|
||||
*
|
||||
* Läuft in einer eigenen Anfrage und damit mit dem Code der neuen Fassung: Migrationen,
|
||||
* Aufräumen, Wartungszustand aus. Der Einmalschlüssel aus var/update/offen.json ersetzt das
|
||||
* CSRF-Token, das die Zwischenseite nicht mehr erzeugen kann; ohne Administratorrolle geht es
|
||||
* ohnehin nicht. Ein zweiter Aufruf (Neuladen) findet nichts mehr offen und meldet das.
|
||||
*/
|
||||
#[Route('/%kant.admin_path%/system/abschliessen', name: 'admin_system_finish', methods: ['GET'])]
|
||||
public function finishArchive(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$offen = $this->archive->pending();
|
||||
if (null === $offen) {
|
||||
$this->addFlash('success', 'Das Update ist bereits abgeschlossen.');
|
||||
|
||||
return $this->redirectToRoute('admin_system');
|
||||
}
|
||||
if (!is_string($offen['token'] ?? null) || !hash_equals($offen['token'], $request->query->getString('token'))) {
|
||||
return $this->back('Dieser Link gehört zu keinem offenen Update. Schließe es oben mit „Migrationen ausführen“ ab.');
|
||||
}
|
||||
@set_time_limit(0);
|
||||
$ergebnis = $this->archive->finish($this->installation);
|
||||
$request->getSession()->set('update_steps', $ergebnis['steps']);
|
||||
$this->addFlash($ergebnis['ok'] ? 'success' : 'error', $ergebnis['ok']
|
||||
? sprintf('Update auf %s abgeschlossen. Die Website ist wieder erreichbar.', $offen['fassung'])
|
||||
: 'Die Migrationen sind fehlgeschlagen. Die Website bleibt im Wartungszustand.');
|
||||
|
||||
return $this->redirectToRoute('admin_system');
|
||||
}
|
||||
|
||||
/**
|
||||
* Beendet die Anfrage, die gerade die Dateien getauscht hat, mit einer schlichten Seite.
|
||||
*
|
||||
* Dieser Prozess hat den alten Code im Speicher, auf der Platte liegt der neue. Alles, was
|
||||
* jetzt noch nachgeladen würde - Antwort-Listener, Sitzung, Vorlagen -, käme aus der neuen
|
||||
* Fassung und passte nicht zu dem, was schon geladen ist. Genau das endete vorher mit einem
|
||||
* 500er, obwohl das Update gelungen war. Deshalb hier nur noch PHP selbst: Kopfzeilen, Text,
|
||||
* Ende. Die Seite ruft den Abschluss sofort selbst auf, ein Link steht für den Fall daneben,
|
||||
* dass der Browser das Weiterleiten unterdrückt.
|
||||
*
|
||||
* @param list<array{step: string, ok: bool, detail: string}> $schritte
|
||||
*/
|
||||
private function sendAndStop(string $fassung, string $weiter, array $schritte): never
|
||||
{
|
||||
while (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
$e = static fn (string $text): string => htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
$liste = '';
|
||||
foreach ($schritte as $schritt) {
|
||||
$liste .= '<li>'.($schritt['ok'] ? '✓ ' : '! ').$e($schritt['step']).'</li>';
|
||||
}
|
||||
http_response_code(200);
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
header('Cache-Control: no-store');
|
||||
header('X-Robots-Tag: noindex');
|
||||
header("Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'; base-uri 'none'");
|
||||
echo '<!doctype html><html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">'
|
||||
.'<meta http-equiv="refresh" content="1;url='.$e($weiter).'"><title>Update wird abgeschlossen</title>'
|
||||
.'<style>body{font:16px/1.5 system-ui,sans-serif;background:#f3f5f2;color:#203b34;margin:0;display:grid;place-items:center;min-height:100vh}main{background:#fff;border:1px solid #dfe5e1;border-radius:12px;padding:28px 32px;max-width:460px}h1{font-size:20px;margin:0 0 8px}ul{padding-left:18px;color:#46514c;font-size:14px}a{color:#1f5f45}</style></head>'
|
||||
.'<body><main><h1>Update auf '.$e($fassung).' wird abgeschlossen …</h1>'
|
||||
.'<p role="status">Die neuen Dateien sind da. Jetzt laufen die Migrationen, danach geht es von selbst zur Systemseite.</p>'
|
||||
.'<ul>'.$liste.'</ul><p><a href="'.$e($weiter).'">Weiter, falls nichts passiert</a></p></main></body></html>';
|
||||
exit;
|
||||
}
|
||||
|
||||
#[Route('/%kant.admin_path%/system/update', name: 'admin_system_update', methods: ['POST'])]
|
||||
public function update(Request $request): Response
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user