[wp-trac] [WordPress Trac] #59661: WP_Query::generate_cache_key should consider changes to request via `posts_request_ids` filter.

WordPress Trac noreply at wordpress.org
Mon Nov 27 13:17:40 UTC 2023


#59661: WP_Query::generate_cache_key  should consider changes to request via
`posts_request_ids` filter.
----------------------------------------+-----------------------------
 Reporter:  thekt12                     |       Owner:  thekt12
     Type:  defect (bug)                |      Status:  assigned
 Priority:  normal                      |   Milestone:  Future Release
Component:  Cache API                   |     Version:
 Severity:  minor                       |  Resolution:
 Keywords:  needs-unit-tests has-patch  |     Focuses:
----------------------------------------+-----------------------------

Comment (by thekt12):

 A sample code to indicate the issue. In the following code I am running
 two queries, each should result in a different output. However, the way we
 generate the cache key, causes both the query to return the same output.

 {{{
 // IGNORE THIS
 add_action( 'init', 'add_few_posts_to_test' );
 function add_few_posts_to_test() {
         // create 2 post with slug 'a' and 'b' if it doesn't exist
         $slugs = [ 'a', 'b', 'c' ];
         foreach ( $slugs as $slug ) {
                 $post = get_page_by_path( $slug, OBJECT, 'post' );
                 if ( ! $post ) {
                         $post = wp_insert_post(
                                 array(
                                         'post_title'  => $slug,
                                         'post_status' => 'publish',
                                         'post_type'   => 'post',
                                         'post_name'   => $slug,
                                 )
                         );
                 }
         }
 }

 // ACTUAL ISSUE ->
 add_filter( 'posts_request_ids', 'wp_posts_reqs', 10, 2 );
 function wp_posts_reqs( $request, $query ) {
         if( $query->query_vars['post_name__in'] === [ 'a', 'b', 'c' ] ) {
                 $request = str_replace( "'a',", '', $request );
         }
         return $request;
 }

 add_action( 'init', 'test_query_aa' );
 function test_query_aa() {
         echo '<pre>';
         echo "Query has posts_request_ids filter - ". (int)(bool)
 has_filter( 'posts_request_ids', 'wp_posts_reqs' ) . "<br>";
         $queryR_1 = get_posts(
                 array(
                         'cache_results'  => true,
                         'post_type'      => 'post',
                         'post_name__in'  => [ 'a', 'b', 'c' ],
                 )
         );
         print_r( $queryR_1 );
         remove_filter( 'posts_request_ids', 'wp_posts_reqs' );
         echo "<br>Query has posts_request_ids filter after removal -
 ".(int)(bool) has_filter( 'posts_request_ids', 'wp_posts_reqs' ) . "<br>";
         $queryR_2 = get_posts(
                 array(
                         'cache_results'  => true,
                         'post_type'      => 'post',
                         'post_name__in'  => [ 'a', 'b', 'c' ]
                 )
         );
         print_r( $queryR_2 );
         die( '</pre>' );
 }
 }}}

 [https://github.com/WordPress/wordpress-develop/pull/5513 PR 5513] address
 the above scenario.


 However, the PR doesn't address the problem of dynamic conditional logic
 inside  `'posts_request_ids'` like the code given below-

 {{{

 add_filter( 'posts_request_ids', 'wp_posts_reqs', 10, 2 );
 function wp_posts_reqs( $request, $query ) {
         if( $query->query_vars['post_name__in'] === [ 'a', 'b', 'c' ] ) {
                 static $count = 0;
                 if( $count%2 === 0 ) {
                         $request = str_replace( "'a',", '', $request );
                 }
                 $count++;
         }
         return $request;
 }

 add_action( 'init', 'test_query_aa' );
 function test_query_aa() {
         echo '<pre>';
         echo "Query has posts_request_ids filter - ". (int)(bool)
 has_filter( 'posts_request_ids', 'wp_posts_reqs' ) . "<br>";
         $queryR_1 = get_posts(
                 array(
                         'cache_results'  => true,
                         'post_type'      => 'post',
                         'post_name__in'  => [ 'a', 'b', 'c' ],
                 )
         );
         print_r( $queryR_1 );
         $queryR_2 = get_posts(
                 array(
                         'cache_results'  => true,
                         'post_type'      => 'post',
                         'post_name__in'  => [ 'a', 'b', 'c' ]
                 )
         );
         print_r( $queryR_2 );
         echo '</pre>';
         die();
 }
 }}}

 For the second scenario, disabling `cache_results` for the query is the
 only solution I could think of at the moment.

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


More information about the wp-trac mailing list