From c1a397536752d3636fcf43250a56bc40c5a0d9c1 Mon Sep 17 00:00:00 2001 From: Jb Audras Date: Mon, 26 Jun 2023 20:55:04 +0000 Subject: [PATCH] Posts, Post Types: Add a `$previous_status` parameter to `wp_trash_post()` related hooks. This adds a `$previous_status` parameter to the `pre_trash_post`, `wp_trash_post`, and `trashed_post` hooks. Props mujuonly, mukesh27, nihar007, dhruvishah2203, SergeyBiryukov, costdev, hugod, audrasjb, oglekler. Fixes #58392. git-svn-id: https://develop.svn.wordpress.org/trunk@56043 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/post.php | 30 +++-- tests/phpunit/tests/post/wpTrashPost.php | 129 ++++++++++++++++++++ tests/phpunit/tests/post/wpUntrashPost.php | 132 +++++++++++++++++++++ 3 files changed, 280 insertions(+), 11 deletions(-) create mode 100644 tests/phpunit/tests/post/wpTrashPost.php create mode 100644 tests/phpunit/tests/post/wpUntrashPost.php diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index fcd948066d..abf94bcbe5 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -3576,15 +3576,19 @@ function wp_trash_post( $post_id = 0 ) { return false; } + $previous_status = $post->post_status; + /** * Filters whether a post trashing should take place. * * @since 4.9.0 + * @since 6.3.0 Added the `$previous_status` parameter. * - * @param bool|null $trash Whether to go forward with trashing. - * @param WP_Post $post Post object. + * @param bool|null $trash Whether to go forward with trashing. + * @param WP_Post $post Post object. + * @param string $previous_status The status of the post about to be trashed. */ - $check = apply_filters( 'pre_trash_post', null, $post ); + $check = apply_filters( 'pre_trash_post', null, $post, $previous_status ); if ( null !== $check ) { return $check; @@ -3594,12 +3598,14 @@ function wp_trash_post( $post_id = 0 ) { * Fires before a post is sent to the Trash. * * @since 3.3.0 + * @since 6.3.0 Added the `$previous_status` parameter. * - * @param int $post_id Post ID. + * @param int $post_id Post ID. + * @param string $previous_status The status of the post about to be trashed. */ - do_action( 'wp_trash_post', $post_id ); + do_action( 'wp_trash_post', $post_id, $previous_status ); - add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status ); + add_post_meta( $post_id, '_wp_trash_meta_status', $previous_status ); add_post_meta( $post_id, '_wp_trash_meta_time', time() ); $post_updated = wp_update_post( @@ -3619,10 +3625,12 @@ function wp_trash_post( $post_id = 0 ) { * Fires after a post is sent to the Trash. * * @since 2.9.0 + * @since 6.3.0 Added the `$previous_status` parameter. * - * @param int $post_id Post ID. + * @param int $post_id Post ID. + * @param string $previous_status The status of the post at the point where it was trashed. */ - do_action( 'trashed_post', $post_id ); + do_action( 'trashed_post', $post_id, $previous_status ); return $post; } @@ -3656,7 +3664,7 @@ function wp_untrash_post( $post_id = 0 ) { * Filters whether a post untrashing should take place. * * @since 4.9.0 - * @since 5.6.0 The `$previous_status` parameter was added. + * @since 5.6.0 Added the `$previous_status` parameter. * * @param bool|null $untrash Whether to go forward with untrashing. * @param WP_Post $post Post object. @@ -3671,7 +3679,7 @@ function wp_untrash_post( $post_id = 0 ) { * Fires before a post is restored from the Trash. * * @since 2.9.0 - * @since 5.6.0 The `$previous_status` parameter was added. + * @since 5.6.0 Added the `$previous_status` parameter. * * @param int $post_id Post ID. * @param string $previous_status The status of the post at the point where it was trashed. @@ -3717,7 +3725,7 @@ function wp_untrash_post( $post_id = 0 ) { * Fires after a post is restored from the Trash. * * @since 2.9.0 - * @since 5.6.0 The `$previous_status` parameter was added. + * @since 5.6.0 Added the `$previous_status` parameter. * * @param int $post_id Post ID. * @param string $previous_status The status of the post at the point where it was trashed. diff --git a/tests/phpunit/tests/post/wpTrashPost.php b/tests/phpunit/tests/post/wpTrashPost.php new file mode 100644 index 0000000000..1b1a5d6aad --- /dev/null +++ b/tests/phpunit/tests/post/wpTrashPost.php @@ -0,0 +1,129 @@ +post = $this->factory()->post->create_and_get( + array( + 'post_status' => 'draft', + ) + ); + } + + /** + * Tests that wp_trash_post() returns a WP_Post object + * and sets the correct post meta to trash a post. + * + * @ticket 58392 + * + * @covers ::wp_trash_post + */ + public function test_trash_post() { + $result = wp_trash_post( $this->post->ID ); + + $this->assertInstanceOf( 'WP_Post', $result, 'wp_trash_post returned value should be an instance of WP_Post.' ); + + $trashed = get_posts( + array( + 'post_status' => 'trash', + 'fields' => 'ids', + ) + ); + + $this->assertContains( $this->post->ID, $trashed, 'The post should be trashed.' ); + + $trashed_post_metas = get_post_meta( $this->post->ID ); + + $this->assertArrayHasKey( '_wp_trash_meta_status', $trashed_post_metas, 'Trashed post should have _wp_trash_meta_status meta set.' ); + $this->assertCount( 1, $trashed_post_metas['_wp_trash_meta_status'], 'Trashed post should have only one _wp_trash_meta_status meta set.' ); + $this->assertSame( $this->post->post_status, reset( $trashed_post_metas['_wp_trash_meta_status'] ), 'Trashed post should have _wp_trash_meta_status meta set to previous post status.' ); + $this->assertArrayHasKey( '_wp_trash_meta_time', $trashed_post_metas, 'Trashed post should have _wp_trash_meta_time meta set.' ); + $this->assertCount( 1, $trashed_post_metas['_wp_trash_meta_time'], 'Trashed post should have only one _wp_trash_meta_time meta set.' ); + } + + /** + * Tests that wp_trash_post() applies 'pre_trash_post' filters + * and passes the expected values to callbacks. + * + * @ticket 58392 + * + * @covers ::wp_trash_post + */ + public function test_pre_trash_post_hook() { + add_filter( + 'pre_trash_post', + function ( $trash, $post, $previous_status ) { + $this->assertNull( $trash, 'pre_trash_post first parameter should be null.' ); + $this->assertSame( $this->post->ID, $post->ID, 'pre_trash_post second parameter should be the trashed post ID.' ); + $this->assertSame( $this->post->post_status, $previous_status, 'pre_trash_post third parameter should be the previous trashed post status.' ); + + return $trash; + }, + 10, + 3 + ); + + wp_trash_post( $this->post->ID ); + + $this->assertGreaterThan( 0, did_filter( 'pre_trash_post' ), 'pre_trash_post filter was not called.' ); + } + + /** + * Tests that wp_trash_post() triggers the 'wp_trash_post' action + * and passes the expected values to callbacks. + * + * @ticket 58392 + * + * @covers ::wp_trash_post + */ + public function test_wp_trash_post_hook() { + add_action( + 'wp_trash_post', + function ( $post_id, $previous_status ) { + $this->assertSame( $this->post->ID, $post_id, 'wp_trash_post first parameter should be the trashed post ID.' ); + $this->assertSame( $this->post->post_status, $previous_status, 'wp_trash_post second parameter should be the previous trashed post status.' ); + }, + 10, + 2 + ); + + wp_trash_post( $this->post->ID ); + + $this->assertGreaterThan( 0, did_action( 'wp_trash_post' ), 'wp_trash_post action was not called.' ); + } + + /** + * Tests that wp_trash_post() triggers the 'trashed_post' action + * and passes the expected values to callbacks. + * + * @ticket 58392 + * + * @covers ::wp_trash_post + */ + public function test_trashed_post_hook() { + add_action( + 'trashed_post', + function ( $post_id, $previous_status ) { + $this->assertSame( $this->post->ID, $post_id, 'trashed_post first parameter should be the trashed post ID.' ); + $this->assertSame( $this->post->post_status, $previous_status, 'trashed_post second parameter should be the previous trashed post status.' ); + }, + 10, + 2 + ); + + wp_trash_post( $this->post->ID ); + + $this->assertGreaterThan( 0, did_action( 'trashed_post' ), 'trashed_post action was not called.' ); + } +} diff --git a/tests/phpunit/tests/post/wpUntrashPost.php b/tests/phpunit/tests/post/wpUntrashPost.php new file mode 100644 index 0000000000..a4843dd2a2 --- /dev/null +++ b/tests/phpunit/tests/post/wpUntrashPost.php @@ -0,0 +1,132 @@ +trashed_post = wp_trash_post( + $this->factory()->post->create( + array( + 'post_status' => 'draft', + ) + ) + ); + } + + /** + * Tests that wp_untrash_post() returns a WP_Post object, + * removes post meta for an untrashed post and sets it to a 'Draft'. + * + * @ticket 58392 + * + * @covers ::wp_untrash_post + */ + public function test_untrash_post() { + $result = wp_untrash_post( $this->trashed_post->ID ); + + $this->assertInstanceOf( 'WP_Post', $result, 'wp_untrash_post returned value should be an instance of WP_Post.' ); + + $trashed = get_posts( + array( + 'post_status' => 'trash', + 'fields' => 'ids', + ) + ); + + $this->assertNotContains( $this->trashed_post->ID, $trashed, 'Untrashed post should not belong to trashed posts anymore.' ); + + $untrashed_post_metas = get_post_meta( $this->trashed_post->ID ); + + $this->assertArrayNotHasKey( '_wp_trash_meta_status', $untrashed_post_metas, 'Untrashed post should not have _wp_trash_meta_status meta anymore.' ); + $this->assertArrayNotHasKey( '_wp_trash_meta_time', $untrashed_post_metas, 'Untrashed post should not have _wp_trash_meta_time meta anymore.' ); + + $post = get_post( $this->trashed_post->ID ); + + $this->assertSame( 'draft', $post->post_status, 'Untrashed post should have its previous status set correctly.' ); + } + + /** + * Tests that wp_untrash_post() applies 'pre_untrash_post' filters + * and passes the expected values to callbacks. + * + * @ticket 58392 + * + * @covers ::wp_untrash_post + */ + public function test_pre_untrash_post_hook() { + add_filter( + 'pre_untrash_post', + function ( $trash, $post, $previous_status ) { + $this->assertNull( $trash, 'pre_untrash_post first parameter should be null.' ); + $this->assertSame( $this->trashed_post->ID, $post->ID, 'pre_untrash_post second parameter should be the trashed post ID.' ); + $this->assertSame( $this->trashed_post->post_status, $previous_status, 'pre_untrash_post third parameter should be the previous trashed post status.' ); + + return $trash; + }, + 10, + 3 + ); + + wp_untrash_post( $this->trashed_post->ID ); + + $this->assertGreaterThan( 0, did_filter( 'pre_untrash_post' ), 'pre_untrash_post filter was not called.' ); + } + + /** + * Tests that wp_untrash_post() triggers the 'untrash_post' action + * and passes the expected values to callbacks. + * + * @ticket 58392 + * + * @covers ::wp_untrash_post + */ + public function test_untrash_post_hook() { + add_action( + 'untrash_post', + function ( $post_id, $previous_status ) { + $this->assertSame( $this->trashed_post->ID, $post_id, 'untrash_post first parameter should be the trashed post ID.' ); + $this->assertSame( $this->trashed_post->post_status, $previous_status, 'untrash_post second parameter should be the previous trashed post status.' ); + }, + 10, + 2 + ); + + wp_untrash_post( $this->trashed_post->ID ); + + $this->assertGreaterThan( 0, did_action( 'untrash_post' ), 'untrash_post action was not called.' ); + } + + /** + * Tests that wp_untrash_post() triggers the 'untrashed_post' action + * and passes the expected values to callbacks. + * + * @ticket 58392 + * + * @covers ::wp_untrash_post + */ + public function test_untrashed_post_hook() { + add_action( + 'untrashed_post', + function ( $post_id, $previous_status ) { + $this->assertSame( $this->trashed_post->ID, $post_id, 'untrashed_post first parameter should be the trashed post ID.' ); + $this->assertSame( $this->trashed_post->post_status, $previous_status, 'untrashed_post second parameter should be the previous trashed post status.' ); + }, + 10, + 2 + ); + + wp_untrash_post( $this->trashed_post->ID ); + + $this->assertGreaterThan( 0, did_action( 'untrashed_post' ), 'untrashed_post action was not called.' ); + } +}