Make WordPress Core

Changeset 37479


Ignore:
Timestamp:
05/21/2016 05:26:55 PM (9 years ago)
Author:
boonebgorges
Message:

Cache queries in get_page_by_path().

Props spacedmonkey.
Fixes #36711.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/post.php

    r37403 r37479  
    42324232    global $wpdb;
    42334233
     4234    $last_changed = wp_cache_get( 'last_changed', 'posts' );
     4235    if ( false === $last_changed ) {
     4236        $last_changed = microtime();
     4237        wp_cache_set( 'last_changed', $last_changed, 'posts' );
     4238    }
     4239
     4240    $hash = md5( $page_path . serialize( $post_type ) );
     4241    $cache_key = "get_page_by_path:$hash:$last_changed";
     4242    $cached = wp_cache_get( $cache_key, 'posts' );
     4243    if ( false !== $cached ) {
     4244        // Special case: '0' is a bad `$page_path`.
     4245        if ( '0' === $cached || 0 === $cached ) {
     4246            return;
     4247        } else {
     4248            return get_post( $cached );
     4249        }
     4250    }
     4251
    42344252    $page_path = rawurlencode(urldecode($page_path));
    42354253    $page_path = str_replace('%2F', '/', $page_path);
     
    42854303        }
    42864304    }
     4305
     4306    // We cache misses as well as hits.
     4307    wp_cache_set( $cache_key, $foundid, 'posts' );
    42874308
    42884309    if ( $foundid ) {
  • trunk/tests/phpunit/tests/post/getPageByPath.php

    r37478 r37479  
    124124        $this->assertNull( $found );
    125125    }
     126
     127    /**
     128     * @ticket 36711
     129     */
     130    public function test_should_hit_cache() {
     131        global $wpdb;
     132
     133        $page = self::factory()->post->create( array(
     134            'post_type' => 'page',
     135            'post_name' => 'foo',
     136        ) );
     137
     138        // Prime cache.
     139        $found = get_page_by_path( 'foo' );
     140        $this->assertSame( $page, $found->ID );
     141
     142        $num_queries = $wpdb->num_queries;
     143
     144        $found = get_page_by_path( 'foo' );
     145        $this->assertSame( $page, $found->ID );
     146        $this->assertSame( $num_queries, $wpdb->num_queries );
     147    }
     148
     149    /**
     150     * @ticket 36711
     151     */
     152    public function test_bad_path_should_be_cached() {
     153        global $wpdb;
     154
     155        // Prime cache.
     156        $found = get_page_by_path( 'foo' );
     157        $this->assertNull( $found );
     158
     159        $num_queries = $wpdb->num_queries;
     160
     161        $found = get_page_by_path( 'foo' );
     162        $this->assertNull( $found );
     163        $this->assertSame( $num_queries, $wpdb->num_queries );
     164    }
     165
     166    /**
     167     * @ticket 36711
     168     */
     169    public function test_bad_path_served_from_cache_should_not_fall_back_on_current_post() {
     170        global $wpdb, $post;
     171
     172        // Fake the global.
     173        $post = self::factory()->post->create_and_get();
     174
     175        // Prime cache.
     176        $found = get_page_by_path( 'foo' );
     177        $this->assertNull( $found );
     178
     179        $num_queries = $wpdb->num_queries;
     180
     181        $found = get_page_by_path( 'foo' );
     182        $this->assertNull( $found );
     183        $this->assertSame( $num_queries, $wpdb->num_queries );
     184
     185        unset( $post );
     186    }
     187
     188    /**
     189     * @ticket 36711
     190     */
     191    public function test_cache_should_not_match_post_in_different_post_type_with_same_path() {
     192        global $wpdb;
     193
     194        register_post_type( 'wptests_pt' );
     195
     196        $p1 = self::factory()->post->create( array(
     197            'post_type' => 'page',
     198            'post_name' => 'foo',
     199        ) );
     200
     201        $p2 = self::factory()->post->create( array(
     202            'post_type' => 'wptests_pt',
     203            'post_name' => 'foo',
     204        ) );
     205
     206        // Prime cache for the page.
     207        $found = get_page_by_path( 'foo' );
     208        $this->assertSame( $p1, $found->ID );
     209
     210        $num_queries = $wpdb->num_queries;
     211
     212        $found = get_page_by_path( 'foo', OBJECT, 'wptests_pt' );
     213        $this->assertSame( $p2, $found->ID );
     214        $num_queries++;
     215        $this->assertSame( $num_queries, $wpdb->num_queries );
     216    }
     217
     218    /**
     219     * @ticket 36711
     220     */
     221    public function test_cache_should_be_invalidated_when_post_name_is_edited() {
     222        global $wpdb;
     223
     224        $page = self::factory()->post->create( array(
     225            'post_type' => 'page',
     226            'post_name' => 'foo',
     227        ) );
     228
     229        // Prime cache.
     230        $found = get_page_by_path( 'foo' );
     231        $this->assertSame( $page, $found->ID );
     232
     233        wp_update_post( array(
     234            'ID' => $page,
     235            'post_name' => 'bar',
     236        ) );
     237
     238        $num_queries = $wpdb->num_queries;
     239
     240        $found = get_page_by_path( 'bar' );
     241        $this->assertSame( $page, $found->ID );
     242        $num_queries++;
     243        $this->assertSame( $num_queries, $wpdb->num_queries );
     244    }
    126245}
Note: See TracChangeset for help on using the changeset viewer.