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([]));