[wp-trac] [WordPress Trac] #43502: `WP_REST_Posts_Controller::prepare_item_for_response()` doesn't reset postdata after calling setup_postdata()

WordPress Trac noreply at wordpress.org
Sun Jun 29 17:33:26 UTC 2025


#43502: `WP_REST_Posts_Controller::prepare_item_for_response()` doesn't reset
postdata after calling setup_postdata()
-------------------------------------------------+-------------------------
 Reporter:  gerbenvandijk                        |       Owner:  (none)
     Type:  defect (bug)                         |      Status:  new
 Priority:  normal                               |   Milestone:  Future
                                                 |  Release
Component:  REST API                             |     Version:  4.9.4
 Severity:  normal                               |  Resolution:
 Keywords:  good-first-bug has-patch needs-      |     Focuses:  rest-api
  testing needs-unit-tests                       |
-------------------------------------------------+-------------------------
Changes (by SirLouen):

 * keywords:  good-first-bug has-patch needs-testing has-unit-tests => good-
     first-bug has-patch needs-testing needs-unit-tests


Comment:

 == Combined Bug Reproduction and Patch Test Report
 === Description
 ✅ This report validates that the indicated patch works as expected.

 Patches tested:
 - First Patch: https://github.com/WordPress/wordpress-
 develop/pull/1165.diff
 - Second Patch (Unit Tests): https://github.com/WordPress/wordpress-
 develop/pull/4591.diff

 === Environment
 - WordPress: 6.9-alpha-60093-src
 - PHP: 8.2.28
 - Server: nginx/1.29.0
 - Database: mysqli (Server: 8.4.5 / Client: mysqlnd 8.2.28)
 - Browser: Chrome 137.0.0.0
 - OS: Windows 10/11
 - Theme: Twenty Twenty 2.9
 - MU Plugins: None activated
 - Plugins:
   * Postdata Test 1.0.0
   * Test Reports 1.2.0

 === Bug Reproduction

 1. Create a post. Take note of the ID for such post
 2. For testing this, we need to add the code in Supp Artifacts somewhere
 where it could be executed, like a plugin, functions.php, etc… This code
 takes the code provided in the OP and adds a shortcodes to display the
 results of using that function during the loop processing.
 3. Modify the code here: `$test_post = get_post(1);` and instead of `1`
 use the ID you got in the first step
 4. Create a second post
 5. Add the shortcode `[test_postdata]`
 6. Check the post results
 7. 🐞 Post ID after API call shows the first one used instead of the
 current post, as expected. This proves that REST Request is modifying the
 global `$post` data.

 === Expected Results
 - The Post ID after API is the same before and after

 === Actual Results
 1. ✅ Issue resolved with first patch.
 2. ⚠️ Unit Tests are inadequate

 === Additional Notes
 - The solution is pretty straightforward, as commented by
 @TimothyBlynJacobs long time ago. I can't understand why i thas not been
 merged yet. Maybe the absence of valid Unit Tests has been the problem. I
 will work on something.

 - I'm trying to understand the Unit Tests provided in
 [https://github.com/WordPress/wordpress-develop/pull/4591 PR 4591], but
 they don't seem to be correct. For the first Unit Test
 `test_postdata_reset_by_prepare_item_for_response`, it's using a variable
 `$post_id` for the `posts` endpoint that has not even been declared
 previously.

 - For the second one
 `test_postdata_reset_by_prepare_item_for_response_revisions`, it returns
 almost immediately `Attempt to read property "post_content" on null`. The
 problem here is that [https://github.com/SirLouen/wordpress-
 develop/blob/trunk/src/wp-includes/revision.php#L210-L212 it will not add
 a revision because the post has not changed]

 - For this, I'm restoring the `needs-unit-tests` workflow tag, as the ones
 provided are not valid.

 === Supplemental Artifacts

 Test Code:

 {{{
 function convert_post_object_to_rest_response($post) {
     global $wp_rest_server;
     $post_type = get_post_type_object($post->post_type);
     $request = WP_REST_Request::from_url(rest_url(sprintf('wp/v2/%s/%d',
 $post_type->rest_base, $post->ID)));
     $request = rest_do_request($request);
     $data = $wp_rest_server->response_to_data($request, isset($_GET[
 '_embed' ]));
     return $data;
 }

 function test_template() {
     global $post;
     echo 'Original Post ID: ' . $post->ID . '<br>';

     $test_post = get_post(1);
     $response = convert_post_object_to_rest_response($test_post);
     echo 'Returned API ID: ' . $response['id'] . '<br>';

     echo 'Post ID After API Call: ' . $post->ID . '<br>';
     echo 'Post Title: ' . get_the_title() . '<br>';
 }

 add_shortcode('test_postdata', 'test_template');
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/43502#comment:22>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list