docs: Notizen und Spec für Etappe 4d (Recherche, Formate-Nachtrag, Rulings W1–W14, offene Kleinpunkte)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
cb41f9e877
commit
bfede30d33
@@ -28,6 +28,23 @@ Geprüft gegen den installierten Quelltext `includes/builder-5/server/Packages/G
|
||||
- **Neuer Typ `gradients`** (`GLOBAL_VARIABLE_TYPES = numbers, strings, images, links, fonts, gradients`); `strings` und `gradients` behalten ihren Wert zeichengetreu. `get_global_variables()` liefert zusätzlich die leere Gruppe `colors`, wandelt Objekt-Gruppen in Arrays und fügt `allowedActions` und die Customizer-Schriften hinzu (jede Gruppe als `stdClass`); beim Zurückschreiben bleiben nur Speicherformat-Felder.
|
||||
- **Archivierte Variablen:** `_sort_global_variable_snapshot()` behandelt `order` archivierter Variablen als `''`; der Builder setzt beim Archivieren `order: null`, das Sanitize macht daraus `''`.
|
||||
|
||||
## Nachtrag Divi 5.15.1 – Theme-Optionen und Schriften (Etappe 4d, 2026-10-19)
|
||||
|
||||
Zeilenangaben und Belege: `2026-10-19-etappe-4d-divi-recherche.md` (Abschnitt 0 und A–D).
|
||||
|
||||
1. **`FontsUtility::font_add()` ist im Prozess aufrufbar:** mit `['action' => 'wp_handle_upload_rest']` nimmt `wp_handle_upload()` serverseitige Temp-Dateien (`copy`/`unlink` statt `move_uploaded_file`), so wie Divis KI-Pfad `AiAgentImageUtility::install_to_custom_fonts()`; ein Nachbau des `et_uploaded_fonts`-Eintrags entfällt.
|
||||
2. **Divi-Rolle für Schriften ist `custom_fonts_management`** (plus `upload_files`), nicht `use_visual_builder`.
|
||||
3. **Divis UI kennt nur `ttf`/`otf`** (`et_pb_get_supported_font_formats()`); `font_add` und das Frontend verarbeiten auch `woff`, `woff2` und `eot` (`mime_types_font()`).
|
||||
4. **Die Standardschrift steht im Customizer als `false`, nicht als `'none'`;** ein gespeichertes `'none'` ist in Divi 5 ein echter Schriftname, „Standard“ heißt deshalb Schlüssel entfernen (`et_delete_option`).
|
||||
5. **Divis Sanitizer klemmen keine Bereiche** (`absint`, `intval`, `floatval`) und liefern bei ungültiger Auswahl `false` statt eines Fehlers; Bereiche gehören ins Plugin.
|
||||
6. **`body_header_style` ist im Control mehrfach wählbar, der Sanitizer nimmt aber genau einen Wert;** Kombinationen und `''` werden zu `false`.
|
||||
7. **`et_builder_get_google_fonts()` kann einen HTTP-Abruf auslösen** (einmal je 24 h, nur mit API-Schlüssel) und lädt sonst 1,3 MB JSON; die Liste wird je Request einmal geholt.
|
||||
8. **`font_add` prüft den Namen nur gegen Google-Fonts und `et_uploaded_fonts`,** nicht gegen Web-Safe-Schriften, und entfernt unzulässige Zeichen stillschweigend.
|
||||
9. **`font_add` meldet Teilerfolg als Erfolg;** das Plugin vergleicht die gelieferten `font_file`-Schlüssel mit der Eingabe und entfernt die Schrift bei Abweichung.
|
||||
10. **`ET_Core_PageResource::remove_static_resources` hat sieben Parameter** (neu: `$skip_external_cache`) und ist ohne angemeldeten Benutzer wirkungslos.
|
||||
11. **`GlobalData::get_customizer_fonts()` cacht per `static` ohne Reset;** Zurücklesen läuft über `get_option('et_divi')`.
|
||||
12. **`et_update_option` schreibt das ganze `et_divi`-Array aus einem Request-Global** (Lost-Update-Risiko bei gleichzeitigen Änderungen); `design_rev` und Sperre mindern es.
|
||||
|
||||
## 0. Grundlagen: wo Divi speichert
|
||||
|
||||
`et_get_option()`/`et_update_option()` (`epanel/custom_functions.php:211`, `:272`) haben drei Ziele:
|
||||
|
||||
@@ -80,3 +80,43 @@ Ansätze vorschlagen → Entwurf abschnittsweise freigeben → Spec schreiben
|
||||
- DesignLock: zwei gleichzeitige Übernahmen einer veralteten Sperre möglich (sehr kleines Fenster); Schreibvorgang > 120 s kann Sperre verlieren
|
||||
- Verwaister @param-Docblock in DiviPresetsDeleteAbility
|
||||
- Smoke divi-presets-smoke.sh läuft nur mit deaktivierten Plugins postlos (Monolog 2) und asynclistry (Deprecated-Ausgabe)
|
||||
|
||||
## Etappe 4d (Plan 2026-10-19-etappe-4d-theme-optionen-schriften.md)
|
||||
|
||||
Belege: `2026-10-19-etappe-4d-divi-recherche.md`; Formate-Nachtrag „Etappe 4d“. Die Rulings amendieren Spec §8 und §10.
|
||||
|
||||
- **W1:** Drei neue Fähigkeiten `theme-option-read`, `theme-option-write` und `font-upload`; der Mirror `customizer-typography` trägt Lesen und Schreiben, die Schriftlisten-Aufrufe tragen `theme-option-write`, `font-upload` und `variable-write`.
|
||||
- **W2:** Whitelist von 20 Theme-Optionen (vier Schriften, zwei Gewichte, Größen, Zeilenhöhen, Abstände, `body_header_style`, vier Layout-Werte); Standards, Bereiche und Sanitizer sind Literale in `ThemeOptionSpec`/`ThemeOptionsAdapter`, gesichert durch den Mirror.
|
||||
- **W3:** „Nicht gesetzt“ ist der Divi-Standard; `null` setzt zurück (`et_delete_option`), `'none'` und `false` werden abgelehnt; Tablet-/Phone-Größen erben, solange sie nicht gesetzt sind.
|
||||
- **W4:** Das Plugin prüft Bereiche, Schritte und Auswahl selbst (Divis Sanitizer klemmen nicht); `body_header_style` nimmt genau einen Wert; Zahlen als Zahl oder Ziffern-String.
|
||||
- **W5:** Schriftnamen gelten exakt (Groß-/Kleinschreibung) gegen Divis gemergte Liste; unbekannt → `validation_failed` mit bis zu fünf ähnlichen Namen; die Liste wird je Request einmal geladen.
|
||||
- **W6:** Snapshot `theme_options` hält die vorhandenen Whitelist-Schlüssel mit Rohwert und Typ; Restore ersetzt die Whitelist vollständig (`et_update_option`/`et_delete_option`) und leert die Caches wie der Customizer.
|
||||
- **W7:** Theme-Optionen haben keinen Seitenbezug; der Probelauf warnt „wirkt auf die gesamte Website“ (bei Schriften auch auf den Builder), `usages` bleibt `null`.
|
||||
- **W8:** Der Upload installiert im Prozess über `FontsUtility::font_add()` mit `wp_handle_upload_rest`; Mirror `font-install`; Formate `woff2`, `woff`, `ttf`, `otf`; Teilerfolg wird erkannt und mit `font_remove` zurückgenommen.
|
||||
- **W9:** Name 1–100 Zeichen aus `A–Z a–z 0–9`, Leerzeichen, `_`, `-`, nicht in Google-, Web-Safe- oder hochgeladenen Schriften; je Datei höchstens `min(Upload-Limit, 5 MB)`, 1–4 Dateien, Magic Bytes passend zur Endung, URL-Regeln über den geteilten `RemoteFileFetcher`.
|
||||
- **W10:** Der Probelauf lädt wirklich herunter (nur Temp-Dateien) und meldet Dateien mit Größe und SHA-256; mit `confirm: true` erneut laden, prüfen, installieren; kein Snapshot.
|
||||
- **W11:** Restore kennt den Bereich `theme_options` (`ThemeOptionsRestorePlanner`); Rechte wie beim Schreiben.
|
||||
- **W12:** Variablen vom Typ `fonts` werden zusätzlich gegen den Schriftkatalog geprüft; `VariableValue` bleibt rein.
|
||||
- **W13:** Divi-Grenzen, die dokumentiert statt behoben sind:
|
||||
- `et_update_option` schreibt das ganze `et_divi`-Array aus dem Request-Global (Lost-Update-Risiko; `design_rev` und Sperre mindern es).
|
||||
- `body_header_style` nimmt in Divi nur einen Wert.
|
||||
- Divi prüft keine Bereiche; das Plugin tut es.
|
||||
- `font_add` meldet Teilerfolg als Erfolg (Plugin vergleicht und nimmt zurück).
|
||||
- `remove_static_resources` wirkt nur mit angemeldetem Benutzer (Smokes laufen mit `--user`).
|
||||
- Divis Leser kennen für `tablet_*`/`phone_*` feste Standards 14 bzw. 30; bei „gleich dem Größeren“ erzeugt Divi keine CSS-Regel.
|
||||
- Zwischen `RemoteFileFetcher::allows()` und dem cURL-Abruf bleibt ein DNS-Rebinding-Fenster (das „IPv4-Pinning“ ist nur `CURL_IPRESOLVE_V4`); Thema für das Security-Audit in 4e.
|
||||
- Schema-Fehler (Bereich, unbekannter Schlüssel) lehnt der MCP-Adapter mit dem Eingabeschema ab, bevor die Tools laufen; sie tragen dann nicht die `validation_failed`-Feldpfade des Plugins.
|
||||
- **W14:** `DesignRights::themeOptions()` verlangt `edit_theme_options` und `theme_customizer` (der Parameter `$writer` ist ungenutzt, B2), `DesignRights::fonts()` verlangt `upload_files`, `edit_theme_options` und `custom_fonts_management`; die Fehlertexte nennen das fehlende Recht und die Divi-Rolle.
|
||||
|
||||
**Folgepunkte (außerhalb 4d):** Schriftprüfung in Preset- und Modul-Attributen; `lit/divi-fonts-list` bzw. Schriftsuche (Vorschläge gibt es nur in Fehlern); Entfernen hochgeladener Schriften (A2); Format `eot`.
|
||||
|
||||
### Offene Kleinpunkte aus 4d (Reviews, nicht merge-relevant)
|
||||
- Theme-Optionen: `ThemeOptionSpec` Zahlen-Regex ohne `/D` („15\n“); Werte neben dem Schritt (1.70000001) werden nicht gerundet; `rev()` von INF/NAN; `effective()` gibt gespeicherte Unwerte bei Auswahlfeldern unverändert zurück; `FontSuggest` rechnet bytebasiert.
|
||||
- Update-Tool: unnötiger Schreibvorgang bei gespeichertem „16“ gegen gesetzte 16 (`ThemeOptionsArea::same` nutzen); Schriftname wird vor dem Trimmen geprüft (" Roboto"); `DesignRights::themeOptions` mit ungenutztem `$writer` samt Test-Mock; kein Hinweis zu Schriftstärken im Builder.
|
||||
- Gespeichertes `false`: Tests für `get`/Planer/Restore und `design_rev`-Vergleich fehlen; ungesetzte, gespeicherte `false`-Schlüssel entfernt `write()` still.
|
||||
- Schrift-Variablen: Test, dass reine Status-/Label-Änderungen den Katalog nicht laden; ein erneut gesendeter Wert einer Schrift, die Divis Liste verlassen hat, wird `validation_failed`.
|
||||
- Upload: `confirm` bindet die im Probelauf gezeigte SHA-256 nicht (optionale Eingabe); der Probelauf prüft den Rohnamen, `install()` nutzt `sanitize_file_name`; `FontInstaller::install()` prüft die Endung nicht selbst gegen `FORMATS`; Meldung bei fehlendem `fileinfo` irreführend; Tests für Fetcher-Ausnahme/Aufräumen und leeres `wp_tempnam` fehlen; nur vier Magic-Byte-Signaturen; gleichzeitiger Upload desselben Namens in anderer Schreibweise.
|
||||
- `FontInstaller` lässt die verschobene Datei in `et-fonts`, wenn `font_add` wirft (nicht-Array `et_uploaded_fonts`); Aufräumen mit `catch Throwable` ergänzen.
|
||||
- Smoke-Skripte: fehlende `file_exists`-Prüfung in Schritt 7, Format-Grep im Probelauf vakuos (stattdessen `sha256`/`bytes` prüfen), Namenskonflikt prüft nicht auf `conflict`, `'none'` nicht isoliert, kein Zurücklesen von `body_font`, EXIT-Trap stellt ganz `et_divi` wieder her (Admin-Änderungen während des Laufs gehen verloren) und räumt Snapshots sowie Dateien fälschlich akzeptierter Schriften nicht auf, Sentinel-Prüfung vakuos, `restore()` verbirgt stderr.
|
||||
- Protokoll: `src/Admin/LogObjects.php` kennt den Objekttyp `divi_font` nicht (Anzeige als Code).
|
||||
- Kleinkram: Reihenfolge der `use`-Blöcke; `DiviLocked`-Rethrow setzt voraus, dass die Sperre vor jedem Schreiben greift.
|
||||
|
||||
@@ -91,4 +91,4 @@ beeinflussen, ohne dass ein Test ihn bräuchte.
|
||||
|
||||
- Der Admin-Hinweis berechnet den Zustand auf jeder Admin-Seite (Reflection und Dateihashes je Aufruf); bei Bedarf
|
||||
kurzlebig cachen.
|
||||
- `DesignArea::feature()`: Farben (`color-write`) und Variablen (`variable-write`) haben seit Etappe 4c eigene Fähigkeiten; Theme-Optionen bekommen ihre mit 4d.
|
||||
- `DesignArea::feature()`: Farben (`color-write`) und Variablen (`variable-write`) haben seit Etappe 4c eigene Fähigkeiten; Theme-Optionen bekommen ihre mit 4d. **Erledigt (4d):** `ThemeOptionsArea::feature()` = `theme-option-write`; neu sind `theme-option-read`, `theme-option-write` und `font-upload` („Theme-Optionen lesen“, „Theme-Optionen schreiben“, „Schriften hochladen“).
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
# Etappe 4d – Divi 5.15.1: Theme-Optionen und Schriften (Code-Recherche)
|
||||
|
||||
Stand: 2026-10-19. Grundlage der Rulings W1–W14 (siehe `2026-09-28-etappe-4-entscheidungen-entwurf.md`, Abschnitt „Etappe 4d“). Die Befunde in Abschnitt 0 sind in den Formate-Nachtrag „Etappe 4d“ übernommen.
|
||||
|
||||
Quelle: installiertes Divi 5.15.1 (`style.css:4`), WordPress 7.1.3. Alle Pfade relativ zu `wp-content/themes/Divi`, sofern nicht anders angegeben. Nur aus Code abgeleitet; die Zeilen der Formate-Notiz §4 (5.2.1) sind durchweg um ca. +80 verschoben.
|
||||
|
||||
## 0. Überraschungen gegenüber Spec §8 (Kurzfassung)
|
||||
|
||||
1. **`FontsUtility::font_add()` ist in-process aufrufbar.** `wp_handle_upload()` nimmt `$overrides['action']` als Action (`wp-admin/includes/file.php:1110`); nur bei Action `'wp_handle_upload'` prüft `_wp_handle_upload` `is_uploaded_file()`/`move_uploaded_file()` (`file.php:936`, `:1019-1027`), sonst `is_readable()` + `copy()`/`unlink()`. Divi übergibt selbst `['action' => 'wp_handle_upload_rest']` (`CustomFontController.php:68-75`) und installiert so **serverseitige Temp-Dateien**: `AiAgentImageUtility::install_to_custom_fonts()` (`includes/builder-5/server/VisualBuilder/AiAgent/AiAgentImageUtility.php:860-1009`, `wp_tempnam` → `copy` → `font_add([...'tmp_name'=>$temp...], …, ['action'=>'wp_handle_upload_rest'])`). → Kein eigener Sideload und kein Nachbau des `et_uploaded_fonts`-Eintrags nötig; Spec §8.2 („nur echte Browser-Uploads“, „Nachbau mit Fingerabdruck“) ist überholt. Mirror höchstens für die *Aufrufkonvention* (`install_to_custom_fonts`).
|
||||
2. **Divi-Rolle für Schriften ist `custom_fonts_management`**, nicht `use_visual_builder` (`CustomFontController.php:141-152`, `:214-225`; Rollen-Editor `includes/builder/functions.php:9595`). Plus `upload_files`. Spec §10 nachziehen.
|
||||
3. **Standard-Formate nur `ttf`, `otf`:** `et_pb_get_supported_font_formats()` (`includes/builder/core.php:5090`, Filter `et_pb_supported_font_formats`). Der REST-Store nimmt nur diese Felder an; `font_add` selbst akzeptiert alles aus `mime_types_font()` (otf, ttf, woff, woff2, eot), das Frontend (`et_builder_enqueue_user_fonts`, `includes/builder/functions.php:3813ff`) gibt alle fünf aus. woff/woff2 sind also technisch möglich, aber über Divis UI nicht vorgesehen → Entscheidung nötig.
|
||||
4. **„Standard-Schrift“ wird im Customizer als `false` gespeichert, nicht als `'none'`.** `et_sanitize_font_choices('none')` → `false` (`'none'` steht nicht in `et_builder_get_fonts()`), WP speichert `false` (nur `null`/`WP_Error` werden verworfen, `wp-includes/class-wp-customize-manager.php:1848-1851`). Leser: Divi-4-CSS/Google-URL `et_pb_get_specific_default_font()` behandelt `false`/`''`/`'none'` gleich (`functions.php:1287-1290`, lose `in_array`); Divi 5 `Fonts::enqueue()` und `GlobalData::get_customizer_fonts()` nehmen bei *fehlendem* Schlüssel `'Open Sans'`, bei `false` ebenfalls `'Open Sans'` (`FrontEnd/Module/Fonts.php:100-129`), bei `'none'` aber `self::add('none')` (`:138-144`). → „Standard“ = Schlüssel entfernen (`et_delete_option`), nie `'none'` schreiben.
|
||||
5. **Divis Sanitizer prüfen keine Bereiche.** `absint`, `intval`, `floatval` klemmen nicht auf min/max der Controls; `et_sanitize_*_choices` liefern bei Unbekanntem `false` (kein Fehler). Plugin muss Bereiche aus den Control-`input_attrs` selbst prüfen und `false` als Ablehnung werten.
|
||||
6. **`body_header_style` ist im Control mehrfach wählbar (`italic|uppercase`, Checkbox-Liste mit `|`, `functions.php:5457-5481`), der Sanitizer `et_divi_global_font_style` akzeptiert aber nur genau einen Schlüssel** → jede Kombination und auch `''` (alles abgewählt) wird zu `false`. Divi-Bug; Tool sollte nur einen Wert (oder „unset“) zulassen.
|
||||
7. **`et_builder_get_google_fonts()` kann einen HTTP-Request auslösen** (`et_builder_google_fonts_sync()`, `includes/builder/core.php:4868-4905`: einmal je 24 h per Transient `fonts_cache_status`, nur wenn Google-API-Key gesetzt). Sonst Option `et_google_fonts_cache` bzw. 1,3-MB-JSON (`core/json-data/google-fonts.json`, 1945 Familien), statisch gecacht. `et_sanitize_font_choices` ruft das bei jedem Aufruf (ksort über ~1950 Einträge) → Liste je Request einmal holen.
|
||||
8. **Namens-Eindeutigkeit in `font_add` prüft nur Google-Fonts und `et_uploaded_fonts`, nicht Web-Safe-Fonts** (`FontsUtility.php:125-131`) – „Arial“ wäre hochladbar. Plugin-Regel strenger halten.
|
||||
9. **`font_add` meldet Teilerfolg als Erfolg:** schlägt eine von mehreren Dateien fehl, wird die Schrift mit den übrigen gespeichert, die Fehler gehen verloren (`FontsUtility.php:157-190`). Plugin: vorab jede Datei mit `HooksRegistration::check_filetype_and_ext_font()` prüfen (wie Divis AI-Pfad) und Ergebnis `font_file`-Schlüssel gegen Eingabe vergleichen.
|
||||
10. **`ET_Core_PageResource::remove_static_resources` hat jetzt 7 Parameter** (`+ $skip_external_cache`, `core/components/PageResource.php:1398`); Signatur-Fingerabdruck prüfen.
|
||||
11. **`GlobalData::get_customizer_fonts()` cached per `static` ohne Reset** (`GlobalData.php:446-451`) → Zurücklesen nach dem Schreiben im selben Request über `get_option('et_divi')`/`et_get_option`, nicht darüber.
|
||||
12. **`et_update_option` schreibt das ganze `et_divi`-Array aus dem Request-Global `$et_theme_options`** (`epanel/custom_functions.php:297-310`); wurde das Global früher im Request geladen und die Option inzwischen von einem anderen Prozess geändert, werden dessen Änderungen überschrieben (Lost Update). Für `design_rev`-Vergleich und Snapshot `get_option('et_divi')` lesen; Restrisiko dokumentieren.
|
||||
|
||||
## A. Theme-Optionen
|
||||
|
||||
Allgemein für alle 20 Settings (Registrierung in `et_divi_customizer_theme_settings()`, `functions.php:1371ff`, Hook `customize_register` → `et_divi_customize_register` `functions.php:1306`/`:1363`):
|
||||
- `type => 'option'`, ID `et_divi[<key>]` → Speicher `get_option('et_divi')[<key>]` (Divi: `$shortname = 'divi'`, `$et_store_options_in_one_row = true`, `functions.php:16-17`).
|
||||
- `capability => 'edit_theme_options'`, `transport => 'postMessage'`.
|
||||
- Sanitizer sind **globale Funktionen**, immer geladen: `includes/functions/sanitization.php` und `choices.php` werden in `et_setup_theme()` (`after_setup_theme`, `functions.php:50-52`, `:150`) ohne Bedingung eingebunden; Builder-Listen in `includes/builder/core.php` (immer geladen). WP ruft sie als Filter `customize_sanitize_{id}` mit `($value, $setting)` (`class-wp-customize-setting.php:581`); alle Divi-Sanitizer nehmen nur `$value`, also direkt mit 1 Argument aufrufbar. Kein Customizer-Kontext nötig.
|
||||
- Rückgabe `false` bei ungültiger Auswahl (`et_sanitize_key_based_option($choosen, $options, $default = false)`, `sanitization.php:45-52`; `isset($options[$choosen])`, also **case-sensitiv**, numerische String-Schlüssel ≙ int).
|
||||
- Gespeicherte Typen: `absint` → int, `et_sanitize_float_number` → float, `et_sanitize_int_number` → int, Auswahl-Sanitizer → der übergebene Wert (String) oder `false`.
|
||||
|
||||
| Schlüssel | Setting (file:line) | Standard (Setting) | sanitize_callback (Definition) | Control / Choices / min–max–step | Zusammenspiel / Leser |
|
||||
|---|---|---|---|---|---|
|
||||
| `heading_font` | `functions.php:2563-2572`, Control `:2574-2586` | `'none'` | `et_sanitize_font_choices($choosen)` `sanitization.php:59-66` (Google+Websafe via `et_builder_get_fonts()` + `et_builder_get_custom_fonts()`) | `ET_Divi_Select_Option`, `type select`, Choices `$font_choices` (`functions.php:1407-1440`: `'none'` + alle Fonts, im UI nach Locale-Zeichensatz gefiltert, Sanitizer filtert **nicht** nach Locale) | `'none'` → `false` gespeichert (§0.4). Builder/D5-Sicht `'Open Sans'` (`GlobalData::$customizer_fonts` `GlobalData.php:108-119`, `Fonts.php:100`). Speist `--et_global_heading_font` (`Fonts.php:148-175`), D4-Font-URL `functions.php:432`, `:7216`, `et_builder_get_font_family('--et_global_heading_font')` `includes/builder/core.php:4683-4686`. Alias `Source Sans Pro`→`Source Sans 3` nur im D5-Enqueue (`Fonts.php:113-127`). |
|
||||
| `body_font` | `functions.php:2636-2645`, Control `:2647-2659` | `'none'` | `et_sanitize_font_choices` | wie oben | wie oben, `--et_global_body_font`; zusätzlich `functions.php:334`, `:474`, `includes/builder/functions.php:4254`, `Fonts.php:134-136` (`'none'`/`''` = „Theme lädt Open Sans selbst“). |
|
||||
| `primary_nav_font` | `functions.php:3477-3486`, Control `:3488-3500` | `'none'` | `et_sanitize_font_choices` | Select, `$font_choices` (Section `et_divi_header_primary`) | nur D4-Header/Google-URL (`functions.php:435`); kein D5-Global. |
|
||||
| `secondary_nav_font` | `functions.php:3601-3610`, Control `:3612-3624` | `'none'` | `et_sanitize_font_choices` | Select, `$font_choices` (Section `et_divi_header_secondary`) | `functions.php:436`; kein D5-Global. |
|
||||
| `heading_font_weight` | `functions.php:2588-2597`, Control `:2599-2611` | `'500'` | `et_sanitize_global_font_weight($choosen)` `sanitization.php:345-347` | `ET_Divi_Custom_Select_Option`, Choices `et_builder_get_font_weight_list()` (`includes/builder/core.php:4792-4807`: `'100'…'900'`, Filter `et_builder_all_font_weights`) | `--et_global_heading_font_weight` (`Fonts.php:151`, leer → `'500'`), D4-CSS `functions.php:5827`, `:6943ff` (nur wenn ≠ 500). |
|
||||
| `body_font_weight` | `functions.php:2661-2670`, Control `:2672-2684` | `'500'` | `et_sanitize_global_font_weight` | wie oben | `--et_global_body_font_weight`, `functions.php:5828`, `:5992ff`. |
|
||||
| `body_font_size` | `functions.php:2287-2296`, Control `:2298-2313` | `'14'` | `absint` (WP) | `ET_Divi_Range_Option`, `range` 10–32, step 1 | `--et_global_body_font_size` (`Fonts.php:104-107`, `''` → 14), D4 `functions.php:5819`, VB-Settings `SettingsDataCallbacks.php:2379`. |
|
||||
| `tablet_body_font_size` | `functions.php:2371-2380`, Control `:2382-2397` | `et_get_option('body_font_size','14')` (dynamisch) | `absint` | Range 10–32, step 1 (Section `et_divi_mobile_tablet`) | Leser nehmen fest `'14'` (`functions.php:5841`, `Fonts.php:108`), CSS nur wenn `≠14 && ≠ body` (`functions.php:7019`) → unset ≙ erbt Desktop. |
|
||||
| `phone_body_font_size` | `functions.php:2343-2352`, Control `:2354-2369` | `et_get_option('tablet_body_font_size','14')` | `absint` | Range 10–32, step 1 (`et_divi_mobile_phone`) | Leser: Standard = Tablet-Wert (`functions.php:5846`, `Fonts.php:109`); CSS nur wenn `≠14 && ≠ tablet` (`:7112`). |
|
||||
| `body_header_size` | `functions.php:2399-2408`, Control `:2410-2425` | `'30'` | `absint` | Range 22–72, step 1 | `functions.php:5821`, VB `SettingsDataCallbacks.php:2391`. |
|
||||
| `tablet_header_font_size` | `functions.php:2535-2544`, Control `:2546-2561` | `et_get_option('body_header_size','30')` | `absint` | Range 22–72, step 1 | Leser fest `'30'` (`functions.php:5840`), CSS nur wenn `≠30 && ≠ body_header_size` (`:7039`). |
|
||||
| `phone_header_font_size` | `functions.php:2507-2516`, Control `:2518-2533` | `et_get_option('tablet_header_font_size','30')` | `absint` | Range 22–72, step 1 | Standard = Tablet (`functions.php:5845`), CSS `:7132`. |
|
||||
| `body_font_height` | `functions.php:2315-2324`, Control `:2326-2341` | `'1.7'` | `et_sanitize_float_number($number)` `sanitization.php:7-9` (`floatval`) | Range 0.8–3, step 0.1 | `--et_global_body_font_height` (`Fonts.php:105-107`, Einheit `em`), D4 `functions.php:5820`, VB `:2378`. |
|
||||
| `body_header_height` | `functions.php:2455-2464`, Control `:2466-2481` | `'1'` | `et_sanitize_float_number` | Range 0.8–3, step 0.1 | D4 `functions.php:5824`, `:6604`. |
|
||||
| `body_header_spacing` | `functions.php:2427-2436`, Control `:2438-2453` | `'0'` | `et_sanitize_int_number($number)` `sanitization.php:16-18` (`intval`) | Range −2–10, step 1 | D4 `functions.php:5823`, `:6604`. Negativ erlaubt. |
|
||||
| `body_header_style` | `functions.php:2483-2492`, Control `:2494-2505` | `''` | `et_divi_global_font_style($choosen)` `sanitization.php:358-360` | `ET_Divi_Font_Style_Option` (`functions.php:5457`, Checkboxen, Wert `a|b`), Choices `et_divi_global_font_style_choices()` (`includes/functions/choices.php:23-33`: `italic`, `uppercase`, `underline`; Filter `et_divi_global_font_style_choices`) – **kein `bold`** (das gibt es nur bei `et_divi_font_style_choices`/`et_sanitize_font_style`) | Sanitizer nimmt nur genau einen Wert, `''` und Kombinationen → `false` (§0.6). Leser `et_get_option('body_header_style','','',true)` + `et_pb_print_font_style()` (`functions.php:5822`, `:6616`). |
|
||||
| `content_width` | `functions.php:1903-1912`, Control `:1914-1929` | `'1080'` | `absint` | Range 960–1920, step 1 (`et_divi_general_layout`) | D4 `functions.php:5833`, `:6133`; VB `SettingsDataCallbacks.php:2387`. |
|
||||
| `gutter_width` | `functions.php:1931-1940`, Control `:1942-1957` | `'3'` | `absint` | Range 1–4, step 1 | Standard für Section/Row-`gutter_width` (D4 `includes/builder/main-structure-elements.php:239`, `:1953`), Body-Klasse `functions.php:8581`. In D5-Servercode kein Leser gefunden. |
|
||||
| `section_padding` | `functions.php:2006-2015`, Control `:2017-2032` | `'4'` | `absint` | Range 0–10, step 1 | D4 `functions.php:5837`. |
|
||||
| `row_padding` | `functions.php:2090-2099`, Control `:2101-2116` | `'2'` | `absint` | Range 0–10, step 1 | D4 `functions.php:5838`. |
|
||||
|
||||
Abhängige Standards: `tablet_*` / `phone_*` werden im Customizer beim Registrieren aus dem aktuellen Größeren berechnet; die CSS-Leser nutzen feste 14/30 und „gleich dem Größeren = keine Regel“. Für das Tool: Standard von `tablet_body_font_size` = effektiver `body_font_size`, `phone_*` = effektiver `tablet_*`; „unset“ heißt „erbt“.
|
||||
|
||||
### A.1 Builder-Globals (`--et_global_*`)
|
||||
|
||||
- `GlobalData::$customizer_fonts` (`includes/builder-5/server/Packages/GlobalData/GlobalData.php:108-119`): `--et_global_heading_font` → `heading_font`, `--et_global_body_font` → `body_font`, beide Standard `'Open Sans'`. `get_customizer_fonts()` (`:446-470`) liefert `{id,label,value,status:'active',order}`, `static` gecacht.
|
||||
- Frontend-Variablen (`FrontEnd/Module/Fonts.php:99-191`, `Fonts::enqueue()`): `--et_global_heading_font`, `--et_global_body_font`, `--et_global_heading_font_weight`, `--et_global_body_font_weight`, `--et_global_body_font_size` (+ responsive aus `tablet_/phone_body_font_size`), `--et_global_body_font_height` – also speisen **heading_font, body_font, heading_font_weight, body_font_weight, body_font_size, tablet_body_font_size, phone_body_font_size, body_font_height** Divi-5-Globals; inline ausgegeben (`<style class="et-vb-global-data et-vb-global-fonts">`), nicht im Static-CSS gecacht.
|
||||
- REST `POST /global-data/global-fonts` (`includes/builder-5/server/VisualBuilder/REST/RESTRegistration.php:1677`) → `GlobalDataController::update_global_fonts()` (`GlobalDataController.php:166-191`): `et_update_option('heading_font', …)`, `et_update_option('body_font', …)` (Args `required`, nur `sanitize_text_field`, `:215-227`, **keine Font-Prüfung**), dann `ET_Core_PageResource::remove_static_resources('all','all',true)`. Rechte nur `edit_posts` (`:243-249`) + Routen-Nonce. Weitere Schreiber derselben Schlüssel: AJAX `et_update_customizer_fonts` (`includes/builder/functions.php:13583-13603`, `edit_theme_options`), Import `PortabilityPost.php:4130-4136`.
|
||||
|
||||
### A.2 Was ein Customizer-Speichern zusätzlich tut
|
||||
|
||||
- WP schreibt das Setting direkt per `update_option('et_divi', …)` (multidimensional), **nicht** über `et_update_option`.
|
||||
- `customize_save_after`-Hooks in Divi (vollständig per grep): `ET_Core_PageResource::customize_save_after_cb` → `remove_static_resources('all','all')` (`core/components/PageResource.php:953`, `:1252-1254`) und `et_pb_force_regenerate_templates` (`includes/builder/core.php:3811-3817`, `:3825`: `et_update_option('et_pb_clear_templates_cache', true)` + `et_fb_delete_builder_assets()` `core.php:6592ff`, löscht VB-Helper-JS/`.data`/Bild-Caches).
|
||||
- Keine Hooks auf `update_option_et_divi` / `pre_update_option_et_divi` in Divi.
|
||||
- `remove_static_resources` (`PageResource.php:1398-1417`): wirkungslos bei `DOING_AUTOSAVE`, ohne `wp_doing_cron()` bzw. `et_core_security_check_passed('edit_posts')`, oder ohne Schreibrecht im Dateisystem; `$force` löscht nur zusätzlich die Option `et_core_page_resource_remove_all` (`:1596-1598`); `$skip_external_cache=false` ruft `et_core_clear_wp_cache()` (Fremd-Page-Caches). Die Customizer-CSS liegt im Static-Resource `et-divi-customizer-global-*` (`functions.php:5790`, `:7331`) und wird damit invalidiert.
|
||||
- `et_update_option` (`epanel/custom_functions.php:276-315`): lädt `$et_theme_options` nur, wenn das Global fehlt oder `is_customize_preview()`; setzt Schlüssel, `update_option('et_divi', $et_theme_options)`; aktualisiert damit auch das Global (spätere `et_get_option` im Request sehen den neuen Wert). Keine weiteren Seiteneffekte.
|
||||
|
||||
### A.3 Minimale korrekte In-Process-Schreibfolge (≙ Customizer-Speichern)
|
||||
|
||||
1. Rechte: `current_user_can('edit_theme_options')` **und** `et_pb_is_allowed('theme_customizer')` (Customizer: `functions.php:1357`, `wp_die`; Rollen-Editor `includes/builder/functions.php:9523`). `et_pb_is_allowed` (`includes/builder/core.php:1136-1170`) ist ohne Eintrag im Rollen-Editor `true` (nicht „dangerous“); nur eine Fähigkeit je Aufruf übergeben (bei Arrays entscheidet die erste gespeicherte).
|
||||
2. Je Schlüssel: Divi-Sanitizer aufrufen; `false` → Validierungsfehler (statt wie Divi `false` zu speichern); Bereich aus Tabelle selbst prüfen; Ergebnis vergleichen (z. B. `absint('15.7')` = 15 → als Änderung melden oder ablehnen).
|
||||
3. Schreiben: `et_update_option($key, $sanitized)` je Schlüssel; „unset“: `et_delete_option($key)`.
|
||||
4. Caches: `ET_Core_PageResource::remove_static_resources('all', 'all')` (Customizer) – oder `('all','all',true)` wie `global-fonts`; plus `et_pb_force_regenerate_templates()`. Benutzer muss angemeldet sein (`edit_posts`).
|
||||
5. Zurücklesen: `get_option('et_divi')` (WP-Cache wird von `update_option` aktualisiert), nicht `GlobalData::get_customizer_fonts()`.
|
||||
|
||||
## B. Schriften
|
||||
|
||||
### B.1 Listen
|
||||
|
||||
| Funktion | Ort | Signatur | Rückgabe / Kosten |
|
||||
|---|---|---|---|
|
||||
| `et_builder_get_google_fonts()` | `includes/builder/core.php:4911-4929` | `()` | `[] ` wenn Google Fonts aus (`et_core_use_google_fonts()`, `core/functions.php:223-228`, Option `et_google_api_settings['use_google_fonts']`, Standard `'on'`). Sonst ruft **`et_builder_google_fonts_sync()`** (`:4868-4905`, ggf. `wp_remote_get` an Google, 1×/24 h, nur mit API-Key) und liefert Option `et_google_fonts_cache` (Array oder JSON-String, dann jedes Mal geparst) bzw. `et_core_get_saved_google_fonts()` (`core/functions.php:1970-1985`, 1,3 MB JSON, 1945 Familien, `static`). Filter `et_builder_google_fonts`. Form: `Family => {styles:'100,100italic,…', character_set:'latin,…', type:'sans-serif|serif|display|handwriting|monospace', is_variable:bool, axes:[{tag,min,max,default?}]}` (`et_core_parse_google_fonts_json`, `core/functions.php:1898-1958`, `ksort`). |
|
||||
| `et_builder_get_websafe_fonts()` | `core.php:4783-4785` | `()` | → `et_core_get_websafe_fonts()` (`core/functions.php:1993-2030`): `Arial`, `Georgia`, `Times New Roman`, `Trebuchet`, `Verdana` mit `styles`, `character_set`, `type`, ggf. `add_ms_version`; Filter `et_websafe_fonts`. |
|
||||
| `et_builder_get_fonts( $settings = array() )` | `core.php:4730-4751` | 0–1 Arg (`prepend_standard_fonts`) | Websafe + Google, `ksort`; bei abgeschalteten Google Fonts nur Websafe. **Ohne** hochgeladene Schriften. |
|
||||
| `et_builder_get_custom_fonts()` | `core.php:4822-4831` | `()` | `get_option('et_uploaded_fonts', [])`, nicht-Array → `[]`, Filter `et_builder_custom_fonts`. |
|
||||
| `et_builder_get_font_family( $font_name, $use_important = false )` | `core.php:4683-4723` | 1–2 | CSS-String `font-family: '…', <stack>;` – kein Listen-Lieferant. Löst `--et_global_*_font` auf. |
|
||||
| `et_builder_old_fonts_mapping()` | `core.php:4839ff` | `()` | Alt-Namen (`Raleway Light`, `Open Sans Light` …) → `parent_font` + Gewicht. |
|
||||
| `et_builder_get_font_weight_list()` | `core.php:4792-4807` | `()` | `'100'…'900'` → Label. |
|
||||
|
||||
Gesamtliste wie der Customizer-Sanitizer: `array_merge(et_builder_get_custom_fonts(), et_builder_get_fonts())` (`sanitization.php:59-66`). Gültiger Wert = **exakter Familienname als Schlüssel** (case-sensitiv), keine `:`/`|`-Qualifizierer; `'none'` ist kein Schlüssel. Gewichte/Stile sind eigene Settings.
|
||||
|
||||
### B.2 Hochgeladene Schriften
|
||||
|
||||
**Option `et_uploaded_fonts`** (autoload Standard), geschrieben von `FontsUtility::font_add()`:
|
||||
```
|
||||
'<Name>' => [
|
||||
'font_file' => [ '<ext>' => esc_url('<absoluter Dateipfad>') , … ], // Pfad durch esc_url
|
||||
'font_url' => [ '<ext>' => esc_url('<URL>'), … ],
|
||||
'styles' => '100,200,…,900' | '<eingegebene Liste>', // nur wenn $font_settings nicht leer
|
||||
'type' => '<generic_family>' | 'serif', // nur wenn $font_settings nicht leer
|
||||
]
|
||||
```
|
||||
(Divi-4-Altformat von `et_pb_add_font`, `includes/builder/core.php:5183-5270`, ist gleich; `font_file`/`font_url` können dort auch Strings sein – `et_builder_enqueue_user_fonts` behandelt beides, `functions.php:3818`, `:3869`.)
|
||||
|
||||
**`FontsUtility::font_add( array $font_files, string $font_name, array $font_settings, array $overrides = [] )`** (`includes/builder-5/server/VisualBuilder/Fonts/FontsUtility.php:102-213`, Namespace `ET\Builder\VisualBuilder\Fonts`):
|
||||
- `$font_files`: `['<ext>' => <$_FILES-Element {name,type,tmp_name,error,size}>]` (nicht Pfade, trotz Docblock). Leer → `WP_Error file_empty`.
|
||||
- Name: `preg_replace('/[^A-Za-z0-9\s\_-]/', '', $name)` (stilles Entfernen, kein Fehler) → leer: `font_name_empty`; > `FONT_NAME_MAX_LENGTH` (100, `:39`) Zeichen nach `StringUtility::strlen_utf8`: `font_name_too_long`; bereits in `get_option('et_uploaded_fonts')` (ungefiltert) oder `et_builder_get_google_fonts()` (exakt, case-sensitiv): `font_name_exists`. Websafe nicht geprüft. Der tatsächlich gespeicherte Name steht in `uploaded_font` der Rückgabe.
|
||||
- Ablage: `add_filter('upload_dir', [HooksRegistration::class, 'upload_dir_font'])` → `<uploads basedir>/et-fonts`, URL `<baseurl>/et-fonts`, `subdir '/et-fonts'` (keine Jahr/Monat-Ordner; `HooksRegistration.php:318-332`); `add_filter('wp_check_filetype_and_ext', [HooksRegistration::class, 'check_filetype_and_ext_font'], 999, 3)`; beide nach der Schleife entfernt (`:174-178`).
|
||||
- Je Datei `wp_handle_upload($file, wp_parse_args(['test_size'=>true,'test_type'=>true,'test_form'=>false], $overrides))` → die drei Tests sind fest, `action` (und andere Overrides wie `unique_filename_callback`, `mimes`) kommen durch. Dateiname `wp_unique_filename` → keine Überschreibung.
|
||||
- Typprüfung `check_filetype_and_ext_font` (`HooksRegistration.php:77-127`): mit `fileinfo`: Endung (lowercase) muss in `mime_types_font()` stehen und `finfo` (Magic) einen der MIME-Typen liefern: otf `font/otf|application/x-font-opentype|application/x-font-ttf|application/vnd.ms-opentype`, ttf `font/ttf|font/sfnt|application/font-sfnt|application/x-font-ttf`, woff `font/woff|application/font-woff`, woff2 `font/woff2|application/font-woff2`, eot `application/vnd.ms-fontobject` (`FontsUtility.php:290-316`); `proper_filename = sanitize_file_name()`. Ohne `fileinfo`: Fallback auf WPs Ergebnis. **Achtung:** `_wp_handle_upload` lässt bei `current_user_can('unfiltered_upload')` auch fehlgeschlagene Typprüfung durch (`wp-admin/includes/file.php:971`) → eigene Magic-Byte-Prüfung vorab ist Pflicht (Spec hat sie schon).
|
||||
- Gewichte: `font_weights` fehlt oder `'all'` → `'100,200,300,400,500,600,700,800,900'`, sonst **ungeprüft übernommen**; `generic_family` ungeprüft, Standard `'serif'`. Kein Größenlimit außer `test_size` (>0).
|
||||
- Ergebnis: mind. eine Datei ok → `update_option('et_uploaded_fonts', …)`, `do_action('divi_visual_builder_fonts_custom_font_added')` (→ `et_fb_delete_builder_assets`, `HooksRegistration.php:345`), Rückgabe `['uploaded_font' => $name, 'updated_fonts' => $all]`. Keine Datei ok → `WP_Error` (gesammelte Upload-Fehler, ggf. `fileinfo_extension_not_loaded`, sonst `upload_error_unknown`).
|
||||
- **Keine** Rechte-/Nonce-Prüfung in `font_add`/`font_remove`; die liegt im REST-Controller: `CustomFontController::store_permission()` / `destroy_permission()` (`includes/builder-5/server/VisualBuilder/REST/CustomFont/CustomFontController.php:141-152`, `:214-225`): `upload_files` + `et_pb_is_allowed('custom_fonts_management')`; Routen `POST /custom-font/add`, `/custom-font/remove` (`RESTRegistration.php:1168-1183`) mit Divi-Routen-Nonce. Store nimmt nur `et_pb_font_file_<fmt>` für `et_pb_get_supported_font_formats()` (Standard ttf, otf).
|
||||
|
||||
**In-process mit Nicht-HTTP-Dateien:** möglich. `wp_handle_upload()` setzt `$action = $overrides['action'] ?? 'wp_handle_upload'` (`wp-admin/includes/file.php:1110`); `_wp_handle_upload` prüft `is_uploaded_file()` und nutzt `move_uploaded_file()` nur bei `'wp_handle_upload' === $action`, sonst `is_readable()`, `filesize()`, `copy()` + `unlink(tmp)`; zusätzlich laufen `{$action}_prefilter`/`{$action}_overrides`-Filter (also `wp_handle_upload_rest_prefilter`, nicht `wp_handle_upload_prefilter`). Divi macht genau das in `AiAgentImageUtility::install_to_custom_fonts()` (`AiAgentImageUtility.php:860-1009`): `check_filetype_and_ext_font()` vorab, `wp_tempnam($filename)`, `copy`, `font_add([$ext => ['name'=>$filename,'type'=>$mime,'tmp_name'=>$temp,'error'=>0,'size'=>filesize($temp)]], $name, ['font_weights'=>'all','generic_family'=>'sans-serif'], ['action'=>'wp_handle_upload_rest'])`, danach Temp löschen. → Plugin: `wp_safe_remote_get` → Temp (`wp_tempnam`, Name mit korrekter Endung) → Magic-Bytes + `check_filetype_and_ext_font` → `font_add(..., ['action' => 'wp_handle_upload_rest'])`. **Kein Sideload-Nachbau, kein Nachbau des Options-Formats.** `wp_handle_sideload` wäre gleichwertig, aber unnötig.
|
||||
|
||||
**`FontsUtility::font_remove( string $font_name )`** (`:242-276`): `''` → `file_name_empty`; fehlt Schlüssel oder `font_file` → `font_not_exist`; jede Datei `et_pb_safe_unlink_font_file()` (`includes/builder/core.php:5336-5381`: nur echte Pfade unter `uploads/et-fonts`, Font-Endung), `unset`, `update_option`, `do_action('divi_visual_builder_fonts_custom_font_removed')`. Für Rollback nach fehlgeschlagenem Zurücklesen nutzbar.
|
||||
|
||||
**Zu rufende Divi-Symbole für den Upload:** `FontsUtility::font_add` (4), `HooksRegistration::check_filetype_and_ext_font` (3, Vorprüfung je Datei), `FontsUtility::mime_types_font` (0, erlaubte Endungen), `FontsUtility::FONT_NAME_MAX_LENGTH` (Konstante), `et_pb_get_supported_font_formats` (0, falls Divi-UI-Formate gelten sollen), `et_builder_get_google_fonts` (0) / `et_builder_get_websafe_fonts` (0) / `et_builder_get_custom_fonts` (0) für Namensprüfung, `et_pb_is_allowed` (1, `custom_fonts_management`), optional `FontsUtility::font_remove` (1) für Rollback. `HooksRegistration::upload_dir_font` muss nicht gerufen werden (setzt `font_add` selbst).
|
||||
|
||||
**Mirror-Kandidaten (statt Speicher-Nachbau):**
|
||||
- `new Mirror('font-install', 'includes/builder-5/server/VisualBuilder/AiAgent/AiAgentImageUtility.php', 'install_to_custom_fonts', 'AiAgentImageUtility', 'Aufrufkonvention von font_add mit Temp-Datei (check_filetype_and_ext_font, wp_tempnam, action wp_handle_upload_rest)')` – fängt, wenn Divi den In-Process-Weg ändert.
|
||||
- Optional `new Mirror('font-add', 'includes/builder-5/server/VisualBuilder/Fonts/FontsUtility.php', 'font_add', 'FontsUtility', 'Namensregeln und Eintragsformat von et_uploaded_fonts (Plugin-Vorprüfung, Rückgabe-Vergleich)')` – nur nötig, wenn das Plugin Namensregeln (Regex, 100 Zeichen, Kollision) vorab nachbildet, um im Probelauf ohne Upload zu melden.
|
||||
- `new Mirror('customizer-font-sanitize', 'includes/functions/sanitization.php', 'et_sanitize_font_choices', null, …)` nur, wenn die Font-Validierung nicht über den Sanitizer, sondern über die gemergte Liste nachgebaut wird.
|
||||
|
||||
## C. Snapshot / Restore „theme_options“
|
||||
|
||||
- Inhalt: genau die 20 Whitelist-Schlüssel aus `get_option('et_divi')`, je Schlüssel **vorhanden + Rohwert (mit Typ: int/float/string/false)** oder **nicht vorhanden**. Darstellung z. B. `{"set": {key: value, …}, "unset": [key, …]}` oder Wert-Objekt `{present: bool, value}` – wichtig ist die Unterscheidung „fehlt“ vs. `false` vs. `''`, weil `et_get_option` bei vorhandenem Schlüssel (auch `false`) den Wert, sonst den Standard liefert (`custom_functions.php:238`, `:246-248`; Bedingung `! empty($default_value)`). Farben (`accent_color` …) nicht hier (Snapshot `colors`).
|
||||
- Restore: für „vorhanden“ `et_update_option($key, $raw)` (Rohwert ohne Sanitizer zurückschreiben – er stammt aus Divi), für „fehlt“ `et_delete_option($key)`; danach Caches wie A.3. `et_update_option` allein reicht nicht, weil es Schlüssel nicht entfernen kann.
|
||||
- `et_delete_option( $option_name )` (`epanel/custom_functions.php:320-333`, 1 Arg, untypisiert): lädt das Global nur, wenn nicht gesetzt (ignoriert `is_customize_preview`), `unset`, `update_option('et_divi', …)`. Entfernt den Schlüssel also wirklich. Sonderfall: ist `et_divi` gar nicht vorhanden (`false`), schreibt es `false` zurück (unkritisch).
|
||||
- „Unset“ im Tool-Input: eigener Wert (z. B. `null` = „auf Divi-Standard zurück“) → `et_delete_option`. Nicht `'none'`, nicht `false` schreiben.
|
||||
- `get` liefert Divi-Standard je Feld aus der Tabelle (Settings-`default`; für `tablet_*`/`phone_*` den effektiven Wert des Größeren; für Schriften Customizer-Standard `none` = „Theme-Standard“, Builder-Anzeige `Open Sans`).
|
||||
|
||||
## D. Divi-Symbole für das Manifest
|
||||
|
||||
Arg-Anzahl = was das Plugin übergibt; „untyp.“ = Parameter ohne Typ-Deklaration (Signatur-Fingerabdruck weniger aussagekräftig).
|
||||
|
||||
**Optionen lesen**
|
||||
- `et_get_option` – 2 (von 8), untyp. (`epanel/custom_functions.php:215`) – optional; für Rohsicht direkt `get_option('et_divi')` (Key `et_divi`).
|
||||
- `ET\Builder\Packages\GlobalData\GlobalData::get_customizer_fonts` – 0, typisiert `(): array` (`GlobalData.php:446`) – nur Builder-Sicht, gecacht.
|
||||
- Keys: `et_divi`, `et_uploaded_fonts`, `et_google_fonts_cache`, `et_google_api_settings`, Statische Eigenschaft `GlobalData::$customizer_fonts`.
|
||||
|
||||
**Standards / Choices**
|
||||
- `et_builder_get_font_weight_list` – 0 (`includes/builder/core.php:4792`).
|
||||
- `et_divi_global_font_style_choices` – 0 (`includes/functions/choices.php:23`).
|
||||
- Standardwerte und min/max/step selbst sind nur in `et_divi_customizer_theme_settings()` (`functions.php:1371`) als Literale → nicht aufrufbar (braucht `WP_Customize_Manager`) → **Mirror** `new Mirror('customizer-typography', 'functions.php', 'et_divi_customizer_theme_settings', null, 'Standards, Sanitize-Callbacks und Bereiche der 20 Whitelist-Settings')` (große Funktion; Fingerabdruck schlägt bei jeder Customizer-Änderung an – akzeptabel oder engere Referenz wählen).
|
||||
|
||||
**Sanitize**
|
||||
- `absint` (WP-Core, nicht ins Manifest).
|
||||
- `et_sanitize_float_number` – 1, untyp. (`includes/functions/sanitization.php:7`).
|
||||
- `et_sanitize_int_number` – 1, untyp. (`:16`).
|
||||
- `et_sanitize_font_choices` – 1, untyp. (`:59`).
|
||||
- `et_sanitize_global_font_weight` – 1, untyp. (`:345`).
|
||||
- `et_divi_global_font_style` – 1, untyp. (`:358`).
|
||||
- (indirekt `et_sanitize_key_based_option` – 3, untyp., `:45`.)
|
||||
|
||||
**Schreiben**
|
||||
- `et_update_option` – 2 (von 6), untyp. (`epanel/custom_functions.php:276`).
|
||||
- `et_delete_option` – 1, untyp. (`:320`).
|
||||
|
||||
**Rechte**
|
||||
- `et_pb_is_allowed` – 1, untyp. (`includes/builder/core.php:1136`) mit `theme_customizer` bzw. `custom_fonts_management`.
|
||||
|
||||
**Caches**
|
||||
- `ET_Core_PageResource::remove_static_resources` – 2 oder 3 (von 7), untyp. (`core/components/PageResource.php:1398`).
|
||||
- `et_pb_force_regenerate_templates` – 0 (`includes/builder/core.php:3811`).
|
||||
|
||||
**Schriftlisten**
|
||||
- `et_builder_get_fonts` – 0, untyp. (`core.php:4730`).
|
||||
- `et_builder_get_google_fonts` – 0 (`core.php:4911`; Seiteneffekt HTTP, §0.7).
|
||||
- `et_builder_get_websafe_fonts` – 0 (`core.php:4783`).
|
||||
- `et_builder_get_custom_fonts` – 0 (`core.php:4822`).
|
||||
- optional `et_core_use_google_fonts` – 0 (`core/functions.php:223`), `et_builder_old_fonts_mapping` – 0 (`core.php:4839`).
|
||||
|
||||
**Font-Upload**
|
||||
- `ET\Builder\VisualBuilder\Fonts\FontsUtility::font_add` – 4, typisiert `(array, string, array, array = [])`, Rückgabe untyp. (`FontsUtility.php:102`).
|
||||
- `ET\Builder\VisualBuilder\Fonts\FontsUtility::font_remove` – 1, `(string)`, Rückgabe untyp. (`:242`).
|
||||
- `ET\Builder\VisualBuilder\Fonts\FontsUtility::mime_types_font` – 0, `(): array` (`:290`).
|
||||
- Konstante `FontsUtility::FONT_NAME_MAX_LENGTH` (`:39`).
|
||||
- `ET\Builder\VisualBuilder\Hooks\HooksRegistration::check_filetype_and_ext_font` – 3, `(array, string, string): array` (`HooksRegistration.php:77`).
|
||||
- `et_pb_get_supported_font_formats` – 0 (`includes/builder/core.php:5090`).
|
||||
- Hooks (nur Namen, Keys): `divi_visual_builder_fonts_custom_font_added`, `upload_dir`/`wp_check_filetype_and_ext` (von Divi gesetzt).
|
||||
Reference in New Issue
Block a user