fix: guard revision-restore follow-ups, mark divi revisions

RevisionRestoreAbility now wraps the after-save action and change-log
write in FollowUp::run() and reports failures as warnings instead of
letting them turn a saved restore into an error response, matching
ContentUpdateAbility; a failed wp_restore_post_revision() is now
Errors::writeFailed() (nothing was changed) instead of unsupported().
RevisionsListAbility marks each item divi (reusing
PostPresenter::usesDivi()/DIVI_HINT) since a Divi/block revision's
excerpt is stripped markup, not prose.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
2026-09-25 23:53:36 +02:00
co-authored by Claude Opus 5.5
parent b9dd86d223
commit 236d25325d
4 changed files with 131 additions and 17 deletions
@@ -6,6 +6,7 @@ namespace LIT\MCP\Integrations\WordPress\Revisions;
use LIT\MCP\Abilities\Ability;
use LIT\MCP\Abilities\Errors;
use LIT\MCP\Abilities\FollowUp;
use LIT\MCP\Abilities\Rev;
use LIT\MCP\Abilities\ToolResult;
use LIT\MCP\ChangeLog\ChangeLog;
@@ -113,25 +114,36 @@ final class RevisionRestoreAbility implements Ability
$backupId = RevisionPoint::capture($postId);
$restored = wp_restore_post_revision((int) $revision->ID);
if (! $restored) {
return Errors::unsupported(
'WordPress konnte die Revision nicht wiederherstellen.',
'Revision in WordPress unter „Revisionen“ prüfen.'
);
return Errors::writeFailed('WordPress konnte die Revision nicht wiederherstellen.');
}
do_action('lit_mcp_after_save', $postId, $this->name(), $input);
// The restore is saved – failures from here on are logged and reported as warnings only.
$warnings = [];
FollowUp::run(
fn () => do_action('lit_mcp_after_save', $postId, $this->name(), $input),
$this->name() . ' lit_mcp_after_save',
'Eine Erweiterung ist nach dem Wiederherstellen auf einen Fehler gestoßen; die Änderung ist gespeichert.',
$warnings
);
$updated = get_post($postId);
$updated = $updated instanceof WP_Post ? $updated : $post;
$summary = sprintf('"%s" auf Stand vom %s zurückgesetzt', $updated->post_title, $revision->post_date);
$postType = (string) $post->post_type;
$logId = $this->log->record($this->name(), $postType, (string) $postId, $summary, $backupId);
$logId = FollowUp::run(
fn () => $this->log->record($this->name(), $postType, (string) $postId, $summary, $backupId),
$this->name() . ' change log',
'Änderungsprotokoll konnte nicht geschrieben werden; die Änderung ist gespeichert.',
$warnings
);
return ToolResult::ok($summary . sprintf(' (Status unverändert: %s).', $updated->post_status))
->changed((string) $postId, $postType, 'restored', (string) $updated->post_title)
->rev(Rev::ofPost($updated))
->revisionId($backupId)
->logId($logId)
->logId(is_int($logId) ? $logId : null)
->urls((string) get_preview_post_link($updated), (string) get_edit_post_link($postId, 'raw'))
->warnings($warnings)
->toArray();
}