Ticket #18877: 36292-after-18877.diff
File 36292-after-18877.diff, 13.1 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-wp-rewrite-rule.php
1 <?php 2 3 /** 4 * Rewrite rule handler. 5 */ 6 class WP_Rewrite_Rule implements WP_Rewrite_RuleInterface { 7 /** 8 * Traditional query string/array. 9 * 10 * @var string|array `index.php`-prefixed query string, or query argument map. 11 */ 12 public $query = null; 13 14 /** 15 * Constructor. 16 * 17 * @param string|array $query Query string/argument map. 18 */ 19 public function __construct( $query = null ) { 20 if ( $query ) { 21 $this->query = $query; 22 } 23 } 24 25 /** 26 * Get string representation of the rule. 27 * 28 * Primarily for backwards compatibility. 29 * 30 * @return string String representation of the rewrite rule. 31 */ 32 public function __toString() { 33 return is_array( $this->query ) ? 'index.php?' . build_query( $this->query ) : $this->query; 34 } 35 36 /** 37 * Should this rule skip the main query? 38 * 39 * @return bool 40 */ 41 public function should_skip_main_query() { 42 return $this->skip_main_query; 43 } 44 45 /** 46 * Parse pattern matches into query string. 47 * 48 * @param array $matches Regex matched groups from `$this->pattern` 49 * @return array Query vars. 50 */ 51 public function get_query_vars( $matches ) { 52 if ( ! $this->query ) { 53 // Empty query, but ensure we run the main query anyway. 54 return array(); 55 } 56 57 // Trim the query of everything up to the '?'. 58 $query = preg_replace( '!^.+\?!', '', $this->query ); 59 60 // Substitute the substring matches into the query. 61 $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) ); 62 63 // Parse into an array 64 parse_str( $query, $perma_query_vars ); 65 66 return $perma_query_vars; 67 } 68 69 /** 70 * Get verbose page match parameter. 71 * 72 * @return int|bool Match offset number, or false if non-verbose page pattern. 73 */ 74 public function get_verbose_page_match() { 75 if ( ! $this->query ) { 76 return false; 77 } 78 79 $matches = preg_match( '/pagename=\$matches\[([0-9]+)\]/', $this->query, $varmatch ); 80 if ( ! $matches ) { 81 return false; 82 } 83 84 return $varmatch; 85 } 86 87 /** 88 * Should we skip this rewrite rule? 89 * 90 * @param array $matches Regex matched groups from `$this->pattern` 91 * @return boolean True if the rule should be skipped, false if the rule should be used. 92 */ 93 public function should_skip( $matches ) { 94 global $wp_rewrite; 95 96 if ( ! $this->query || ! $wp_rewrite->use_verbose_page_rules ) { 97 return false; 98 } 99 100 $needs_verbose_match = preg_match( '/pagename=\$matches\[([0-9]+)\]/', $this->query, $varmatch ); 101 if ( ! $needs_verbose_match ) { 102 return false; 103 } 104 105 // This is a verbose page match, let's check to be sure about it. 106 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 107 if ( ! $page ) { 108 // Page doesn't exist, skip rule. 109 return true; 110 } 111 112 $post_status_obj = get_post_status_object( $page->post_status ); 113 if ( ! $post_status_obj->public && ! $post_status_obj->protected 114 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { 115 // Page isn't public, skip rule. 116 return true; 117 } 118 119 return false; 120 } 121 } -
src/wp-includes/class-wp-rewrite-ruleinterface.php
1 <?php 2 3 interface WP_Rewrite_RuleInterface { 4 /** 5 * Parse pattern matches into query string. 6 * 7 * @param array $matches Regex matched groups from `$this->pattern` 8 * @return array|null Query vars if required. `null` will skip the main query. 9 */ 10 public function get_query_vars( $matches ); 11 12 /** 13 * Should the rule be skipped? 14 * 15 * A rule may be skipped if it relies on other criteria apart from the 16 * pattern to match. For example, the page rewrite rule is skipped if the 17 * corresponding page doesn't exist. 18 * 19 * @param array $matches Regex matched groups from `$this->pattern` 20 * @return boolean True if the rule should be skipped, false if the rule should be used. 21 */ 22 public function should_skip( $matches ); 23 } -
src/wp-includes/class-wp-rewrite.php
1637 1637 * or 'bottom'. Default 'bottom'. 1638 1638 */ 1639 1639 public function add_rule( $regex, $query, $after = 'bottom' ) { 1640 if ( is_array( $query ) ) { 1640 if ( $query instanceof WP_Rewrite_RuleInterface ) { 1641 // Rule objects are for internal rewrites only. 1641 1642 $external = false; 1643 } elseif ( is_array( $query ) ) { 1644 $external = false; 1642 1645 $query = add_query_arg( $query, 'index.php' ); 1643 1646 } else { 1644 1647 $index = false === strpos( $query, '?' ) ? strlen( $query ) : strpos( $query, '?' ); … … 1651 1654 if ( $external ) { 1652 1655 $this->add_external_rule( $regex, $query ); 1653 1656 } else { 1657 // Upgrade to rule object 1658 $rule = $query; 1659 if ( ! ( $rule instanceof WP_Rewrite_RuleInterface ) ) { 1660 $rule = new WP_Rewrite_Rule( $query ); 1661 } 1662 1654 1663 if ( 'bottom' == $after ) { 1655 $this->extra_rules = array_merge( $this->extra_rules, array( $regex => $ query) );1664 $this->extra_rules = array_merge( $this->extra_rules, array( $regex => $rule ) ); 1656 1665 } else { 1657 $this->extra_rules_top = array_merge( $this->extra_rules_top, array( $regex => $ query) );1666 $this->extra_rules_top = array_merge( $this->extra_rules_top, array( $regex => $rule ) ); 1658 1667 } 1659 1668 } 1660 1669 } … … 1938 1947 } 1939 1948 1940 1949 /** 1950 * Get the rewrite rule that matches a request. 1951 * 1952 * @since 4.6.0 1953 * 1954 * @param string $requested_path The URL path to match against. 1955 * @param string $requested_file The requested file, for PATHINFO links. 1956 * @return array|false $rewritten If a rule matches, an array containing 1957 * the match and the query. 1958 * False otherwise. 1959 */ 1960 public function get_rewrite_rule_for_request( $requested_path, $requested_file ) { 1961 $rewrite_rules = $this->wp_rewrite_rules(); 1962 if ( empty( $rewrite_rules ) ) { 1963 return false; 1964 } 1965 1966 // Look for matches. 1967 $request_match = $requested_path; 1968 if ( empty( $request_match ) ) { 1969 // An empty request could only match against ^$ regex 1970 if ( isset( $rewrite['$'] ) ) { 1971 $rule = $rewrite['$']; 1972 1973 // Upgrade rule to an object if required. 1974 if ( is_string( $rule ) || is_array( $rule ) ) { 1975 $rule = new WP_Rewrite_Rule( $rewrite['$'] ); 1976 } 1977 1978 return array( '$', $rule, array( '' ) ); 1979 } 1980 1981 // Empty request, and no ^$ rule. 1982 return false; 1983 } 1984 1985 foreach ( (array) $rewrite_rules as $match => $rule ) { 1986 // If the requested file is the anchor of the match, prepend it to the path info. 1987 if ( ! empty( $requested_file ) && strpos( $match, $requested_file ) === 0 1988 && $requested_file != $requested_path ) { 1989 $request_match = $requested_file . '/' . $requested_path; 1990 } 1991 1992 if ( preg_match( "#^$match#", $request_match, $matches ) || 1993 preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { 1994 1995 // Upgrade rule to an object if required. 1996 if ( is_string( $rule ) || is_array( $rule ) ) { 1997 $rule = new WP_Rewrite_Rule( $rule ); 1998 } 1999 2000 if ( $rule->should_skip( $matches ) ) { 2001 continue; 2002 } 2003 2004 // Got a match. 2005 return array( $match, $rule, $matches ); 2006 } 2007 } 2008 2009 // No matches. 2010 return false; 2011 } 2012 2013 /** 1941 2014 * Constructor - Calls init(), which runs setup. 1942 2015 * 1943 2016 * @since 1.5.0 -
src/wp-includes/class-wp.php
65 65 public $request; 66 66 67 67 /** 68 * Rewrite rule the request matched.68 * Rewrite rule pattern the request matched. 69 69 * 70 70 * @since 2.0.0 71 71 * @access public … … 74 74 public $matched_rule; 75 75 76 76 /** 77 * Rewrite rule object the request matched. 78 * 79 * @access public 80 * @var WP_Rewrite_RuleInterface 81 */ 82 public $matched_rule_object; 83 84 /** 77 85 * Rewrite query the request matched. 78 86 * 79 87 * @since 2.0.0 … … 92 100 public $did_permalink = false; 93 101 94 102 /** 103 * Should we perform the main query? 104 * 105 * @since 4.6.0 106 * @access public 107 * @var bool 108 */ 109 public $perform_main_query = true; 110 111 /** 95 112 * Add name to list of public query variables. 96 113 * 97 114 * @since 2.1.0 … … 212 229 $requested_file = $req_uri; 213 230 214 231 $this->request = $requested_path; 232 $rewrite_match = $wp_rewrite->get_rewrite_rule_for_request( $requested_path, $requested_file ); 215 233 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; 234 if ( $rewrite_match ) { 235 $this->matched_rule = $rewrite_match[0]; 236 $this->matched_rule_object = $rewrite_match[1]; 237 $matches = $rewrite_match[2]; 230 238 231 if ( preg_match("#^$match#", $request_match, $matches) ||232 preg_match("#^$match#", urldecode($request_match), $matches) ) {239 // Substitute the substring matches into the query. 240 $query = $this->matched_rule_object->get_query_vars( $matches ); 233 241 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 } 242 if ( is_array( $query ) ) { 243 $perma_query_vars = $query; 240 244 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 } 245 // For backwards compatibility, store as a string. 246 $this->matched_query = http_build_query( $query, '', '&' ); 247 } else { 248 // Skip the main query. 249 $this->perform_main_query = false; 250 $this->matched_query = ''; 252 251 } 253 }254 252 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 264 // Parse the query.265 parse_str($query, $perma_query_vars);266 267 253 // If we're processing a 404 request, clear the error var since we found something. 268 254 if ( '404' == $error ) 269 255 unset( $error, $_GET['error'] ); … … 606 592 public function query_posts() { 607 593 global $wp_the_query; 608 594 $this->build_query_string(); 609 $wp_the_query->query( $this->query_vars);595 $wp_the_query->query( $this->query_vars ); 610 596 } 611 597 612 598 /** … … 724 710 $this->init(); 725 711 $this->parse_request($query_args); 726 712 $this->send_headers(); 727 $this->query_posts();728 $this->handle_404();729 $this->register_globals();730 713 731 714 /** 715 * Filter whether the main query should be run. 716 * 717 * Pages that don't require the main query should return `null` from a 718 * WP_Rewrite_RuleInterface object, or filter this value to false. 719 * 720 * @since 4.6.0 721 * 722 * @param bool $perform_query True to run the main query, false to skip. 723 * @param string $matched_rule Regular expression used to match the current request. 724 * @param WP_Rewrite_RuleInterface $matched_rule_object Rule object handling the current request. 725 */ 726 $peform_query = apply_filters( 'perform_main_query', $this->perform_main_query, $this->matched_rule, $this->matched_rule_object ); 727 if ( $peform_query ) { 728 $this->query_posts(); 729 $this->handle_404(); 730 $this->register_globals(); 731 } 732 733 /** 732 734 * Fires once the WordPress environment has been set up. 733 735 * 734 736 * @since 2.1.0 -
src/wp-settings.php
172 172 require( ABSPATH . WPINC . '/comment-template.php' ); 173 173 require( ABSPATH . WPINC . '/rewrite.php' ); 174 174 require( ABSPATH . WPINC . '/class-wp-rewrite.php' ); 175 require( ABSPATH . WPINC . '/class-wp-rewrite-ruleinterface.php' ); 176 require( ABSPATH . WPINC . '/class-wp-rewrite-rule.php' ); 175 177 require( ABSPATH . WPINC . '/feed.php' ); 176 178 require( ABSPATH . WPINC . '/bookmark.php' ); 177 179 require( ABSPATH . WPINC . '/bookmark-template.php' );