Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
17 KiB
Divi-Absicherung – Design-Spezifikation
- Datum: 2026-09-29
- Status: Entwurf zur Freigabe
- Autor: Jan-Niclas Loosen (Loosen-IT), erarbeitet mit Claude
- Einordnung: eigene Etappe vor Etappe 4 (Designsystem schreiben); Etappe 4 baut darauf auf.
1. Ziel und Kontext
1.1 Problem
Die Divi-Integration hängt an Divi-Interna, nicht an einer zugesicherten Schnittstelle (Divi 5 bietet zum Schreiben keine an). Stand 0.5.0:
- 19 Dateien rufen Divi direkt auf (
et_*-Funktionen,ET\…-Klassen,_et_*-Meta, Optionet_divi), auch außerhalb vonIntegrations/Divi/(MediaUsageFinder,PostPresenter,ContentSchema). - Einige Stellen bilden Divi-Speicherlogik nach (Theme-Builder-Templateliste/Bedingungen/
_et_enablednachet_theme_builder_api_save(), Bibliothekseinträge nachet_pb_submit_layout(), Builder-Kennzeichen nachSyncToServerController). Ändert Divi diese Logik, schreibt das Plugin still falsche Daten. - Welche Divi-Teile genutzt werden, steht an drei Orten (
DiviCompatibility,DiviThemeBuilder::FUNCTIONS, Docblocks mit Zeilennummern aus Divi 5.2.1).DiviCompatibilityprüft nur Existenz, nicht Verhalten. - Eine Divi-Version wird nicht geprüft.
1.2 Ziele (Vorgabe Auftraggeber)
- Weniger Aufwand pro Divi-Update.
- Ungetestete Divi-Version → nichts schreiben, klare Antwort. Lesende Divi-Tools laufen weiter mit Hinweis „Achtung, ungetestet“; schreibende Divi-Tools sind gesperrt und sagen warum.
- Freigabe ohne Plugin-Update möglich: getestete Versionen stehen fest im Code; zusätzlich kann ein Administrator auf einer Website im WP-Admin eine Prüfung laufen lassen und die Version danach freigeben (Eintrag in der Datenbank). Freigeben geht nur nach bestandener Prüfung.
- Wartbarkeit: Divi-Zugriffe an einer Stelle bündeln (bestehender Code wird umgebaut, nicht nur neuer Code).
1.3 Erfolgskriterien
- Außerhalb der fünf Divi-Adapter (§3) gibt es keinen direkten Divi-Zugriff; ein Unit-Test erzwingt das.
- Jede genutzte Divi-Funktion/-Klasse/-Methode, jeder Post-Typ, jede Taxonomie, jeder Meta-Schlüssel und jede Option steht im Manifest ihres Adapters; nachgebaute Divi-Funktionen haben einen Fingerabdruck.
- Mit einer nicht freigegebenen Divi-Version schreibt kein Divi-Tool; die Antwort trägt
divi_untestedbzw.divi_incompatibleund einen deutschen Hinweis. Lesende Divi-Tools liefern ihr Ergebnis mit Hinweis inwarnings. - Die Admin-Prüfung läuft auf einer Live-Website ohne sichtbare Spuren: die Wegwerfseite ist danach in jedem Fall gelöscht.
- Alle bestehenden Unit-Tests und Smoke-Skripte sind nach dem Umbau unverändert grün (Umbau ohne Verhaltensänderung).
- Eine neue Divi-Version lokal prüfen ist ein Befehl (
wp lit-mcp divi-check); bei Rot zeigt--diffdie geänderten Divi-Funktionen.
1.4 Nicht Teil dieser Etappe
- Sperren für Pods (nutzt nur die öffentliche Pods-API) oder den MCP-Adapter.
- Automatisierter Browsertest des Visual Builders.
- Schreiben ins Designsystem (Etappe 4 – dort gleich mit Manifest).
2. Begriffe
- Adapter: Klasse, die als einzige Divi direkt anspricht (§3).
- Manifest: Beschreibung der Divi-Abhängigkeiten eines Adapters (§4).
- Nachbau (Mirror): Plugin-Code, der Speicherlogik einer Divi-Funktion wiederholt, statt sie aufzurufen.
- Fingerabdruck: SHA-256 des normalisierten Quelltexts einer Divi-Funktion/-Methode (§4.2).
- Live-Prüfung: Abgleich aller Manifeste mit dem installierten Divi (Existenz + Fingerabdrücke), zur Laufzeit, zwischengespeichert (§5.4).
- Admin-Prüfung: vollständige Prüfung aus dem WP-Admin inkl. Schreibtest (§6).
3. Divi-Grenze
Nur fünf Adapter greifen auf Divi zu. Vorhandene Klassen werden wo möglich zu Adaptern bzw. in sie hineingezogen, damit der Umbau klein bleibt.
| Adapter | Übernimmt (Stand 0.5.0) |
|---|---|
| Seiten | DiviSaver (Divi-Teil), DiviFlags, CSS-Cache ET_Core_PageResource, WpLinkTargets (Divi-Teil) |
| Bibliothek | DiviLibraryStore, LibraryItemSpec, NewLibraryEntry, DiviRoles, LibraryAccess (Divi-Teil), GlobalLayout |
| Theme Builder | DiviThemeBuilder, Template, TemplateConditions (Divi-Teile) |
| Designsystem | DesignSystemReader, DesignSystem (Divi-Teil), Option et_divi inkl. divi_logo für MediaUsageFinder |
| Katalog | DiviModules, DynamicContentMap, Divi-Post-Typen/Flags für PostPresenter und ContentSchema |
Die genaue Klassenaufteilung legt der Plan fest; Regel: jede Divi-Berührung liegt in genau einem Adapter, der Rest des Plugins nutzt nur dessen Methoden.
Parser, Serializer und Compose/ bleiben, wo sie sind: sie kennen das Divi-Format (Blockmarkup, Attributpfade), rufen aber keine Divi-Funktionen auf. Ihr Schutz ist die Katalog- und Formatprüfung (§6.2 Schritte 2–3).
Architekturtest (Unit): durchsucht src/; außerhalb der Adapter-Dateien sind et_*(-Aufrufe, ET\…- und ET_…-Klassen sowie '_et_…'/'et_divi'-Schlüssel ein Fehler. Innerhalb der Adapter ist jede solche Fundstelle ein Fehler, die nicht im Manifest des Adapters steht. Während des Umbaus gibt es eine Ausnahmeliste für Altbestand; am Ende der Etappe ist sie leer und wird entfernt.
4. Manifest
4.1 Inhalt
Jeder Adapter liefert ein Manifest (festes PHP-Wertobjekt, keine Konfigurationsdatei) mit:
functions: Divi-Funktionen, die aufgerufen werden;methods: Klasse + Methode (+ erwartete Mindest-Parameterzahl), z. B.ET\Builder\Packages\GlobalData\GlobalData::get_global_colors;classes: Klassen, deren Existenz genügt;post_types,taxonomies,block_types;meta_keys,options: Divi-Schlüssel, die gelesen oder geschrieben werden (dokumentarisch; Architekturtest nutzt sie);mirrors: nachgebaute Divi-Funktionen/-Methoden mit Fingerabdruck und Kurzbeschreibung, was nachgebaut wird;sources: Quellenangaben (Divi-Datei, Funktion) – ersetzt die Zeilennummern in Docblocks. Zeilennummern entfallen.
4.2 Fingerabdruck
sha256 über den Quelltext der Funktion bzw. Methode (per ReflectionFunction/ReflectionMethod: Datei, Start- und Endzeile), normalisiert mit token_get_all(): T_COMMENT, T_DOC_COMMENT, T_WHITESPACE entfernt, übrige Tokens aneinandergehängt. Kommentar- und Formatänderungen ändern den Fingerabdruck nicht; Codeänderungen schon.
Die Soll-Fingerabdrücke werden mit dem Plugin ausgeliefert (erzeugte Datei im Plugin, z. B. JSON neben den Manifesten). Die normalisierten Soll-Quelltexte liegen nur für die Entwicklung unter tests/Fixtures/divi/reference/ (per .gitattributes nicht im Plugin-Paket) und dienen --diff (§7).
4.3 DiviCompatibility
Verliert ihre handgepflegte Liste und prüft alle Manifeste: Existenz von Funktionen/Klassen/Methoden (inkl. Parameterzahl), Post-Typen, Taxonomien, Block-Typen; Fingerabdrücke der Mirrors. Ergebnis: Liste roter Punkte mit Adapter, Divi-Symbol, Fundort in der installierten Version. Die bisherigen Sonderprüfungen (z. B. divi/global-layout registriert oder in den Core-Metadaten) werden Manifest-Einträge mit eigener Prüfregel.
5. Freigabe und Sperre zur Laufzeit
5.1 Divi-Version
Aus dem aktiven Theme wie bisher (EnvironmentProbe: Template Divi, bei Child-Theme Version des Eltern-Themes).
5.2 Zustände
| Zustand | Bedingung | Schreibende Divi-Tools | Lesende Divi-Tools |
|---|---|---|---|
released |
Version freigegeben (§5.3) und Live-Prüfung grün | laufen | laufen |
untested |
Live-Prüfung grün, Version nicht freigegeben | gesperrt, divi_untested |
laufen, Hinweis |
incompatible |
Live-Prüfung rot | gesperrt, divi_incompatible |
laufen, Hinweis |
Die Live-Prüfung zählt immer, auch für Versionen aus der Code-Liste (erkennt z. B. Hotfixes mit gleicher Versionsnummer). Ist Divi nicht aktiv, gibt es wie bisher keine Divi-Tools; der Zustand ist dann ohne Bedeutung.
5.3 Quellen der Freigabe
Eine Divi-Version ist freigegeben, wenn sie
- im Code steht: feste Liste getesteter Versionen (PHP-Konstante), vom Entwickler gepflegt; oder
- in der Datenbank der Website steht: Option
lit_mcp_divi_releases, Liste von Einträgen{divi_version, plugin_version, user_id, released_at, report_id}. Ein Eintrag entsteht nur über die Admin-Prüfung nach grünem Bericht (§6.3) und gilt nur für die Plugin-Version, mit der geprüft wurde. Nach einem Plugin-Update muss eine nur per Datenbank freigegebene Divi-Version neu geprüft werden, außer sie steht inzwischen in der Code-Liste. Ein Administrator kann Einträge zurückziehen.
Multisite: pro Website (Optionen der jeweiligen Website).
5.4 Live-Prüfung und Zwischenspeicher
Die Live-Prüfung (Manifeste, §4.3) wird im Transient lit_mcp_divi_state zwischengespeichert, Schlüssel aus Divi-Version, Plugin-Version und filemtime der Dateien aller Mirrors und Methoden. Weicht der Schlüssel ab oder lief ein Theme-Update (upgrader_process_complete für das Divi-Theme), wird neu berechnet. Kosten ohne Cache: Reflection + Tokenisieren von rund zehn Funktionen.
5.5 Sperre
Zentral (AbilityRegistrar): Für jedes Tool der Divi-Integration wird vor execute der Zustand ermittelt.
- Schreibendes Tool (Annotation nicht
readonly) und Zustand ≠released: sofortWP_Errormit Codedivi_untestedbzw.divi_incompatible, keine Ausführung, Protokolleintrag als abgelehnter Aufruf. - Lesendes Tool und Zustand ≠
released: normale Ausführung, Hinweis inwarningsdes Ergebnisses.
Welche Tools „Divi-Tools“ sind, ergibt sich aus der Integrations-Zugehörigkeit (IntegrationRegistry::groupMap()); Divi-lastige Tools anderer Integrationen deklarieren sich zusätzlich (Ability-Eigenschaft „nutzt Divi“), ein Unit-Test prüft die Zuordnung.
In den Adaptern: Jede schreibende Adapter-Methode prüft den Zustand selbst und wirft bei ≠ released eine eigene Ausnahme, die auf dieselben Fehlercodes abgebildet wird; bestehendes Rollback greift. Das deckt Wege ab, die Divi-Interna indirekt nutzen (z. B. Content-Update einer Divi-Seite über DiviSaver). Generisches Kopieren/Wiederherstellen von Posts (PostCloner, Revisionen) berührt keine Divi-Interna und bleibt ungesperrt.
Prüfmodus: Der Schreibtest der Admin-Prüfung (§6.2 Schritt 4) muss trotz untested schreiben. Er setzt dafür eine request-lokale Ausnahme, die ausschließlich für die ID der Wegwerfseite gilt; sie ist nicht von außen setzbar (kein Parameter, keine Option).
5.6 Hinweistexte
divi_untested: „Achtung: Divi {version} ist auf dieser Website noch nicht für LIT MCP freigegeben. Schreibende Divi-Werkzeuge sind gesperrt, bis ein Administrator unter Einstellungen → LIT MCP → Divi die Prüfung ausführt und die Version freigibt. Es wurde nichts geändert.“divi_incompatible: „Divi {version} hat Stellen geändert, die LIT MCP nutzt. Schreibende Divi-Werkzeuge sind gesperrt, bis LIT MCP aktualisiert wurde. Es wurde nichts geändert.“- Lesehinweis (
warnings): „Achtung: Divi {version} ist für LIT MCP ungetestet (bzw. inkompatibel); Lesen funktioniert, Schreiben ist gesperrt.“
5.7 lit-site-status
Zeigt für Divi zusätzlich: Zustand, Quelle der Freigabe (code/database mit Datum und Benutzer), rote Punkte der Live-Prüfung.
6. Admin-Prüfung
6.1 Oberfläche und Rechte
Neuer Reiter „Divi“ unter Einstellungen → LIT MCP: Zustand, Divi-Version, Quelle der Freigabe, letzter Prüfbericht, Knöpfe „Prüfung starten“, „Divi {version} freigeben“, „Freigabe zurückziehen“. Alle Aktionen: manage_options, Nonce, admin-post-Aktionen wie die übrigen Reiter (AdminPostAction). Eine Sperre (Transient) verhindert zwei gleichzeitige Prüfungen.
6.2 Prüfschritte
- Manifeste: Live-Prüfung (§4.3), ohne Cache.
- Modulkatalog: Alle Attributpfade aus
ShortformMapexistieren im Live-Katalog von Divi. Die Logik vontests/Integration/divi-shortform-check.phpwandert dafür ins Plugin; das Skript nutzt danach die Plugin-Klasse. - Format im Speicher: Ein mit dem Plugin ausgelieferter Referenzinhalt (Divi-5-Blockmarkup, deckt die Alltagsmodule ab) wird mit dem Plugin-Parser gelesen und serialisiert und muss byte-identisch herauskommen;
parse_blocks()muss dieselbe Blockstruktur (Namen, Verschachtelung) liefern. - Schreibtest auf Wegwerfseite: privater Entwurf „[LIT MCP Prüfung] {Datum}“ (Post-Typ
page); über den normalen Schreibweg (Composer → Serializer → Seiten-Adapter) je ein Exemplar der Alltagsmodule schreiben; prüfen: Inhalt gespeichert wie serialisiert, Builder-Kennzeichen gesetzt, Rendern über Divi ohne PHP-Fehler/Warnung und mit den erwarteten Texten in der Ausgabe. Kein Eintrag im Änderungsprotokoll. Imfinallyimmerwp_delete_post($id, true)(endgültig, mit Revisionen und Meta); schlägt das fehl, nennt der Bericht die ID zum Löschen von Hand und der Bericht ist rot.
Jeder Schritt meldet grün/rot mit Einzelpunkten. Ein Fehler in einem Schritt bricht die übrigen nicht ab (außer Schritt 4 bei rotem Schritt 1: dann kein Schreibtest).
6.3 Bericht und Freigabe
Der Bericht wird in der Option lit_mcp_divi_check_report gespeichert (letzter Bericht; ID, Zeit, Benutzer, Divi-Version, Plugin-Version, Cache-Schlüssel aus §5.4, Ergebnisse). „Freigeben“ ist nur aktiv – und wird serverseitig nur ausgeführt –, wenn der letzte Bericht vollständig grün ist und Divi-Version, Plugin-Version und Cache-Schlüssel zum aktuellen Stand passen. Freigabe und Zurückziehen werden im Änderungsprotokoll vermerkt.
Hinweis im Bericht (blockiert nichts): „Optional: eine Divi-Seite im Visual Builder öffnen und speichern.“
7. WP-CLI für die Entwicklung
wp lit-mcp divi-check (nur registriert, wenn WP_CLI definiert ist) führt die Prüfschritte aus §6.2 aus und gibt den Bericht aus; Rückgabecode ≠ 0 bei Rot. Freigaben schreibt der Befehl nicht.
--diff: zeigt für jeden roten Mirror den Unterschied zwischen Soll-Quelltext (tests/Fixtures/divi/reference/) und installiertem Quelltext, mit Datei und Zeilen in der installierten Version.--update-reference: schreibt Soll-Fingerabdrücke und Referenz-Quelltexte neu – nur, wenn alle übrigen Prüfschritte grün sind. Gedacht nach dem Anpassen eines Nachbaus.
Ablauf bei neuer Divi-Version: lokal einspielen → wp lit-mcp divi-check → bei Grün Version in die Code-Liste eintragen; bei Rot --diff, Nachbau anpassen, --update-reference, Smoke-Skripte, Version eintragen → Plugin-Release.
8. Daten und Deinstallation
Neu: Optionen lit_mcp_divi_releases, lit_mcp_divi_check_report; Transients lit_mcp_divi_state, Prüfsperre. Uninstaller und uninstall.php-Doku werden ergänzt.
9. Fehlerbehandlung
- Reflection/Tokenisieren scheitert (Funktion fehlt, Datei nicht lesbar): Punkt rot →
incompatible, nie Ausnahme nach außen. - Zustand nicht ermittelbar (unerwartete Ausnahme): wie
incompatiblebehandeln (Schreiben gesperrt), Protokoll-Fehlereintrag. - Admin-Prüfung bricht ab (Timeout, Fatal im Rendern): Wegwerfseite im
finallygelöscht; bei Fatal zusätzlich beim nächsten Aufruf des Reiters nach verwaisten „[LIT MCP Prüfung]“-Entwürfen des Plugins suchen (Marker-Meta) und löschen.
10. Tests
Unit:
- Zustandsberechnung: alle Kombinationen aus Code-Liste, DB-Eintrag (passende/andere Plugin-Version), Live-Prüfung grün/rot.
- Sperre in
AbilityRegistrar: lesend/schreibend × drei Zustände; Fehlercodes und Texte;warningsbei lesenden Tools. - Sperre in Adaptern inkl. Prüfmodus nur für die Wegwerfseiten-ID.
- Fingerabdruck: Kommentar/Leerraum ändert nichts, Codeänderung schon.
- Architekturtest (§3) und Test „jedes Divi-Tool ist als solches erkannt“.
- Freigabe nur bei frischem grünem Bericht (Version, Plugin-Version, Cache-Schlüssel); Rechte und Nonce.
Uninstallerentfernt die neuen Optionen/Transients.
Integration gegen echtes Divi (Smoke-Skript):
- Admin-Prüfung komplett grün; Wegwerfseite danach nicht mehr vorhanden (auch keine Revisionen).
- Künstlich veränderter Soll-Fingerabdruck →
incompatible, schreibendes Tool liefertdivi_incompatible, lesendes Tool liefert Ergebnis + Hinweis. - Version aus Code-Liste entfernt →
untested; nach Admin-Prüfung + Freigabe →released. wp lit-mcp divi-checkgrün;--diffbei verändertem Soll zeigt den Unterschied.
Regression: alle bestehenden Unit-Tests und Smoke-Skripte unverändert grün.
11. Umsetzungsreihenfolge
- Manifest-Format, Fingerabdruck, Architekturtest mit Ausnahmeliste für Altbestand.
- Adapter nacheinander umbauen, bis die Ausnahmeliste leer ist;
DiviCompatibilityauf Manifeste umstellen; Docblock-Zeilennummern entfernen. - Zustand, Freigabe (Code-Liste, Datenbank), zentrale und Adapter-Sperre,
lit-site-status. - Admin-Reiter „Divi“, Prüfschritte, Wegwerfseite, Bericht, Freigabe.
- WP-CLI-Befehl mit
--diffund--update-reference. - Security-Audit; danach Etappe 4.