feat: lit/divi-variables-set warnt vor Verwendungen in Presets und beim Archivieren verwendeter Variablen
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
d7a8b85f8d
commit
fef964bb7a
@@ -10,6 +10,7 @@ use LIT\MCP\Abilities\Ability;
|
||||
use LIT\MCP\Abilities\Annotations;
|
||||
use LIT\MCP\Abilities\Errors;
|
||||
use LIT\MCP\Integrations\Divi\Library\GlobalUsages;
|
||||
use LIT\MCP\Integrations\Divi\Library\UsageReport;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
|
||||
use WP_Error;
|
||||
@@ -22,7 +23,7 @@ defined('ABSPATH') || exit;
|
||||
* value. Variables are never deleted – Divi refuses an inventory that lacks a stored ID (V1) –, only archived (order
|
||||
* "") and activated again (appended at the end of their type); the type of a variable stays, gradients are left to the
|
||||
* builder. Values are checked per type (VariableValue); an active variable needs one. The dry run lists the posts that
|
||||
* reference a changed, archived or activated variable (ReferenceUsageQuery).
|
||||
* reference a changed, archived or activated variable (ReferenceUsageQuery) and warns about presets that use it.
|
||||
*/
|
||||
final class DiviVariablesSetAbility implements Ability, RequiresDiviFeatures
|
||||
{
|
||||
@@ -38,6 +39,13 @@ final class DiviVariablesSetAbility implements Ability, RequiresDiviFeatures
|
||||
private const NEW_ENTRY = ['id' => '', 'label' => '', 'value' => '', 'order' => '', 'status' => 'active',
|
||||
'lastUpdated' => '', 'variableType' => ''];
|
||||
|
||||
/** At most this many names per warning. */
|
||||
private const LISTED = 10;
|
||||
|
||||
private const IN_USE = 'Die unter affected genannten Inhalte verweisen auf geänderte oder archivierte Variablen; '
|
||||
. 'archivierte Variablen bleiben dort als Verweis stehen. lit/divi-design-detach mit variable ersetzt die '
|
||||
. 'Verweise vorher durch den Wert.';
|
||||
|
||||
/** @param (Closure(int): string)|null $random Random characters for new IDs (VariableBook::newId(); tests). */
|
||||
public function __construct(
|
||||
private DesignSystemWriter $writer,
|
||||
@@ -173,12 +181,14 @@ final class DiviVariablesSetAbility implements Ability, RequiresDiviFeatures
|
||||
}
|
||||
}
|
||||
$touched = array_values(array_unique($touched));
|
||||
$report = $touched === [] ? null : $this->usages->reportFor(new ReferenceUsageQuery($touched));
|
||||
|
||||
return new DesignPlan(
|
||||
$book->data(),
|
||||
$diff,
|
||||
VariableDiff::summary($diff),
|
||||
$touched === [] ? null : $this->usages->reportFor(new ReferenceUsageQuery($touched))
|
||||
$report,
|
||||
$this->warnings($diff, $report)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -370,4 +380,47 @@ final class DiviVariablesSetAbility implements Ability, RequiresDiviFeatures
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruling V8: presets that use a changed, archived or activated variable are warnings, never a block; archiving a
|
||||
* variable that posts still use is allowed (V1a) and points to lit/divi-design-detach.
|
||||
*
|
||||
* @param list<array<string, mixed>> $diff
|
||||
* @return list<string>
|
||||
*/
|
||||
private function warnings(array $diff, ?UsageReport $report): array
|
||||
{
|
||||
$presets = null;
|
||||
$warnings = [];
|
||||
$archives = false;
|
||||
foreach ($diff as $row) {
|
||||
if ($row['action'] === 'added') {
|
||||
continue;
|
||||
}
|
||||
$archived = $row['action'] === 'archived';
|
||||
$archives = $archives || $archived;
|
||||
$presets ??= PresetBook::fromDivi($this->writer->presets());
|
||||
$users = array_column($presets->referencing((string) $row['id']), 'name');
|
||||
if ($users !== []) {
|
||||
$warnings[] = sprintf(
|
||||
$archived
|
||||
? 'Variable „%s“ wird archiviert, aber noch von Presets verwendet: %s.'
|
||||
: 'Die Änderung an Variable „%s“ wirkt auch auf die Presets %s.',
|
||||
$row['name'],
|
||||
self::names($users)
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($archives && $report !== null && $report->exists()) {
|
||||
$warnings[] = self::IN_USE;
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/** @param list<string> $names */
|
||||
private static function names(array $names): string
|
||||
{
|
||||
return implode(', ', array_slice($names, 0, self::LISTED)) . (count($names) > self::LISTED ? ', …' : '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,4 +316,47 @@ final class DiviVariablesSetAbilityTest extends TestCase
|
||||
self::assertCount(2, $calls);
|
||||
self::assertSame(VariableBook::fromDivi(VariableAreaTest::stored())->data(), $calls[1], 'the snapshot again');
|
||||
}
|
||||
|
||||
/** Ruling V1a/V8: archiving a used variable is allowed; presets and posts are warnings, the dry run lists posts. */
|
||||
public function testArchivingAUsedVariableWarnsAndListsTheUsages(): void
|
||||
{
|
||||
$dry = self::assertToolError(
|
||||
$this->ability(self::usages(self::used()), null, PresetBookTest::storedWithReferences())
|
||||
->execute(['items' => [['id' => 'Slogan', 'status' => 'archived']]]),
|
||||
'confirm_required'
|
||||
);
|
||||
|
||||
self::assertSame(7, $dry['affected'][0]['post_id']);
|
||||
self::assertSame([
|
||||
'Variable „Slogan“ wird archiviert, aber noch von Presets verwendet: Doppelt.',
|
||||
'Die unter affected genannten Inhalte verweisen auf geänderte oder archivierte Variablen; archivierte '
|
||||
. 'Variablen bleiben dort als Verweis stehen. lit/divi-design-detach mit variable ersetzt die Verweise '
|
||||
. 'vorher durch den Wert.',
|
||||
], $dry['warnings']);
|
||||
}
|
||||
|
||||
public function testChangingAVariableWarnsAboutThePresetsThatUseIt(): void
|
||||
{
|
||||
$dry = self::assertToolError(
|
||||
$this->ability(null, null, PresetBookTest::storedWithReferences())
|
||||
->execute(['items' => [['id' => 'Eckenradius', 'value' => '12px']]]),
|
||||
'confirm_required'
|
||||
);
|
||||
|
||||
self::assertSame(
|
||||
['Die Änderung an Variable „Eckenradius“ wirkt auch auf die Presets Lesetext.'],
|
||||
$dry['warnings']
|
||||
);
|
||||
}
|
||||
|
||||
public function testNewVariablesHaveNoWarnings(): void
|
||||
{
|
||||
$dry = self::assertToolError(
|
||||
$this->ability(null, null, PresetBookTest::storedWithReferences())
|
||||
->execute(['items' => [['type' => 'strings', 'label' => 'Gruß', 'value' => 'Hallo']]]),
|
||||
'confirm_required'
|
||||
);
|
||||
|
||||
self::assertSame([], $dry['warnings']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user