Make WordPress Core

Opened 15 months ago

Closed 2 months ago

Last modified 2 months ago

#59521 closed defect (bug) (fixed)

Issue with update_post_thumbnail_cache if using get_posts

Reported by: xendo's profile Xendo Owned by: antpb's profile antpb
Milestone: 6.7 Priority: normal
Severity: normal Version: 6.3.1
Component: Media Keywords: has-patch has-unit-tests needs-testing
Focuses: Cc:

Description

Hello,

I got this:
Warning: Attempt to read property "ID" on int in /wp-includes/post-thumbnail-template.php on line 116

I'm using:

<?php
$posts = get_posts( array( 'fields' => 'ids' ) );

foreach ( $posts as $post_id ) :
        $thumb = get_the_post_thumbnail( $post_id );
endforeach;

The update_post_thumbnail_cache() used in get_the_post_thumbnail() assumes $wp_query->posts always contains an array of $posts objects, while it can be an array of $posts IDs.
To prevent the warning it would be appropriate to check that $post is actually a post object.

The patched code:

<?php
foreach ( $wp_query->posts as $post ) {
        $post = get_post( $post ); // Add this or check if is_integer( $post )
        $id = get_post_thumbnail_id( $post->ID );

Thanks

Kind Regards

Change History (12)

This ticket was mentioned in Slack in #core-media by antpb. View the logs.


8 months ago

#2 @antpb
8 months ago

  • Milestone changed from Awaiting Review to 6.6
  • Owner set to antpb
  • Status changed from new to accepted

Moving this into 6.6 as this is a straightforward problem and solution to validate. Thank you @Xendo for the suggestion!

This ticket was mentioned in PR #6636 on WordPress/wordpress-develop by @khokansardar.


7 months ago
#3

  • Keywords has-patch added; needs-patch removed

Fix attempt to read post ID on update_post_thumbnail_cache function as some cases $wp_query->posts return array of post IDs instead of WP_Post object.

Trac ticket: #59521

#4 @khokansardar
7 months ago

  • Keywords has-unit-tests added

This ticket was mentioned in Slack in #core-media by antpb. View the logs.


6 months ago

This ticket was mentioned in Slack in #core by nhrrob. View the logs.


6 months ago

#7 @sumitsingh
6 months ago

  • Keywords needs-testing added

#8 @oglekler
6 months ago

  • Milestone changed from 6.6 to 6.7

It looks like straight forward solution but from my point of view there is still something strange in the functions code itself.

get_the_post_thumbnail() function calls update_post_thumbnail_cache() like this:

if ( in_the_loop() ) {
	update_post_thumbnail_cache();
}

and get_posts() should not set the loop 🤔 and if are getting posts in the loop that has nothing to do with the current post something needs to be done.

Btw, requesting posts one by one that were originally requested only with IDs is incorrect from the beginning because it's raising the amount of requests to the db. Query Monitor is simple tool to check if such things are happening in the code ‎😅 This worth checking from time to time.

We have RC1 today, so, I am moving this ticket to the next milestone for further work.

#9 @LinSoftware
3 months ago

I attempted to reproduce the PHP warning, but the example code didn't trigger the function update_post_thumbnail_cache to run. Can additional example code be provided?

It looks like update_post_thumbnail_cache only runs in the loop context or in the admin. I agree that performing an individual query for each post is a performance issue.

#10 @peterwilsoncc
2 months ago

I've added some notes to the pull request about repeating of logic.

#11 @peterwilsoncc
2 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 59235:

Media: Account for post ID queries in update_post_thumbnail_cache().

Updates update_post_thumbnail_cache() to account for WP_Query objects that only contain the post ID field rather than the entire post object.

This changes passes the $post value to get_post_thumbnail_id() rather than assuming the presence of the ID property. Additionally, the posts to which the thumbnail is attached are now primed prior to calling the function to avoid numerous unnecessary database queries.

The test WP_Test_REST_Posts_Controller::test_get_items_primes_parent_post_caches() is modified to account for an order of operations change for the priming of post meta caches. The cache is no longer primed in the final call to update_meta_cache() so the tests need to account for the post meta to be primed in any call to the function.

Props antpb, jorbin, khokansardar, linsoftware, mukesh27, oglekler, rajinsharwar, sumitsingh, xendo.
Fixes #59521.

Note: See TracTickets for help on using tickets.