Ticket #18877: 18877.3.diff
File 18877.3.diff, 12.1 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-wp-rewrite.php
1938 1938 } 1939 1939 1940 1940 /** 1941 * Find a rewrite rule that matches a request. 1942 * 1943 * @since 4.5.0 1944 * @access private 1945 * @todo Explain the difference between $request and $req_uri here. Only used 1946 * for PATH_INFO links? 1947 * 1948 * @param string $request The URL to match against. 1949 * @param string $req_uri The request URI. 1950 * @param array $rewrite_rules Rewrite pairs (regex matches and rewritten query strings). 1951 * @return array|false $rewritten If a rule matches, an array containing 1952 * the match and the query. 1953 * False otherwise. 1954 */ 1955 public function find_match( $request, $req_uri, $rewrite_rules ) { 1956 $found_match = false; 1957 // Look for matches. 1958 $request_match = $request; 1959 if ( empty( $request_match ) ) { 1960 // An empty request could only match against ^$ regex 1961 if ( isset( $rewrite_rules['$'] ) ) { 1962 $this->matched_rule = '$'; 1963 $query = $rewrite_rules['$']; 1964 $matches = array(''); 1965 } 1966 } else { 1967 foreach ( (array) $rewrite_rules as $match => $query ) { 1968 // If the requesting file is the anchor of the match, prepend it to the path info. 1969 if ( ! empty($req_uri) && strpos($match, $req_uri) === 0 && $req_uri != $request ) 1970 $request_match = $req_uri . '/' . $request; 1971 1972 if ( preg_match("#^$match#", $request_match, $matches) || 1973 preg_match("#^$match#", urldecode($request_match), $matches) ) { 1974 1975 if ( $this->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 1976 // This is a verbose page match, let's check to be sure about it. 1977 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 1978 if ( ! $page ) { 1979 continue; 1980 } 1981 1982 $post_status_obj = get_post_status_object( $page->post_status ); 1983 if ( ! $post_status_obj->public && ! $post_status_obj->protected 1984 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { 1985 continue; 1986 } 1987 } 1988 1989 // Got a match. 1990 $found_match = true; 1991 break; 1992 } 1993 } 1994 } 1995 1996 if ( $found_match ) { 1997 // Trim the query of everything up to the '?'. 1998 $query = preg_replace("!^.+\?!", '', $query); 1999 2000 // Substitute the substring matches into the query. 2001 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); 2002 2003 return array( $match, $query ); 2004 } else { 2005 return false; 2006 } 2007 } 2008 2009 /** 1941 2010 * Constructor - Calls init(), which runs setup. 1942 2011 * 1943 2012 * @since 1.5.0 -
src/wp-includes/class-wp.php
200 200 201 201 $this->request = $request; 202 202 203 // Look for matches. 204 $request_match = $request; 205 if ( empty( $request_match ) ) { 206 // An empty request could only match against ^$ regex 207 if ( isset( $rewrite['$'] ) ) { 208 $this->matched_rule = '$'; 209 $query = $rewrite['$']; 210 $matches = array(''); 211 } 212 } else { 213 foreach ( (array) $rewrite as $match => $query ) { 214 // If the requesting file is the anchor of the match, prepend it to the path info. 215 if ( ! empty($req_uri) && strpos($match, $req_uri) === 0 && $req_uri != $request ) 216 $request_match = $req_uri . '/' . $request; 203 $result = $wp_rewrite->find_match( $request, $req_uri, $rewrite ); 217 204 218 if ( preg_match("#^$match#", $request_match, $matches) || 219 preg_match("#^$match#", urldecode($request_match), $matches) ) { 205 if ( $result ) { 206 $this->matched_rule = $result[0]; 207 $this->matched_query = $result[1]; 220 208 221 if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) {222 // This is a verbose page match, let's check to be sure about it.223 $page = get_page_by_path( $matches[ $varmatch[1] ] );224 if ( ! $page ) {225 continue;226 }227 228 $post_status_obj = get_post_status_object( $page->post_status );229 if ( ! $post_status_obj->public && ! $post_status_obj->protected230 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) {231 continue;232 }233 }234 235 // Got a match.236 $this->matched_rule = $match;237 break;238 }239 }240 }241 242 if ( isset( $this->matched_rule ) ) {243 // Trim the query of everything up to the '?'.244 $query = preg_replace("!^.+\?!", '', $query);245 246 // Substitute the substring matches into the query.247 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches));248 249 $this->matched_query = $query;250 251 209 // Parse the query. 252 parse_str($ query, $perma_query_vars);210 parse_str($this->matched_query, $perma_query_vars); 253 211 254 212 // If we're processing a 404 request, clear the error var since we found something. 255 213 if ( '404' == $error ) -
src/wp-includes/rewrite.php
538 538 } 539 539 540 540 // Look for matches. 541 $request_match = $request; 542 foreach ( (array)$rewrite as $match => $query) { 541 $result = $wp_rewrite->find_match( $request, $url, $rewrite ); 542 if ( $result ) { 543 // Got a match. 544 $match = $result[0]; 545 $query = $result[1]; 543 546 544 // If the requesting file is the anchor of the match, prepend it 545 // to the path info. 546 if ( !empty($url) && ($url != $request) && (strpos($match, $url) === 0) ) 547 $request_match = $url . '/' . $request; 548 549 if ( preg_match("#^$match#", $request_match, $matches) ) { 550 551 if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 552 // This is a verbose page match, let's check to be sure about it. 553 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 554 if ( ! $page ) { 555 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; 556 557 } 557 558 $post_status_obj = get_post_status_object( $page->post_status );559 if ( ! $post_status_obj->public && ! $post_status_obj->protected560 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) {561 continue;562 }563 558 } 559 } 564 560 565 // Got a match. 566 // Trim the query of everything up to the '?'. 567 $query = preg_replace("!^.+\?!", '', $query); 561 // Resolve conflicts between posts with numeric slugs and date archive queries. 562 $query = wp_resolve_numeric_slug_conflicts( $query ); 568 563 569 // Substitute the substring matches into the query. 570 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); 571 572 // Filter out non-public query vars 573 global $wp; 574 parse_str( $query, $query_vars ); 575 $query = array(); 576 foreach ( (array) $query_vars as $key => $value ) { 577 if ( in_array( $key, $wp->public_query_vars ) ){ 578 $query[$key] = $value; 579 if ( isset( $post_type_query_vars[$key] ) ) { 580 $query['post_type'] = $post_type_query_vars[$key]; 581 $query['name'] = $value; 582 } 583 } 584 } 585 586 // Resolve conflicts between posts with numeric slugs and date archive queries. 587 $query = wp_resolve_numeric_slug_conflicts( $query ); 588 589 // Do the query 590 $query = new WP_Query( $query ); 591 if ( ! empty( $query->posts ) && $query->is_singular ) 592 return $query->post->ID; 593 else 594 return 0; 595 } 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; 596 570 } 597 571 return 0; 598 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 }