diff --git a/wp-includes/class-wp.php b/wp-includes/class-wp.php index deea1e6df8..a1bc2f1255 100644 --- a/wp-includes/class-wp.php +++ b/wp-includes/class-wp.php @@ -200,6 +200,13 @@ class WP { if ( preg_match("#^$match#", $request_match, $matches) || preg_match("#^$match#", urldecode($request_match), $matches) ) { + + if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$([^&\[]+)\[([0-9]+)\]/', $query, $varmatch ) ) { + // this is a verbose page match, lets check to be sure about it + if ( ! get_page_by_path( ${$varmatch[1]}[$varmatch[2]] ) ) + continue; + } + // Got a match. $this->matched_rule = $match; break; diff --git a/wp-includes/post.php b/wp-includes/post.php index 391818b666..09ab918ff3 100644 --- a/wp-includes/post.php +++ b/wp-includes/post.php @@ -3146,38 +3146,49 @@ function &get_page(&$page, $output = OBJECT, $filter = 'raw') { */ function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { global $wpdb; - $null = null; + $page_path = rawurlencode(urldecode($page_path)); $page_path = str_replace('%2F', '/', $page_path); $page_path = str_replace('%20', ' ', $page_path); - $page_paths = '/' . trim($page_path, '/'); - $leaf_path = sanitize_title(basename($page_paths)); - $page_paths = explode('/', $page_paths); - $full_path = ''; - foreach ( (array) $page_paths as $pathdir ) - $full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir); + $parts = explode( '/', trim( $page_path, '/' ) ); + $parts = array_map( 'esc_sql', $parts ); + $parts = array_map( 'sanitize_title', $parts ); - $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 )); + $in_string = "'". implode( "','", $parts ) . "'"; + $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 ); - if ( empty($pages) ) - return $null; + $revparts = array_reverse( $parts ); + $foundid = 0; foreach ( $pages as $page ) { - $path = '/' . $leaf_path; - $curpage = $page; - while ( $curpage->post_parent != 0 ) { - $post_parent = $curpage->post_parent; - $curpage = wp_cache_get( $post_parent, 'posts' ); - if ( false === $curpage ) - $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 ) ); - $path = '/' . $curpage->post_name . $path; - } + if ( $page->post_name == $revparts[0] ) { + $count = 0; + if ( $page->post_parent != 0 ) { + if ( null === ( $parent_page = $pages[ $page->post_parent ] ) ) + continue; - if ( $path == $full_path ) - return get_page($page->ID, $output, $post_type); + while ( $parent_page->ID != 0 ) { + $count++; + if ( $parent_page->post_name != $revparts[ $count ] ) + break; + $parent_page = $pages[ $parent_page->post_parent ]; + } + + if ( $parent_page->ID == 0 && $count+1 == count($revparts) ) { + $foundid = $page->ID; + break; + } + } else if ( count($revparts) == 1 ) { + $foundid = $page->ID; + break; + } + } } - return $null; + if ( $foundid ) + return get_page($foundid, $output, $post_type); + + return null; } /** diff --git a/wp-includes/rewrite.php b/wp-includes/rewrite.php index c7879ad53f..4502db1aa1 100644 --- a/wp-includes/rewrite.php +++ b/wp-includes/rewrite.php @@ -306,12 +306,20 @@ function url_to_postid($url) { // Look for matches. $request_match = $request; foreach ( (array)$rewrite as $match => $query) { + // If the requesting file is the anchor of the match, prepend it // to the path info. if ( !empty($url) && ($url != $request) && (strpos($match, $url) === 0) ) $request_match = $url . '/' . $request; if ( preg_match("!^$match!", $request_match, $matches) ) { + + if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$([^&\[]+)\[([0-9]+)\]/', $query, $varmatch ) ) { + // this is a verbose page match, lets check to be sure about it + if ( ! get_page_by_path( ${$varmatch[1]}[$varmatch[2]] ) ) + continue; + } + // Got a match. // Trim the query of everything up to the '?'. $query = preg_replace("!^.+\?!", '', $query); @@ -813,29 +821,9 @@ class WP_Rewrite { $rewrite_rules = array(); $page_structure = $this->get_page_permastruct(); - if ( ! $this->use_verbose_page_rules ) { - $this->add_rewrite_tag('%pagename%', "(.+?)", 'pagename='); - $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); - return $rewrite_rules; - } - - $page_uris = $this->page_uri_index(); - $uris = $page_uris[0]; - $attachment_uris = $page_uris[1]; - - if ( is_array( $attachment_uris ) ) { - foreach ( $attachment_uris as $uri => $pagename ) { - $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment='); - $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); - } - } - if ( is_array( $uris ) ) { - foreach ( $uris as $uri => $pagename ) { - $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename='); - $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); - } - } - + // the extra .? at the beginning prevents clashes with other regex's in thie structure + $this->add_rewrite_tag('%pagename%', "(.?.+?)", 'pagename='); + $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); return $rewrite_rules; } @@ -1553,7 +1541,7 @@ class WP_Rewrite { // Put them together. if ( $this->use_verbose_page_rules ) - $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); + $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); else $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);