From 6a7193424ca827b2c553ba1517117bfbc994c909 Mon Sep 17 00:00:00 2001 From: Jan-Niclas Loosen Date: Sat, 26 Sep 2026 01:15:29 +0200 Subject: [PATCH] refactor: Rev::matches replaces the inline rev checks Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7 --- src/Abilities/Rev.php | 10 ++++++++++ .../WordPress/Content/ContentUpdateAbility.php | 2 +- .../WordPress/Revisions/RevisionRestoreAbility.php | 2 +- .../WordPress/Status/PostReplaceWithCopyAbility.php | 2 +- tests/Unit/Abilities/RevAndJsonMapTest.php | 10 ++++++++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Abilities/Rev.php b/src/Abilities/Rev.php index 8b1ca36..457e245 100644 --- a/src/Abilities/Rev.php +++ b/src/Abilities/Rev.php @@ -32,4 +32,14 @@ final class Rev (string) $post->post_modified_gmt, ])); } + + /** + * Whether $input carries the current rev of $post (optimistic lock of the post tools). + * + * @param array $input + */ + public static function matches(array $input, WP_Post $post): bool + { + return isset($input['rev']) && $input['rev'] === self::ofPost($post); + } } diff --git a/src/Integrations/WordPress/Content/ContentUpdateAbility.php b/src/Integrations/WordPress/Content/ContentUpdateAbility.php index 0ac8692..fe92ad2 100644 --- a/src/Integrations/WordPress/Content/ContentUpdateAbility.php +++ b/src/Integrations/WordPress/Content/ContentUpdateAbility.php @@ -109,7 +109,7 @@ final class ContentUpdateAbility implements Ability return $post; } - if (! isset($input['rev']) || $input['rev'] !== Rev::ofPost($post)) { + if (! Rev::matches($input, $post)) { return Errors::revMismatch(); } diff --git a/src/Integrations/WordPress/Revisions/RevisionRestoreAbility.php b/src/Integrations/WordPress/Revisions/RevisionRestoreAbility.php index 210d6c3..4055bd7 100644 --- a/src/Integrations/WordPress/Revisions/RevisionRestoreAbility.php +++ b/src/Integrations/WordPress/Revisions/RevisionRestoreAbility.php @@ -107,7 +107,7 @@ final class RevisionRestoreAbility implements Ability )); } - if (! isset($input['rev']) || $input['rev'] !== Rev::ofPost($post)) { + if (! Rev::matches($input, $post)) { return Errors::revMismatch(); } diff --git a/src/Integrations/WordPress/Status/PostReplaceWithCopyAbility.php b/src/Integrations/WordPress/Status/PostReplaceWithCopyAbility.php index 2549d54..0386f45 100644 --- a/src/Integrations/WordPress/Status/PostReplaceWithCopyAbility.php +++ b/src/Integrations/WordPress/Status/PostReplaceWithCopyAbility.php @@ -185,7 +185,7 @@ final class PostReplaceWithCopyAbility implements Ability ); } - if (! isset($input['rev']) || $input['rev'] !== Rev::ofPost($original)) { + if (! Rev::matches($input, $original)) { return Errors::revMismatch(); } diff --git a/tests/Unit/Abilities/RevAndJsonMapTest.php b/tests/Unit/Abilities/RevAndJsonMapTest.php index 096fe56..bce6cf1 100644 --- a/tests/Unit/Abilities/RevAndJsonMapTest.php +++ b/tests/Unit/Abilities/RevAndJsonMapTest.php @@ -39,6 +39,16 @@ final class RevAndJsonMapTest extends TestCase } } + public function testMatchesComparesInputRevWithThePostRev(): void + { + $post = new WP_Post(['post_title' => 'T']); + + self::assertTrue(Rev::matches(['rev' => Rev::ofPost($post)], $post)); + self::assertFalse(Rev::matches(['rev' => 'abcdefabcdef'], $post)); + self::assertFalse(Rev::matches([], $post)); + self::assertFalse(Rev::matches(['rev' => 123], $post)); + } + public function testEmptyMapBecomesJsonObject(): void { self::assertInstanceOf(stdClass::class, JsonMap::of([]));