fix(4e-review M-1): Schleifen-Warnung nennt die ganze Kette (Terme > Beiträge); loopWhere mit frühen Returns

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-20 00:40:05 +02:00
co-authored by Claude Sonnet 5.5
parent 8be2f5e558
commit 71ffbdbf59
3 changed files with 41 additions and 16 deletions
@@ -132,6 +132,17 @@ final class LoopScope
return $kind === null ? (string) $this->queryType : self::LABELS[$kind];
}
/** label() of the whole chain, outermost first ("Terme > Beiträge"); an unknown outer loop shows as "?". */
public function chainLabel(): string
{
$labels = array_map(
static fn (?string $kind): string => $kind === null ? '?' : self::LABELS[$kind],
array_slice($this->kinds(), 1)
);
return implode(' > ', [...array_reverse($labels), $this->label()]);
}
/**
* Whether the loop_* option $option belongs to this loop's kind – a meta key option (loop_<kind>_meta_key_*)
* to the kind of every loop of the chain (audit M1), since Divi reads meta by the ID of whatever loop
@@ -191,23 +191,33 @@ abstract class DiviWriteAbility implements Ability, RequiresDiviFeatures
/** @param list<string> $names */
protected static function loopWarning(array $names, LoopScope $from, LoopScope $to): string
{
$where = $to->queryType() === null
? 'jetzt außerhalb jeder Divi-Schleife; Divi zeigt sie dort leer'
: ($to->active() ? sprintf(
'jetzt in einer Divi-Schleife vom Typ: %s (vorher: %s); passen sie nicht zu dieser Art, zeigt Divi '
. 'sie leer oder mit Daten eines anderen Objekts mit derselben ID',
$to->label(),
$from->active() ? $from->label() : 'keine Schleife'
) : sprintf(
'jetzt in einer Divi-Schleife, die dieses Werkzeug nicht unterstützt (Typ: %s); Divi kann Daten '
. 'eines anderen Objekts zeigen',
$to->label()
));
return sprintf(
'Schleifen-Inhalte (%s) liegen %s. Zurückverschieben oder die Inhalte anpassen.',
implode(', ', $names),
$where
self::loopWhere($from, $to)
);
}
/** Where the content sits after the change, in words; names the whole chain of loops. */
private static function loopWhere(LoopScope $from, LoopScope $to): string
{
if ($to->queryType() === null) {
return 'jetzt außerhalb jeder Divi-Schleife; Divi zeigt sie dort leer';
}
if (! $to->active()) {
return sprintf(
'jetzt in einer Divi-Schleife, die dieses Werkzeug nicht unterstützt (Typ: %s); Divi kann Daten '
. 'eines anderen Objekts zeigen',
$to->chainLabel()
);
}
return sprintf(
'jetzt in einer Divi-Schleife vom Typ: %s (vorher: %s); passen sie nicht zu dieser Art, zeigt Divi '
. 'sie leer oder mit Daten eines anderen Objekts mit derselben ID',
$to->chainLabel(),
$from->active() ? $from->chainLabel() : 'keine Schleife'
);
}
}
@@ -423,7 +423,9 @@ final class DiviLoopWriteTest extends DiviWriteAbilityTestCase
]);
self::assertTrue($result['ok'], (string) json_encode($result));
self::assertStringContainsString('loop_post_meta_key_manual_custom_field', implode(' | ', $result['warnings']));
$warnings = implode(' | ', $result['warnings']);
self::assertStringContainsString('loop_post_meta_key_manual_custom_field', $warnings);
self::assertStringContainsString('Typ: Terme > Beiträge (vorher: Beiträge > Beiträge)', $warnings);
}
/** Audit L2: "terms" is a term loop for Divi, an unsupported target "can show data of another object". */
@@ -531,7 +533,9 @@ final class DiviLoopWriteTest extends DiviWriteAbilityTestCase
$result = $this->moveNode(['id' => 's0.r0.c0.m0', 'parent' => 's0.r0.c1']);
self::assertTrue($result['ok'], (string) json_encode($result));
self::assertStringContainsString('loop_post_meta_key_manual_custom_field', implode(' | ', $result['warnings']));
$warnings = implode(' | ', $result['warnings']);
self::assertStringContainsString('loop_post_meta_key_manual_custom_field', $warnings);
self::assertStringContainsString('Typ: Terme > Beiträge (vorher: Beiträge)', $warnings);
}
/** Two sections: a post loop on its own, and a post loop inside a term loop (s1). */