fix: FontInstaller prüft Divis Schriftenliste vor font_add; leere Installation ist ein sauberer Rollback

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-19 18:27:02 +02:00
co-authored by Claude Sonnet 5.5
parent 901179de62
commit 2b45f1bdd3
4 changed files with 51 additions and 1 deletions
@@ -411,6 +411,13 @@ final class DiviFontsUploadAbility implements Ability, RequiresDiviFeatures
throw WriteFailed::rolledBack(self::REASON, $e, 'font upload: ' . $e->getMessage());
}
if ($installed === []) {
throw WriteFailed::rolledBack(
self::REASON . ' Divi hat nichts gespeichert.',
detail: 'font upload: Divi stored nothing of ' . implode(',', array_keys($paths))
);
}
$missing = array_values(array_diff(array_keys($paths), $installed));
if ($missing === []) {
return;
@@ -43,6 +43,8 @@ class FontInstaller implements DiviAdapter
new Call(FontsUtility::class . '::font_remove', 1),
],
constants: [FontsUtility::class . '::FONT_NAME_MAX_LENGTH'],
// Read before font_add(): a corrupt list would make Divi lose the files it moved.
keys: ['et_uploaded_fonts'],
mirrors: [
new Mirror(
'font-install',
@@ -79,11 +81,17 @@ class FontInstaller implements DiviAdapter
* @param array<string, string> $files Extension => temp file path (deleted or moved by WordPress).
* @return list<string> The extensions Divi stored – fewer than $files on a partial success.
* @throws DiviLocked When font-upload is not released – before anything is written.
* @throws RuntimeException When Divi refuses a file or the whole font; nothing is stored then.
* @throws RuntimeException When Divi's font list is corrupt or Divi refuses a file or the whole font; nothing is stored then.
*/
public function install(string $name, array $files, string $weights, string $family): array
{
ReleaseGate::assertFeature(DiviFeature::FontUpload);
if (! is_array(get_option('et_uploaded_fonts', []))) {
throw new RuntimeException(
'Divis Schriftenliste (et_uploaded_fonts) ist beschädigt; nichts wurde gespeichert. '
. 'Die Option in Divi bzw. der Datenbank prüfen.'
);
}
$uploads = [];
foreach ($files as $extension => $path) {
$filename = sanitize_file_name($name . '.' . $extension);