Ticket #18877: 18877.4.diff
File 18877.4.diff, 12.4 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-wp-rewrite.php
1937 1937 } 1938 1938 } 1939 1939 1940 1941 1940 1942 /** 1943 * Find a rewrite rule that matches a request. 1944 * 1945 * @since 4.5.0 1946 * @access private 1947 * @todo Explain the difference between $request and $requested_file here. Only used 1948 * for PATH_INFO links? 1949 * 1950 * @param string $request The URL to match against. 1951 * @param string $req_uri The request URI. 1952 * @param array $rewrite_rules Rewrite pairs (regex matches and rewritten query strings). 1953 * @return array|false $rewritten If a rule matches, an array containing 1954 * the match and the query. 1955 * False otherwise. 1956 */ 1957 public function find_match( $requested_path, $requested_file, $rewrite_rules ) { 1958 $found_match = false; 1959 // Look for matches. 1960 $request_match = $requested_path; 1961 if ( empty( $request_match ) ) { 1962 // An empty request could only match against ^$ regex 1963 if ( isset( $rewrite_rules['$'] ) ) { 1964 $this->matched_rule = '$'; 1965 $query = $rewrite_rules['$']; 1966 $matches = array(''); 1967 } 1968 } else { 1969 foreach ( (array) $rewrite_rules as $match => $query ) { 1970 // If the requesting file is the anchor of the match, prepend it to the path info. 1971 if ( ! empty($requested_file) && strpos($match, $requested_file) === 0 && $requested_file != $requested_path ) 1972 $request_match = $requested_file . '/' . $requested_path; 1973 1974 if ( preg_match("#^$match#", $request_match, $matches) || 1975 preg_match("#^$match#", urldecode($request_match), $matches) ) { 1976 1977 if ( $this->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 1978 // This is a verbose page match, let's check to be sure about it. 1979 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 1980 if ( ! $page ) { 1981 continue; 1982 } 1983 1984 $post_status_obj = get_post_status_object( $page->post_status ); 1985 if ( ! $post_status_obj->public && ! $post_status_obj->protected 1986 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { 1987 continue; 1988 } 1989 } 1990 1991 // Got a match. 1992 $found_match = true; 1993 break; 1994 } 1995 } 1996 } 1997 1998 if ( $found_match ) { 1999 // Trim the query of everything up to the '?'. 2000 $query = preg_replace("!^.+\?!", '', $query); 2001 2002 // Substitute the substring matches into the query. 2003 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); 2004 2005 return array( $match, $query ); 2006 } else { 2007 return false; 2008 } 2009 } 2010 2011 /** 1941 2012 * Constructor - Calls init(), which runs setup. 1942 2013 * 1943 2014 * @since 1.5.0 -
src/wp-includes/class-wp.php
210 210 $requested_path = $req_uri; 211 211 } 212 212 $requested_file = $req_uri; 213 214 213 $this->request = $requested_path; 214 $rewrite_match = $wp_rewrite->find_match( $requested_path, $requested_file, $rewrite ); 215 215 216 // Look for matches. 217 $request_match = $requested_path; 218 if ( empty( $request_match ) ) { 219 // An empty request could only match against ^$ regex 220 if ( isset( $rewrite['$'] ) ) { 221 $this->matched_rule = '$'; 222 $query = $rewrite['$']; 223 $matches = array(''); 224 } 225 } else { 226 foreach ( (array) $rewrite as $match => $query ) { 227 // If the requested file is the anchor of the match, prepend it to the path info. 228 if ( ! empty($requested_file) && strpos($match, $requested_file) === 0 && $requested_file != $requested_path ) 229 $request_match = $requested_file . '/' . $requested_path; 230 231 if ( preg_match("#^$match#", $request_match, $matches) || 232 preg_match("#^$match#", urldecode($request_match), $matches) ) { 233 234 if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 235 // This is a verbose page match, let's check to be sure about it. 236 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 237 if ( ! $page ) { 238 continue; 239 } 240 241 $post_status_obj = get_post_status_object( $page->post_status ); 242 if ( ! $post_status_obj->public && ! $post_status_obj->protected 243 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { 244 continue; 245 } 246 } 247 248 // Got a match. 249 $this->matched_rule = $match; 250 break; 251 } 252 } 253 } 254 255 if ( isset( $this->matched_rule ) ) { 256 // Trim the query of everything up to the '?'. 257 $query = preg_replace("!^.+\?!", '', $query); 258 259 // Substitute the substring matches into the query. 260 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); 261 262 $this->matched_query = $query; 263 216 if ( $rewrite_match ) { 217 $this->matched_rule = $rewrite_match[0]; 218 $this->matched_query = $rewrite_match[1]; 264 219 // Parse the query. 265 parse_str($ query, $perma_query_vars);220 parse_str($this->matched_query, $perma_query_vars); 266 221 267 222 // If we're processing a 404 request, clear the error var since we found something. 268 223 if ( '404' == $error ) -
src/wp-includes/rewrite.php
539 539 } 540 540 541 541 // Look for matches. 542 $request_match = $request; 543 foreach ( (array)$rewrite as $match => $query) { 542 $rewrite_match = $wp_rewrite->find_match( $request, $url, $rewrite ); 543 if ( $rewrite_match ) { 544 $match = $rewrite_match[0]; 545 $query = $rewrite_match[1]; 544 546 545 // If the requesting file is the anchor of the match, prepend it 546 // to the path info. 547 if ( !empty($url) && ($url != $request) && (strpos($match, $url) === 0) ) 548 $request_match = $url . '/' . $request; 549 550 if ( preg_match("#^$match#", $request_match, $matches) ) { 551 552 if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 553 // This is a verbose page match, let's check to be sure about it. 554 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 555 if ( ! $page ) { 556 continue; 547 // Filter out non-public query vars 548 global $wp; 549 parse_str( $query, $query_vars ); 550 $query = array(); 551 foreach ( (array) $query_vars as $key => $value ) { 552 if ( in_array( $key, $wp->public_query_vars ) ){ 553 $query[$key] = $value; 554 if ( isset( $post_type_query_vars[$key] ) ) { 555 $query['post_type'] = $post_type_query_vars[$key]; 556 $query['name'] = $value; 557 557 } 558 559 $post_status_obj = get_post_status_object( $page->post_status );560 if ( ! $post_status_obj->public && ! $post_status_obj->protected561 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) {562 continue;563 }564 558 } 559 } 565 560 566 // Got a match. 567 // Trim the query of everything up to the '?'. 568 $query = preg_replace("!^.+\?!", '', $query); 561 // Resolve conflicts between posts with numeric slugs and date archive queries. 562 $query = wp_resolve_numeric_slug_conflicts( $query ); 569 563 570 // Substitute the substring matches into the query. 571 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); 572 573 // Filter out non-public query vars 574 global $wp; 575 parse_str( $query, $query_vars ); 576 $query = array(); 577 foreach ( (array) $query_vars as $key => $value ) { 578 if ( in_array( $key, $wp->public_query_vars ) ){ 579 $query[$key] = $value; 580 if ( isset( $post_type_query_vars[$key] ) ) { 581 $query['post_type'] = $post_type_query_vars[$key]; 582 $query['name'] = $value; 583 } 584 } 585 } 586 587 // Resolve conflicts between posts with numeric slugs and date archive queries. 588 $query = wp_resolve_numeric_slug_conflicts( $query ); 589 590 // Do the query 591 $query = new WP_Query( $query ); 592 if ( ! empty( $query->posts ) && $query->is_singular ) 593 return $query->post->ID; 594 else 595 return 0; 596 } 564 // Do the query 565 $query = new WP_Query( $query ); 566 if ( ! empty( $query->posts ) && $query->is_singular ) 567 return $query->post->ID; 568 else 569 return 0; 597 570 } 598 571 return 0; 599 572 } -
tests/phpunit/tests/rewrite/findMatch.php
1 <?php 2 3 /** 4 * @group rewrite 5 * @group failing 6 */ 7 class Tests_Rewrite_FindMatch extends WP_UnitTestCase { 8 9 public function test_find_match() { 10 global $wp_rewrite; 11 12 $rules = array( 13 'page/?([0-9]{1,})/?$' => 'index.php?paged=$matches[1]', 14 'search/(.+)/?$' => 'index.php?s=$matches[1]', 15 'blog/author/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?author_name=$matches[1]&paged=$matches[2]', 16 'blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]', 17 ); 18 19 $match = $wp_rewrite->find_match( 'page/2', 'page/2', $rules ); 20 $expected = 'paged=2'; 21 $this->assertSame( $expected, $match[1] ); 22 23 $match = $wp_rewrite->find_match( 'search/kombucha', 'search/kombucha', $rules ); 24 $expected = 's=kombucha'; 25 $this->assertSame( $expected, $match[1] ); 26 27 $match = $wp_rewrite->find_match( 'blog/author/glerf/page/29', 'blog/author/glerf/page/29', $rules ); 28 $expected = 'author_name=glerf&paged=29'; 29 $this->assertSame( $expected, $match[1] ); 30 31 $match = $wp_rewrite->find_match( 'blog/2015/06/29', 'blog/2015/06/29', $rules ); 32 $expected = 'year=2015&monthnum=06&day=29'; 33 $this->assertSame( $expected, $match[1] ); 34 } 35 36 public function test_find_match_respects_order() { 37 global $wp_rewrite; 38 39 $rules = array( 40 'page/?([0-9]{1,})/$' => 'index.php?&paged=$matches[1]', 41 'page/?([0-9]{1,})/?$' => 'index.php?&paged=$matches[1]', 42 ); 43 44 $match = $wp_rewrite->find_match( 'page/2/', 'page/2/', $rules ); 45 $expected = 'page/?([0-9]{1,})/$'; 46 $this->assertSame( $expected, $match[0] ); 47 } 48 49 public function test_match_page_with_verbose_page_rules_on() { 50 $this->set_permalink_structure( '/%postname%/' ); 51 52 global $wp_rewrite; 53 54 $page = self::factory()->post->create( array( 55 'post_type' => 'page', 56 'post_status' => 'publish', 57 'post_name' => 'how-to-brew-kombucha', 58 ) ); 59 60 $rules = array( 61 '(.?.+?)(?:/([0-9]+))?/?$' => 'index.php?pagename=$matches[1]&page=$matches[2]', 62 '([^/]+)(?:/([0-9]+))?/?$' => 'index.php?name=$matches[1]&page=$matches[2]', 63 ); 64 65 $match = $wp_rewrite->find_match( 'how-to-brew-kombucha', 'how-to-brew-kombucha', $rules ); 66 $expected = 'pagename=how-to-brew-kombucha&page='; 67 // var_dump( $match) 68 $this->assertSame( $expected, $match[1] ); 69 } 70 71 public function test_skip_page_rule_that_doesnt_match_slug_with_verbose_page_rules_on() { 72 $this->set_permalink_structure( '/%postname%/' ); 73 74 global $wp_rewrite; 75 76 $page = self::factory()->post->create( array( 77 'post_type' => 'page', 78 'post_status' => 'publish', 79 'post_name' => 'how-to-brew-kombucha', 80 ) ); 81 82 $rules = array( 83 '(.?.+?)(?:/([0-9]+))?/?$' => 'index.php?pagename=$matches[1]&page=$matches[2]', 84 '([^/]+)(?:/([0-9]+))?/?$' => 'index.php?name=$matches[1]&page=$matches[2]', 85 ); 86 87 $match = $wp_rewrite->find_match( 'a-vertical-garden-design-for-urban-living', 'a-vertical-garden-design-for-urban-living', $rules ); 88 $expected = 'name=a-vertical-garden-design-for-urban-living&page='; 89 $this->assertSame( $expected, $match[1] ); 90 } 91 92 public function test_skip_page_rule_for_a_trashed_page_with_verbose_page_rules_on() { 93 $this->set_permalink_structure( '/%postname%/' ); 94 95 global $wp_rewrite; 96 97 $trashed_page = self::factory()->post->create( array( 98 'post_type' => 'page', 99 'post_status' => 'trash', 100 'post_name' => 'how-to-brew-kombucha', 101 ) ); 102 103 $post = self::factory()->post->create( array( 104 'post_type' => 'post', 105 'post_status' => 'publish', 106 'post_name' => 'how-to-brew-kombucha', 107 ) ); 108 109 $rules = array( 110 '(.?.+?)(?:/([0-9]+))?/?$' => 'index.php?pagename=$matches[1]&page=$matches[2]', 111 '([^/]+)(?:/([0-9]+))?/?$' => 'index.php?name=$matches[1]&page=$matches[2]', 112 ); 113 114 $match = $wp_rewrite->find_match( 'how-to-brew-kombucha', 'how-to-brew-kombucha', $rules ); 115 $expected = 'name=how-to-brew-kombucha&page='; 116 $this->assertSame( $expected, $match[1] ); 117 } 118 }