Make WordPress Core

Changeset 18541


Ignore:
Timestamp:
08/12/2011 01:55:08 AM (15 years ago)
Author:
markjaquith
Message:

Eliminate verbose rewrite rules for ambiguous rewrite structures, resulting in massive performance gains. props andy, otto42, duck_. Nice work everyone! see #16687

Location:
trunk/wp-includes
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-wp.php

    r18467 r18541  
    201201                                        if ( preg_match("#^$match#", $request_match, $matches) ||
    202202                                                preg_match("#^$match#", urldecode($request_match), $matches) ) {
     203
     204                                                if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$([^&\[]+)\[([0-9]+)\]/', $query, $varmatch ) ) {
     205                                                        // this is a verbose page match, lets check to be sure about it
     206                                                        if ( ! get_page_by_path( ${$varmatch[1]}[$varmatch[2]] ) )
     207                                                                continue;
     208                                                }
     209
    203210                                                // Got a match.
    204211                                                $this->matched_rule = $match;
  • trunk/wp-includes/post.php

    r18513 r18541  
    31473147function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') {
    31483148        global $wpdb;
    3149         $null = null;
     3149
    31503150        $page_path = rawurlencode(urldecode($page_path));
    31513151        $page_path = str_replace('%2F', '/', $page_path);
    31523152        $page_path = str_replace('%20', ' ', $page_path);
    3153         $page_paths = '/' . trim($page_path, '/');
    3154         $leaf_path  = sanitize_title(basename($page_paths));
    3155         $page_paths = explode('/', $page_paths);
    3156         $full_path = '';
    3157         foreach ( (array) $page_paths as $pathdir )
    3158                 $full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir);
    3159 
    3160         $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = %s OR post_type = 'attachment')", $leaf_path, $post_type ));
    3161 
    3162         if ( empty($pages) )
    3163                 return $null;
    3164 
     3153        $parts = explode( '/', trim( $page_path, '/' ) );
     3154        $parts = array_map( 'esc_sql', $parts );
     3155        $parts = array_map( 'sanitize_title', $parts );
     3156
     3157        $in_string = "'". implode( "','", $parts ) . "'";
     3158        $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name IN ({$in_string}) AND (post_type = %s OR post_type = 'attachment')", $post_type ), OBJECT_K );
     3159
     3160        $revparts = array_reverse( $parts );
     3161
     3162        $foundid = 0;
    31653163        foreach ( $pages as $page ) {
    3166                 $path = '/' . $leaf_path;
    3167                 $curpage = $page;
    3168                 while ( $curpage->post_parent != 0 ) {
    3169                         $post_parent = $curpage->post_parent;
    3170                         $curpage = wp_cache_get( $post_parent, 'posts' );
    3171                         if ( false === $curpage )
    3172                                 $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type = %s", $post_parent, $post_type ) );
    3173                         $path = '/' . $curpage->post_name . $path;
     3164                if ( $page->post_name == $revparts[0] ) {
     3165                        $count = 0;
     3166                        if ( $page->post_parent != 0 ) {
     3167                                if ( null === ( $parent_page = $pages[ $page->post_parent ] ) )
     3168                                        continue;
     3169
     3170                                while ( $parent_page->ID != 0 ) {
     3171                                        $count++;
     3172                                        if ( $parent_page->post_name != $revparts[ $count ] )
     3173                                                break;
     3174                                        $parent_page = $pages[ $parent_page->post_parent ];
     3175                                }
     3176
     3177                                if ( $parent_page->ID == 0 && $count+1 == count($revparts) ) {
     3178                                        $foundid = $page->ID;
     3179                                        break;
     3180                                }
     3181                        } else if ( count($revparts) == 1 ) {
     3182                                $foundid = $page->ID;
     3183                                break;
     3184                        }
    31743185                }
    3175 
    3176                 if ( $path == $full_path )
    3177                         return get_page($page->ID, $output, $post_type);
    3178         }
    3179 
    3180         return $null;
     3186        }
     3187
     3188        if ( $foundid )
     3189                return get_page($foundid, $output, $post_type);
     3190
     3191        return null;
    31813192}
    31823193
  • trunk/wp-includes/rewrite.php

    r18540 r18541  
    307307        $request_match = $request;
    308308        foreach ( (array)$rewrite as $match => $query) {
     309
    309310                // If the requesting file is the anchor of the match, prepend it
    310311                // to the path info.
     
    313314
    314315                if ( preg_match("!^$match!", $request_match, $matches) ) {
     316
     317                        if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$([^&\[]+)\[([0-9]+)\]/', $query, $varmatch ) ) {
     318                                // this is a verbose page match, lets check to be sure about it
     319                                if ( ! get_page_by_path( ${$varmatch[1]}[$varmatch[2]] ) )
     320                                        continue;
     321                        }
     322
    315323                        // Got a match.
    316324                        // Trim the query of everything up to the '?'.
     
    814822                $page_structure = $this->get_page_permastruct();
    815823
    816                 if ( ! $this->use_verbose_page_rules ) {
    817                         $this->add_rewrite_tag('%pagename%', "(.+?)", 'pagename=');
    818                         $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
    819                         return $rewrite_rules;
    820                 }
    821 
    822                 $page_uris = $this->page_uri_index();
    823                 $uris = $page_uris[0];
    824                 $attachment_uris = $page_uris[1];
    825 
    826                 if ( is_array( $attachment_uris ) ) {
    827                         foreach ( $attachment_uris as $uri => $pagename ) {
    828                                 $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment=');
    829                                 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
    830                         }
    831                 }
    832                 if ( is_array( $uris ) ) {
    833                         foreach ( $uris as $uri => $pagename ) {
    834                                 $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename=');
    835                                 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
    836                         }
    837                 }
    838 
     824                // the extra .? at the beginning prevents clashes with other regex's in thie structure
     825                $this->add_rewrite_tag('%pagename%', "(.?.+?)", 'pagename=');
     826                $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
    839827                return $rewrite_rules;
    840828        }
     
    15541542                // Put them together.
    15551543                if ( $this->use_verbose_page_rules )
    1556                         $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $old_feed_files, $registration_pages, $page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite,  $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules);
     1544                        $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $old_feed_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite,  $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules);
    15571545                else
    15581546                        $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $old_feed_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite,  $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules);
Note: See TracChangeset for help on using the changeset viewer.