11b60fc5d8365b08339e20e25cccdfb48d80ecdd
22
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
495b26896e | Fassung 1.7.0: verlässliche Installation, übersichtliche Verwaltung und bedienbare Bewegung | ||
|
|
6a044e59e9 | Fassung 1.6.2: sichtbare leere Layouts und direktes Befuellen im Editor | ||
|
|
b783d9d1e5 | Fassung 1.6.1: flexible Editorflaeche und passende Blockeigenschaften | ||
|
|
05ea703655 |
Fassung 1.6.0: der Aufgabenplan wird veroeffentlicht
Wiederkehrende Aufgaben ohne Cronjob (ADR 073): Sicherung, Statistik kuerzen, geplante Veroeffentlichung, Updatepruefung und Aufraeumen laufen als Plan in der Tabelle scheduled_task - eine Zeile je Aufgabe mit Faelligkeit, Sperre und letztem Ergebnis. Auf geteiltem Hosting gibt es oft keinen Cronjob; der Plan haengt stattdessen an Anfragen und an einem Takt aus dem geoeffneten Backend. Diese Arbeit entstand in einer parallel laufenden Sitzung und lag bis hierher unveroeffentlicht im Arbeitsverzeichnis: die Releases 1.5.0 bis 1.5.5 wurden bewusst aus dem jeweiligen Tag gebaut und enthielten sie deshalb nicht. Vor der Veroeffentlichung geprueft, nicht bloss eingepackt: - phpunit 452/452, npm test 28/28, npm run test:editor vollstaendig. - Die Migration 20260914000100 legt nur die Tabelle scheduled_task an und nimmt sie beim Zurueckrollen wieder weg. Sie fasst keine bestehenden Daten an. - Seit einer Stunde keine Schreibzugriffe der anderen Sitzung mehr. Dabei zwei Fehler behoben: - config/services.yaml verwendet !tagged_iterator. Das ist gueltiges Symfony, aber "lint:yaml config" kennt eigene Tags nur mit --parse-tags und gab 1 zurueck - der CI-Lauf waere daran gescheitert. Flag ergaenzt. - AdminHeadersSubscriber.php (aus 1.5.3) entsprach nicht dem Stil von php-cs-fixer; composer lint gab 8 zurueck. Behoben. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d1ac9d760b |
Fassung 1.5.5: die Verwaltungsnavigation war am Schreibtisch unerreichbar
In der ausgelieferten Fassung fehlte in der Verwaltung am Schreibtisch die gesamte linke Navigation - Marke oben, Fusszeile unten, dazwischen nichts. Die Navigation steckt in einem <details>: auf dem Telefon ein Klappmenue, am Schreibtisch die stehende Spalte. Am Schreibtisch wurde der Schalter mit display:none ausgeblendet - aber das Element trug kein open, und ein geschlossenes details versteckt seinen Inhalt selbst. Schalter weg und Inhalt weg. Behoben mit ::details-content, das den Inhalt am Schreibtisch zurueckholt, waehrend der Schalter ausgeblendet bleibt. Kennt ein Browser die Regel nicht, faellt ueber @supports die ganze Gruppe weg: dann steht der Schalter da und die Liste ist einen Klick entfernt statt gar nicht da. Der Code dafuer lag bereits im Arbeitsverzeichnis - eine parallel laufende Sitzung hatte ihn geschrieben, aber nicht committet, und damit war er in keinem Release. Uebernommen ist hier nur diese Korrektur, nicht die uebrige Arbeit jener Sitzung. Wie das durchrutschen konnte: beim vorigen Bericht wurde die Navigation fuer in Ordnung erklaert, nachdem eine Nachbildung der Regel in einer leeren Seite geprueft worden war. Die Nachbildung enthielt die Korrektur, die ausgelieferte Datei nicht - der Befund war wertlos. Jetzt prueft der Browsertest die echte Verwaltungsseite, auf beiden Groessen. Gegenprobe gemacht: gegen die ausgelieferte admin.css schlaegt er fehl. Geprueft: npm run test:editor vollstaendig, npm test 28/28, phpunit 452/452. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7c3c8671a7 |
Fassung 1.5.4: der Werkzeugkasten bekommt Bilder und eine Suche
Die Elementwahl war eine Liste aus Schriftzeichen - "▣" fuer Sektion, "☰" fuer Zeile. Jetzt traegt jeder der 34 Eintraege eine Strichzeichnung, die zeigt, was er baut: die Sektion ein gefuelltes Band, "Zeile, 3 Spalten" tatsaechlich drei Kaesten, das Bild einen Rahmen mit Bergzug. Zeichnungen statt Bilddateien. Flatsome liefert je Element ein PNG mit. Gezeichnet ist hier besser: library-previews.js ist ein paar hundert Byte statt eines Ordners voller Bitmaps, die Formen nehmen die Farbe der Flaeche an, auf der sie liegen - gesperrte Eintraege werden damit von selbst blass - und sie bleiben auf jedem Bildschirm scharf. Die Zeilenvorschau wird gerechnet: zwei, drei oder vier Kaesten aus derselben Funktion. Suche. Ein Feld ueber der Liste filtert ueber alle Gruppen, gesucht wird ueber Namen, internen Typ und Gruppennamen - wer "slider" eingibt, muss nicht wissen, dass er unter "Gruppen" steht. Gruppen ohne Treffer verschwinden, darunter steht wie viele von wie vielen uebrig sind. Dabei bemerkt: es gab zwei Suchfelder namens "Element suchen" auf einem Bildschirm, fuer eine Sprachausgabe nicht unterscheidbar. Sie heissen jetzt nach dem, was sie durchsuchen. Geprueft: der Browsertest zaehlt die Vorschaubilder gegen die Eintraege und sucht nach Name, Gruppenname und etwas Nichtvorhandenem. npm test 28/28, phpunit 452/452, npm run test:editor vollstaendig ohne axe-Verstoss. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9726af9254 |
Fassung 1.5.3: der Editor blieb nach dem Update schwarz
Nach 1.5.2 meldete der Editor im Browser "The requested module './editor-model.js' does not provide an export named 'dropList'", und der Werkzeugkasten war leer. Ursache war nicht der Code, sondern das Zwischenspeichern. public/.htaccess setzt fuer jede .js-Datei Cache-Control: immutable, max-age=31536000 - ein Jahr. Die Fassungskennung haengt aber nur an den Einstiegsdateien, die die Vorlage schreibt. Die fuenf Module, die der Editor ueber import './...js' laedt, tragen keine: der Browser holte das neue editor.js und behielt das alte editor-model.js. Ein neues canvas-overlay.js traf damit auf ein Modell ohne dropList. Beide gemeldeten Symptome hatten diese eine Wurzel. Seit 1.5.1 baut das Skript den Werkzeugkasten auf, und editor.js importiert canvas-overlay.js in Zeile 5; bricht der Import, laeuft keine Zeile danach und die Elementliste bleibt leer. Das gemeldete fehlende Menue war der Werkzeugkasten, nicht die Verwaltungsnavigation - die wurde geprueft und ist in Chrome 152 in Ordnung. Behebung: eine Importkarte in base.html.twig haengt die Fassung an die aufgeloeste Adresse jedes Moduls, ohne dass eine Importzeile sie kennen muss. Das Zwischenspeichern ueber ein Jahr bleibt - die Leistung war nie das Problem, nur die fehlende Kennung. Eine Importkarte muss eingebettet sein; die Spezifikation kennt keine externe. Unter script-src 'self' wurde sie wortlos verworfen. AdminHeadersSubscriber erzeugt deshalb je Verwaltungsseite einen Nonce, nennt ihn in der Richtlinie und legt ihn in die Anfrage; csp_nonce() gibt ihn der Karte mit. Der Nonce erlaubt genau dieses eine Skript, 'self' gilt unveraendert fuer alles andere. Geprueft: der Browsertest verlangt an jeder angeforderten .js-Adresse eine Fassungskennung (vorher fehlten fuenf, jetzt tragen alle acht), dazu ein Test, der jeden Modulimport gegen die Importkarte haelt - Gegenprobe gemacht. npm test 28/28, phpunit 452/452, npm run test:editor vollstaendig. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7225ae052e |
Fassung 1.5.2: die Optionen selbst
Drei Bedienungen, die Flatsome an jeder Option hat und die hier fehlten. Geraeteschalter je Option. Bisher entschied ein einziger Schalter ueber der Vorschau, welches Geraet das ganze Bedienfeld bearbeitet; "ist die Ueberschrift auf dem Telefon kleiner" liess sich nur durch Umschalten und Hinsehen beantworten. Jetzt traegt jede Option drei Chips (D, T, M): sie zeigen, wo ein eigener Wert liegt, und ein Klick wechselt dorthin. Bedienfeld und Vorschau wechseln gemeinsam - einen Wert fuer ein Geraet zu setzen, das man nicht ansieht, ist blindes Aendern. Abstand als Rahmen. Vier Felder untereinander, beschriftet "Oben, Rechts, Unten, Links", zwangen zum Lesen. Jetzt sitzt jedes Feld an seiner Kante, die Lage ist die Beschriftung; in der Mitte verkettet ein Schalter alle vier. Er startet aus: er ersetzt den frueheren Knopf "Alle Seiten gleich setzen", und das war eine bewusste Handlung. Seiten mit unterschiedlichen Einheiten gelten als "gemischt" und bleiben unangetastet - ein gespeichertes 2rem wird nicht still zu 2px. Ziehfelder. Zahlenfelder lassen sich seitwaerts ziehen, Umschalt grob, Alt fein. Tippen und Pfeiltasten bleiben unveraendert. Nur fuer Maus und Stift: auf einem Tippgeraet ist ein seitliches Ziehen ueber ein Feld die Art, wie das Bedienfeld gescrollt wird. Dabei behoben: der Zug war nach einem Pixel zu Ende, weil jede Aenderung das Bedienfeld neu zeichnete und damit das Feld ersetzte, an dem der Zeiger hing (keepPanel). Der Kettenschalter verlor aus demselben Grund seinen Zustand. Und das Gleichziehen nahm den Wert des ersten Feldes, auch wenn es leer war - ein Druck auf die Kette loeschte damit die Seiten, die einen Wert hatten. Geprueft: npm test 27/27, phpunit 452/452, npm run test:editor vollstaendig mit neuem Abschnitt und ohne axe-Verstoss. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0e2334d30f |
Fassung 1.5.1: der Werkzeugkasten kennt den Zusammenhang
Umuts Einwand: Zeile und Spalte standen oben in der Auswahl, als waeren sie Seitenanfaenge. Sie gehoeren in den Inhalt - erst eine Sektion, dann eine Zeile darin. Das war nicht nur eine Anzeigefrage: eine Zeile nahm bisher jedes Kind an, eine Ueberschrift konnte neben den Spalten landen, und eine Spalte durfte ueberall stehen. Die Struktur, die der Editor in seinem eigenen Hinweistext beschreibt, galt fuer die Schaltflaechen nicht. Uebernommen ist Flatsomes Regelmodell (Elements.php): ALLOW - eine Zeile nimmt nur Spalten; REQUIRE - eine Spalte lebt nur in einer Zeile. Dazu ein Zusatz, den Flatsome nicht hat: ROOT_NEEDS_CONTAINER - eine Zeile ist kein Seitenanfang. In jedem Behaelter bleibt sie erlaubt, auch in einem Tab. Daraus die Bedienung: - Werkzeugkasten nach Aufbau gruppiert statt flacher Liste aus 31 Typen. - Was nicht hingehoert, ist gesperrt und sagt beim Ueberfahren warum. Eine Regel, die man erklaert bekommt, lernt man; eine Schaltflaeche, die nur nicht mehr reagiert, drueckt man weiter. - Was moeglich ist, sagt wohin es kommt. - Die Zeile wird nach Spaltenzahl angeboten und bringt ihre Spalten mit; der separate Zeilenbereich ist entfallen. - insertionTarget beantwortet "wohin kaeme das?", ohne etwas einzufuegen. Knopf, Einfuegepunkt, Ziehen und die Sperrlogik nutzen dieselbe Funktion - vorher entschied insertBlock allein, und insertRow hatte eine zweite Kopie derselben Platzierungslogik. Ein Element, das der gewaehlte Behaelter nicht nimmt, wird nicht gesperrt, sondern steigt auf, bis ein Elternteil es annimmt. Nebenbei behoben: postnav fehlte seit Schema v18 in labels und icons, der Strukturbaum zeigte dafuer "Unbekannt" und ein Fragezeichen. Geprueft: npm test 27/27, phpunit 446/446, npm run test:editor vollstaendig mit neuem Abschnitt und ohne axe-Verstoss. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
22e4ada830 |
Fassung 1.5.0: die Vorschau wird zur Arbeitsflaeche
Abgleich mit dem Flatsome UX Builder (docs/FLATSOME-ABGLEICH.md): die Gestaltung ist Flatsome voraus, die Luecken liegen beim Elementkatalog und bei der Bedienung. Umuts Entscheidung: Bedienung zuerst, Shop-Elemente ausgelassen. Erste Haelfte der Bedienung: - Werkzeugleiste am Element in der Vorschau. Sie nennt das Element, auf das sie wirkt - die Seitenleiste hat dieselben fuenf Aktionen, und zwei gleichnamige Bedienelemente auf einem Bildschirm sind fuer eine Sprachausgabe nicht unterscheidbar. Beide Wege rufen dieselben Funktionen auf. - Auswahl- und Ueberfahrrahmen mit Beschriftung. - Einfuegepunkte an Ober- und Unterkante: das naechste Element landet dort statt am Ende. - Ziehen aus dem Werkzeugkasten in die Vorschau, mit Ablegemarke zwischen den Elementen und Rahmen um einen aufnehmenden Behaelter. Der Strukturbaum zieht in dieselbe Flaeche. Die Ebene liegt ueber dem Rahmen, nicht darin: die Vorschau wird bei jeder Aenderung ersetzt, eingezeichnete Bedienelemente waeren weg und stuenden in der Auszeichnung, die die Vorschau wahrheitsgetreu zeigen soll. Leiste und Pluszeichen werden gegenskaliert und bleiben in der Mobilvorschau fingergross. Im Modell neu: insertBlockAt, moveBlockTo, dropList. Dabei behoben: die Ebene war aria-hidden und enthielt fokussierbare Schaltflaechen; canContain zerbrach an einem fehlenden Block beim Ziehen aus dem Werkzeugkasten; beim Verschieben ans Listenende wurde der Index begrenzt, bevor die Entnahme verrechnet war. Geprueft: npm test 22/22, phpunit 434/434, npm run test:editor vollstaendig mit neuem Abschnitt und ohne axe-Verstoss. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
af5a2cef86 |
Fassung 1.4.6: das Update schreibt mit, und die Ergebnisseite ist nachsichtig
Zwei Nachtraege zu 1.4.5, beide aus der Generalprobe. - Jeder Schritt des Archiv-Updaters geht sofort nach var/updates.log, waehrend des Laufs und nicht am Ende. Auf Umuts Hosting war die Ergebnisseite tot, und damit war auch verloren, was der Updater berichtet hatte. Genau so wurde der naechste Fehlschlag dann doch lesbar: "bin liess sich nicht beiseitelegen - der alte Stand wurde zurueckgeschoben" (ein Windows-Artefakt der Testumgebung, und zugleich der Beweis, dass der Rueckweg funktioniert). - Die Ergebnisseite versteht auch die Schreibweise bis 1.4.4. Das ist kein Nachgeben, sondern noetig: Beim Update schreibt der alte Code die Schritte in die Sitzung und der neue zeigt sie an. Eine Fassung, die nur die neue Schreibweise kennt, koennte das Update, das sie selbst einspielt, nicht berichten. Nachgestellt mit einer echten Installation aus dem Releasearchiv, die ueber die Oberflaeche aktualisiert wurde - nicht ueber die Konsole. Geprueft: 434 Tests auf PHP 8.2 und 8.4. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d295757ce0 |
Fassung 1.4.5: drei Fehler, die nur auf fremden Servern auftraten
Alle drei von Umut auf seinem Hosting gefunden, keiner davon auf meinem Rechner sichtbar. - Der Updateknopf endete mit 500. Das Update lief vollstaendig durch - alle neun Schritte, Dateien getauscht, var/ und .env unberuehrt -, aber die Ergebnisseite starb daran: der Updater ueber Git nennt einen Schritt "step", der ueber das Archiv nannte ihn "label", beide legen ihn unter demselben Sitzungsschluessel ab, und die Vorlage liest "step". Damit war auch der zweite Knopf unerreichbar. Zehn Tests prueften das Rueckgabe-Array, keiner die Seite, die es anzeigt; der neue Test rendert sie (ADR 071). - Die Verwaltung zeigte Git-Fehler auf einer Installation ohne Git. "git ist installiert" und "das hier ist eine Arbeitskopie" waren derselbe Schalter; auf dem Hosting ist Git vorhanden, die Installation kam aber aus dem Archiv. Dort stand "fatal: Not a git repository" an der Stelle der Fassungsnummer. Ohne Arbeitskopie verschwinden die Git-Karten jetzt (ADR 072). - "Sicherung anlegen" endete mit 500: VACUUM INTO gibt es erst seit SQLite 3.27, das Hosting hat eine aeltere Fassung - alt genug fuer die Installation, zu alt fuer die Sicherung. Bei aelteren wird jetzt unter einer Schreibsperre kopiert, und der Knopf faengt jeden Fehler ab statt mit einer 500-Seite zu enden (ADR 072). Nachgestellt wurde das mit einer echten 1.4.3-Installation aus dem Releasearchiv, eigener Datenbank, eigenem Port. Der Archiv-Updater laeuft dort vollstaendig durch: 1.4.3 -> 1.4.4, neun Schritte, var/ und .env unberuehrt. Geprueft: 433 Tests auf PHP 8.2 und 8.4, Editor-Browsertest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4153ba0f65 |
Fassung 1.4.4: Migrationen im Browser, und ein Fehlschlag sagt warum
Zwei Luecken, die erst das Veroeffentlichen von 1.4.3 gezeigt hat. - Es gab keinen Weg, ausstehende Migrationen im Browser auszufuehren. Wer die Dateien per FTP hochlaedt - und das muss genau einmal jeder tun, dessen Installation die Updatekarte noch nicht kennt -, hatte danach neuen Code und eine alte Datenbank, und dafuer nur die Konsole. Also genau das, was auf geteiltem Hosting fehlt. Der Bildschirm "System" zeigt jetzt eine Karte, sobald etwas aussteht, nennt die Namen und fuehrt sie auf Knopfdruck aus. - "Die Releaseseite antwortet nicht" waren drei Ursachen in einem Satz. Beim Gegenpruefen des frischen Releases holte der Updater von hier gar nichts - nicht weil die Leitung zu waere, sondern weil diesem PHP der Zertifikatsspeicher fehlt. Auf einem Webhosting ist das der haeufigste Grund und der einzige, den man in einer Minute behebt; er steht jetzt in der Meldung. Bei genau diesem Fehler wird zusaetzlich der Weg ueber den Dateizeiger versucht - damit funktioniert der Abruf auf diesem Rechner. Abgeschaltet wird die Pruefung nicht: ein Update ohne Zertifikatspruefung koennte unterwegs ausgetauscht worden sein. Dazu der manuelle Weg Schritt fuer Schritt in docs/UPDATE.md und ein Test, der beides festhaelt: dass die Karte auffaellt und dass nur ein angemeldeter Administrator mit gueltigem Formular migrieren kann. Geprueft: 431 Tests auf PHP 8.2 und 8.4, Editor-, Browser- und Linkpruefung, Editor-Modelltests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d6d476177a |
Fassung 1.4.3: Update ohne Git, Verwaltung auf dem Telefon, eigene Symbole
Vier Wuensche und ein Fund beim Nachmessen. - Farbwaehler im Designbereich. Das Textfeld bleibt massgeblich, damit "@akzent" ein Verweis auf die Palette bleibt und nicht beim ersten Klick zu einem festen Hexwert erstarrt (ADR 066). - Die Verwaltung auf dem Telefon: das Menue klappt unter 760 px zu und nennt den Bereich, in dem man steht; Ziele 44 px, kein Skript. - Eigene SVG-Symbole statt Unicode-Zeichen - ein Telefon ersetzt die sonst durch Emoji in fremdem Stil. Zwei Eintraege trugen dabei denselben Pfad; ein Test findet beides (ADR 067). - Update aus dem Releasearchiv: der Weg fuer Installationen ohne Git. Zwei Schritte, weil ein Prozess, der sich selbst ausgetauscht hat, mit dem alten Code weiterarbeitet. var/, .env, hochgeladene Schriften und das erzeugte Buendel bleiben unberuehrt; public/ wird dazu Datei fuer Datei zusammengefuehrt. Geprueft ohne Netz gegen eine Releaseseite im Speicher (ADR 068). Beim Nachmessen der echten Startseite statt einer Testseite: das groesste Element ueber der Falz ist dort kein <img>, sondern der Hintergrund des ersten Abschnitts - und der steht nur im Stylesheet. Drei Vorabverweise mit denselben Geraetegrenzen wie der Compiler holen genau die Variante, die die Regel auch nimmt. LCP 1,3 s -> 1,1 s. Dabei gefunden: dasselbe Bild wurde je Geraeteregel neu abgefragt - Startseite 19 -> 15 Abfragen (ADR 069). Geprueft: 428 Tests auf PHP 8.2 und 8.4, Editor-, Browser- und Linkpruefung, Lighthouse auf drei echten Seiten (alles ausser der Leistung der Startseite 100). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ea3dd4ddf2 |
Fassung 1.4.2: die Systempruefung nennt die SQLite-Fassung
Auf dem Hosting brach die Installation im dritten Schritt ab: near
"(": syntax error. Dort laeuft SQLite in einer Fassung vor 3.16, und
Doctrine liest das Schema mit Tabellenfunktionen wie
pragma_table_info(...), die es erst seit 3.16 gibt.
Die Pruefung nennt die gefundene Fassung jetzt vor der Wahl der
Datenbank, und der Datenbankschritt bietet SQLite gar nicht erst an,
wenn sie zu alt ist - mit dem Hinweis auf MySQL. Eine Voraussetzung,
die erst mitten in der Installation auffaellt, ist keine Pruefung wert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
c517173579 |
Fassung 1.4.1: dem Releasearchiv fehlten migrations.php und cli-config.php
Auf dem Hosting brach die Installation im dritten Schritt ab - "The configuration file does not exist", genau dort, wo die Tabellen entstehen sollten. Beide Dateien standen weder in der Mitnahme- noch in der Ausschlussliste des Releaseskripts. Ein Test ordnet jetzt jeden Eintrag im Projektstamm einer der beiden Listen zu: was neu dazukommt und unbedacht bleibt, laesst ihn fehlschlagen. Der Installationsweg wurde danach vollstaendig durchgespielt - 3504 Dateien entpackt, 14 Migrationen ausgefuehrt, 15 Tabellen angelegt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
b218dc79ff |
Fassung 1.4.0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e34b4dca67 |
Installer: sechs Bildschirme, und eine Datei davor
/install fuehrt von einer leeren Installation zu einer Website: Systempruefung, Datenbank (SQLite oder MySQL, Verbindung sofort geprueft), Migration im Prozess ohne Konsole, Website mit Startseite, Bereichen, Menue sowie Impressum und Datenschutzgeruest, erstes Konto, Abschlussliste. Jeder Schritt schreibt sein Ergebnis sofort, damit ein Neuladen nichts verliert. Gesperrt wird ueber den Zustand der Datenbank - gibt es ein Konto, antwortet /install mit 404. Eine Datei koennte jemand loeschen. Solange nichts installiert ist, fuehrt jede Adresse zum Installer statt zu einem 500 aus einer fehlenden Tabelle. Und weil ohne APP_SECRET nicht einmal die Seite bootet, die das erklaeren wuerde, erzeugt der erste Start das Geheimnis selbst. scripts/install.php ist die einzelne Datei davor: Adresse und SHA-256 stehen darin (vom Buildskript eingetragen), ohne passende Pruefsumme wird nicht entpackt, jeder Archiveintrag wird gegen das Zielverzeichnis geprueft, und danach loescht sie sich selbst. Geprueft: 379 Tests unter PHP 8.2 und 8.4, darunter der ganze Ablauf durch die HTTP-Schicht, neun ZIP-Slip-Varianten, axe ohne Verstoss auf allen Installationsbildschirmen, und das entpackte Releasearchiv startet in den Installer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c046681302 |
Fassung 1.2.0
Sicherung und Wiederherstellung, Ladeverhalten gemessen, Seitenbereiche je Seite, Menuearten, Designerausbau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
806df4b5df |
Fassung 1.1.0
Designerausbau, Statistik, Updater, Einwilligung und Pflichtseiten seit 1.0.1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5a8d67a638 |
Fassung 1.0.1: die laufende Fassung steht in der Verwaltung
Eine kleine, von außen sichtbare Änderung - sie ist der Prüfstein für das Update: nach dem Einspielen muss in der Seitenleiste 1.0.1 stehen, und der Weg dorthin muss die Schritte gegangen sein, die der Updater verspricht. Die Fassung kommt über eine Twig-Funktion in die Vorlage, nicht über einen globalen Dienst: die Vorlagen bekommen genau diese eine lesende Antwort und nicht einen Updater mit update() darauf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
52f0ab3807 |
Updater: neue Fassung über Git, mit Vorprüfung und Rückweg
Aus dem Plan in docs/UPDATE.md ist Code geworden: cms:update, cms:health, der Bildschirm "System" und der Wartungszustand. Die Vorprüfung ist die halbe Arbeit. Sie fragt nach proc_open, Git, sauberer Arbeitskopie, Herkunft, Schreibrechten und Platz - und danach, ob Datenbank und Medienordner wirklich von Git ausgenommen sind. Das ist der Punkt, an dem ein Update Inhalte zerstören könnte, also wird er geprüft und nicht angenommen. Jede Prüfung sagt, was zu tun ist, nicht bloß "fehlgeschlagen". Der Rückweg ist Teil des Wegs: scheitert ein Schritt, wird auf den vorherigen Commit zurückgesetzt. Die Datenbank nur dann zurückgeschrieben, wenn die Migration schon begonnen hatte - sonst verlöre der Rückweg Inhalte, die während des Updates entstanden sind. Antwortet der alte Stand im Rauchtest, geht die Website wieder online; antwortet er nicht, bleibt der Wartungszustand, weil eine kaputte Seite schlechter ist als eine ehrliche Meldung. Der Rauchtest läuft als eigener Prozess, denn nur ein frischer Prozess führt den neuen Code aus. Ein Test im laufenden Prozess hätte den alten geprüft und "alles in Ordnung" gemeldet. Kein symfony/process: der Runner sind dreißig Zeilen über proc_open mit dem Befehl als Array - kein Shell, nichts zu maskieren, und "proc_open ist abgeschaltet" wird die erste Antwort statt der Überraschung im dritten Schritt. 285 PHP-Tests / 1244 Assertions. Sechs davon fahren den Updater gegen echte Git-Repositorys in einem Temp-Verzeichnis, mit Platzhalterskripten für die zwei Befehle - inklusive des Fehlschlags, nach dem Code und Datenbank zurückgesetzt sein müssen. Nicht gegen dieses Projekt: ein Test, der die Arbeitskopie auscheckt, in der er läuft, ist ein Weg, Arbeit zu verlieren. Offen bleibt die Sicherung einer MySQL-Datenbank per mysqldump - dafür fehlt die Installation; der Updater sagt das im Schritt "Sicherung". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |