Ticket #48223: 48223-wp-refactor.patch
File 48223-wp-refactor.patch, 37.4 KB (added by , 10 months ago) |
---|
-
new file wp-includes/class-wp-request-environment.php
--- wp-includes/class-wp-request-environment.php | 649 +++++++++++++++++++++++++++ wp-includes/class-wp.php | 474 ++----------------- wp-settings.php | 1 + 3 files changed, 690 insertions(+), 434 deletions(-) create mode 100644 wp-includes/class-wp-request-environment.php diff --git a/wp-includes/class-wp-request-environment.php b/wp-includes/class-wp-request-environment.php new file mode 100644 index 0000000000..0d92289b22
- + 1 <?php 2 /** 3 * WordPress Request Environment. 4 * 5 * @package WordPress 6 * @since x.x.x 7 */ 8 class WP_Request_Environment { 9 /** 10 * Public query variables. 11 * 12 * Long list of public query variables. 13 * 14 * @since 2.0.0 15 * @var string[] 16 */ 17 public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'favicon', 'taxonomy', 'term', 'cpage', 'post_type', 'embed' ); 18 19 /** 20 * Private query variables. 21 * 22 * Long list of private query variables. 23 * 24 * @since 2.0.0 25 * @var string[] 26 */ 27 public $private_query_vars = array( 'offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in', 'post_parent', 'post_parent__in', 'post_parent__not_in', 'title', 'fields' ); 28 29 /** 30 * Extra query variables set by the user. 31 * 32 * @since 2.1.0 33 * @var array 34 */ 35 public $extra_query_vars = array(); 36 37 /** 38 * Query variables for setting up the WordPress Query Loop. 39 * 40 * @since 2.0.0 41 * @var array 42 */ 43 public $query_vars; 44 45 /** 46 * String parsed to set the query variables. 47 * 48 * @since 2.0.0 49 * @var string 50 */ 51 public $query_string; 52 53 /** 54 * The request path, e.g. 2015/05/06. 55 * 56 * @since 2.0.0 57 * @var string 58 */ 59 public $request; 60 61 /** 62 * The server environment - either a copy of $_SERVER or virtual 63 * 64 * @since x.x.x 65 * @var array 66 */ 67 public $server; 68 69 /** 70 * The GET request - either a copy of $_GET or virtual 71 * 72 * @since x.x.x 73 * @var array 74 */ 75 public $get; 76 77 /** 78 * The POST request - either a copy of $_POST or virtual 79 * 80 * @since x.x.x 81 * @var array 82 */ 83 public $post; 84 85 /** 86 * Whether we want to match all rules. 87 * 88 * @since x.x.x 89 * @var boolean 90 */ 91 public $parse_multiple_rules; 92 93 /** 94 * Rewrite rule the request matched. 95 * 96 * @since x.x.x 97 * @var array 98 */ 99 public $all_matched_rules = array(); 100 101 /** 102 * Rewrite rule the request matched. 103 * 104 * @since 2.0.0 105 * @var string 106 */ 107 public $matched_rule; 108 109 /** 110 * Rewrite query the request matched. 111 * 112 * @since 2.0.0 113 * @var string 114 */ 115 public $matched_query; 116 117 /** 118 * Whether already did the permalink. 119 * 120 * @since 2.0.0 121 * @var bool 122 */ 123 public $did_permalink = false; 124 125 /** 126 * Internal (private?) The index of rule we're matching (@see $this->all_matched_rules). 127 * 128 * @since x.x.x 129 * @var int 130 */ 131 public $current_rule; 132 133 /** 134 * Internal (private?) Whether we believe request should result in 404 error. 135 * 136 * @since x.x.x 137 * @var bool 138 */ 139 public $error; 140 141 /** 142 * Internal (private?) Query vars extracted from permalink rewrite rule matching 143 * 144 * @since x.x.x 145 * @var bool 146 */ 147 public $perma_query_vars; 148 149 /** 150 * Add name to list of public query variables. 151 * 152 * @since 2.1.0 153 * 154 * @param string $qv Query variable name. 155 */ 156 public function add_query_var( $qv ) { 157 if ( ! in_array( $qv, $this->public_query_vars ) ) { 158 $this->public_query_vars[] = $qv; 159 } 160 } 161 162 /** 163 * Removes a query variable from a list of public query variables. 164 * 165 * @since 4.5.0 166 * 167 * @param string $name Query variable name. 168 */ 169 public function remove_query_var( $name ) { 170 $this->public_query_vars = array_diff( $this->public_query_vars, array( $name ) ); 171 } 172 173 /** 174 * Set the value of a query variable. 175 * 176 * @since 2.3.0 177 * 178 * @param string $key Query variable name. 179 * @param mixed $value Query variable value. 180 */ 181 public function set_query_var( $key, $value ) { 182 $this->query_vars[ $key ] = $value; 183 } 184 185 /** 186 * Setup Request Environment 187 * 188 * When extending class to write virtual environment - override this method 189 * 190 * @since x.x.x 191 */ 192 public function setup_request_environment( $server=[], $get=[], $post=[], $wp_query=null, $wp_rewrite=null ){ 193 194 $this->server = $server; 195 $this->get = $get; 196 $this->post = $post; 197 $this->wp_query = $wp_query; 198 $this->wp_rewrite = $wp_rewrite; 199 200 } 201 202 203 /** 204 * Parse request to find correct WordPress query. 205 * 206 * Sets up the query variables based on the request. There are also many 207 * filters and actions that can be used to further manipulate the result. 208 * 209 * @since 2.0.0 210 * 211 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 212 * 213 * @param array|string $extra_query_vars Set the extra query variables. 214 */ 215 public function parse_request( $extra_query_vars = '' ) { 216 217 /** 218 * Filters whether to parse the request. 219 * 220 * @since 3.5.0 221 * 222 * @param bool $bool Whether or not to parse the request. Default true. 223 * @param WP $this Current WordPress environment instance. 224 * @param array|string $extra_query_vars Extra passed query variables. 225 */ 226 if ( ! apply_filters( 'do_parse_request', true, $this, $extra_query_vars ) ) { 227 return; 228 } 229 230 $this->_match_rewrite_rules(); 231 $this->_match_single_rule(); 232 $this->_parse_request( $extra_query_vars ); 233 } 234 235 236 /** 237 * Match Rewrite Rules 238 * 239 * Matches request against all rewrite rules. 240 * Sets current_rule index to 0 241 * 242 * @internal Do not use this directly. Use $this->parse_request(). 243 * 244 * @since x.x.x 245 */ 246 public function _match_rewrite_rules(){ 247 248 $rewrite = $this->wp_rewrite->wp_rewrite_rules(); 249 250 if ( empty( $rewrite ) ) { 251 return; 252 } 253 254 $home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' ); 255 $home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) ); 256 257 $pathinfo = isset( $this->server['PATH_INFO'] ) ? $this->server['PATH_INFO'] : ''; 258 $pathinfo = reset( explode( '?', $pathinfo ) ); 259 $pathinfo = str_replace( '%', '%25', $pathinfo ); 260 $pathinfo = trim( $pathinfo, '/' ); 261 $pathinfo = preg_replace( $home_path_regex, '', $pathinfo ); 262 $pathinfo = trim( $pathinfo, '/' ); 263 264 $req_uri = reset( explode( '?', $this->server['REQUEST_URI'] ) ); 265 $req_uri = str_replace( $pathinfo, '', $req_uri ); 266 $req_uri = trim( $req_uri, '/' ); 267 $req_uri = preg_replace( $home_path_regex, '', $req_uri ); 268 $req_uri = trim( $req_uri, '/' ); 269 270 $self = $this->server['PHP_SELF']; 271 $self = trim( $self, '/' ); 272 $self = preg_replace( $home_path_regex, '', $self ); 273 $self = trim( $self, '/' ); 274 275 276 // The requested permalink is in $pathinfo for path info requests and 277 // $req_uri for other requests. 278 if ( ! empty( $pathinfo ) && ! preg_match( '|^.*' . $this->wp_rewrite->index . '$|', $pathinfo ) ) { 279 $this->request = $pathinfo; 280 } else { 281 // If the request uri is the index, blank it out so that we don't try to match it against a rule. 282 if ( $req_uri == $this->wp_rewrite->index ) { 283 $req_uri = ''; 284 } 285 $this->request = $req_uri; 286 } 287 $this->requested_file = $req_uri; 288 $this->self = $self; 289 290 // Look for matches. 291 $request_match = $this->request; 292 if ( empty( $request_match ) ) { 293 // An empty request could only match against ^$ regex. 294 if ( isset( $rewrite['$'] ) ) { 295 $this->all_matched_rules[] = array( 296 'rule' => '$', 297 'query' => $rewrite['$'], 298 'matches' => array( '' ), 299 ); 300 } 301 } else { 302 foreach ( (array) $rewrite as $match => $query ) { 303 // If the requested file is the anchor of the match, prepend it to the path info. 304 if ( ! empty( $this->requested_file ) && strpos( $match, $this->requested_file ) === 0 && $this->requested_file != $this->request ) { 305 $request_match = $this->requested_file . '/' . $this->request; 306 } 307 308 if ( preg_match( "#^$match#", $request_match, $matches ) || 309 preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { 310 311 if ( $this->wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 312 // This is a verbose page match, let's check to be sure about it. 313 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 314 if ( ! $page ) { 315 continue; 316 } 317 318 $post_status_obj = get_post_status_object( $page->post_status ); 319 if ( ! $post_status_obj->public && ! $post_status_obj->protected 320 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { 321 continue; 322 } 323 } 324 325 // Got a match. 326 $this->all_matched_rules[] = array( 327 'rule' => $match, 328 'query' => $query, 329 'matches' => $matches, 330 ); 331 } 332 } 333 } 334 335 $this->current_rule = 0; // set first matched rule index 336 } 337 338 /** 339 * match_single_rule 340 * 341 * @internal Do not use this directly. Use $this->parse_request(). 342 * 343 * @since x.x.x 344 */ 345 public function _match_single_rule(){ 346 // we set matched rule now 347 if ( ! empty ($this->all_matched_rules ) ){ 348 $current_match = $this->all_matched_rules[$this->current_rule]; 349 $this->matched_rule = $current_match['rule']; 350 $query = $current_match['query']; 351 $matches = $current_match['matches']; 352 } 353 354 // If we match a rewrite rule, this will be cleared. 355 $this->error = '404'; 356 $this->did_permalink = true; 357 358 359 if ( isset( $this->matched_rule ) ) { 360 // Trim the query of everything up to the '?'. 361 $query = preg_replace( '!^.+\?!', '', $query ); 362 363 // Substitute the substring matches into the query. 364 $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) ); 365 366 $this->matched_query = $query; 367 368 // Parse the query. 369 parse_str( $query, $this->perma_query_vars ); 370 // If we're processing a 404 request, clear the error var since we found something. 371 if ( '404' == $this->error ) { 372 $this->error = null; 373 } 374 } 375 376 // If req_uri is empty or if it is a request for ourself, unset error. 377 if ( empty( $this->request ) || $this->requested_file == $this->self || strpos( $this->server['PHP_SELF'], 'wp-admin/' ) !== false ) { 378 $this->error = null; 379 380 if ( isset( $this->perma_query_vars ) && strpos( $this->server['PHP_SELF'], 'wp-admin/' ) !== false ) { 381 unset( $this->perma_query_vars ); 382 } 383 384 $this->did_permalink = false; 385 } 386 } 387 388 389 /** 390 * Does the actual request parsing after rule was matched and query vars set 391 * 392 * @internal Do not use this directly. Use $this->parse_request(). 393 * 394 * @since x.x.x 395 */ 396 public function _parse_request( $extra_query_vars = '' ) { 397 398 $this->query_vars = array(); 399 400 /** 401 * Filters the query variables whitelist before processing. 402 * 403 * Allows (publicly allowed) query vars to be added, removed, or changed prior 404 * to executing the query. Needed to allow custom rewrite rules using your own arguments 405 * to work, or any other custom query variables you want to be publicly available. 406 * 407 * @since 1.5.0 408 * 409 * @param string[] $public_query_vars The array of whitelisted query variable names. 410 */ 411 $this->public_query_vars = apply_filters( 'query_vars', $this->public_query_vars ); 412 413 $post_type_query_vars = array(); 414 415 if ( is_array( $extra_query_vars ) ) { 416 $this->extra_query_vars = & $extra_query_vars; 417 } elseif ( ! empty( $extra_query_vars ) ) { 418 parse_str( $extra_query_vars, $this->extra_query_vars ); 419 } 420 421 foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ) { 422 if ( is_post_type_viewable( $t ) && $t->query_var ) { 423 $post_type_query_vars[ $t->query_var ] = $post_type; 424 } 425 } 426 foreach ( $this->public_query_vars as $wpvar ) { 427 if ( isset( $this->extra_query_vars[ $wpvar ] ) ) { 428 $this->query_vars[ $wpvar ] = $this->extra_query_vars[ $wpvar ]; 429 } elseif ( isset( $this->get[ $wpvar ] ) && isset( $this->post[ $wpvar ] ) && $this->get[ $wpvar ] !== $this->post[ $wpvar ] ) { 430 wp_die( __( 'A variable mismatch has been detected.' ), __( 'Sorry, you are not allowed to view this item.' ), 400 ); 431 } elseif ( isset( $this->post[ $wpvar ] ) ) { 432 $this->query_vars[ $wpvar ] = $this->post[ $wpvar ]; 433 } elseif ( isset( $this->get[ $wpvar ] ) ) { 434 // if we've cleared error - skip 435 if ( 'error' == $wpvar && null == $this->error ){ 436 continue; 437 } 438 $this->query_vars[ $wpvar ] = $this->get[ $wpvar ]; 439 } elseif ( isset( $this->perma_query_vars[ $wpvar ] ) ) { 440 $this->query_vars[ $wpvar ] = $this->perma_query_vars[ $wpvar ]; 441 } 442 443 if ( ! empty( $this->query_vars[ $wpvar ] ) ) { 444 if ( ! is_array( $this->query_vars[ $wpvar ] ) ) { 445 $this->query_vars[ $wpvar ] = (string) $this->query_vars[ $wpvar ]; 446 } else { 447 foreach ( $this->query_vars[ $wpvar ] as $vkey => $v ) { 448 if ( is_scalar( $v ) ) { 449 $this->query_vars[ $wpvar ][ $vkey ] = (string) $v; 450 } 451 } 452 } 453 454 if ( isset( $post_type_query_vars[ $wpvar ] ) ) { 455 $this->query_vars['post_type'] = $post_type_query_vars[ $wpvar ]; 456 $this->query_vars['name'] = $this->query_vars[ $wpvar ]; 457 } 458 } 459 } 460 461 // Convert urldecoded spaces back into '+'. 462 foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) { 463 if ( $t->query_var && isset( $this->query_vars[ $t->query_var ] ) ) { 464 $this->query_vars[ $t->query_var ] = str_replace( ' ', '+', $this->query_vars[ $t->query_var ] ); 465 } 466 } 467 468 // Don't allow non-publicly queryable taxonomies to be queried from the front end. 469 if ( ! is_admin() ) { 470 foreach ( get_taxonomies( array( 'publicly_queryable' => false ), 'objects' ) as $taxonomy => $t ) { 471 /* 472 * Disallow when set to the 'taxonomy' query var. 473 * Non-publicly queryable taxonomies cannot register custom query vars. See register_taxonomy(). 474 */ 475 if ( isset( $this->query_vars['taxonomy'] ) && $taxonomy === $this->query_vars['taxonomy'] ) { 476 unset( $this->query_vars['taxonomy'], $this->query_vars['term'] ); 477 } 478 } 479 } 480 481 // Limit publicly queried post_types to those that are 'publicly_queryable'. 482 if ( isset( $this->query_vars['post_type'] ) ) { 483 $queryable_post_types = get_post_types( array( 'publicly_queryable' => true ) ); 484 if ( ! is_array( $this->query_vars['post_type'] ) ) { 485 if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types ) ) { 486 unset( $this->query_vars['post_type'] ); 487 } 488 } else { 489 $this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types ); 490 } 491 } 492 493 // Resolve conflicts between posts with numeric slugs and date archive queries. 494 $this->query_vars = wp_resolve_numeric_slug_conflicts( $this->query_vars ); 495 496 foreach ( (array) $this->private_query_vars as $var ) { 497 if ( isset( $this->extra_query_vars[ $var ] ) ) { 498 $this->query_vars[ $var ] = $this->extra_query_vars[ $var ]; 499 } 500 } 501 502 if ( ! empty( $this->error ) ) { 503 $this->query_vars['error'] = $this->error; 504 } 505 506 /** 507 * Filters the array of parsed query variables. 508 * 509 * @since 2.1.0 510 * 511 * @param array $query_vars The array of requested query variables. 512 */ 513 $this->query_vars = apply_filters( 'request', $this->query_vars ); 514 515 /** 516 * Fires once all query variables for the current request have been parsed. 517 * 518 * @since 2.1.0 519 * 520 * @param WP $this Current WordPress environment instance (passed by reference). 521 */ 522 do_action_ref_array( 'parse_request', array( &$this ) ); 523 } 524 525 526 /** 527 * Reset WP_Query object 528 * Used on _reparse_request() 529 * 530 * @since x.x.x 531 */ 532 public function _reset_query(){ 533 $this->wp_query = new WP_Query(); 534 } 535 536 537 /** 538 * Reparse request 539 * 540 * If we're attempting multiple rule matching we need to re-parse query 541 * Advances current_rule index 542 * Sets up a new WP_Query instance. 543 * Parses request _AND_ queries posts. 544 * 545 * @internal Do not use this directly. Use $this->main(). 546 * 547 * @since x.x.x 548 */ 549 public function _reparse_request(){ 550 551 // if our query returned non-empty (200) 552 // or if we've no more rules to match (404) - we return early 553 if ( $this->wp_query->post_count != 0 || $this->current_rule >= count( $this->all_matched_rules )){ 554 return; 555 } 556 557 // advance counter and create new query 558 $this->current_rule ++; 559 $this->_reset_query(); 560 561 $this->_match_single_rule(); 562 $this->_parse_request(); // no need to pass extra query args - they're already in $this->extra_query_vars 563 $this->query_posts(); 564 565 // recursive call 566 $this->_reparse_request(); 567 } 568 569 /** 570 * Sets the query string property based off of the query variable property. 571 * 572 * The {@see 'query_string'} filter is deprecated, but still works. Plugins should 573 * use the {@see 'request'} filter instead. 574 * 575 * @since 2.0.0 576 */ 577 public function build_query_string() { 578 $this->query_string = ''; 579 foreach ( (array) array_keys( $this->query_vars ) as $wpvar ) { 580 if ( '' != $this->query_vars[ $wpvar ] ) { 581 $this->query_string .= ( strlen( $this->query_string ) < 1 ) ? '' : '&'; 582 if ( ! is_scalar( $this->query_vars[ $wpvar ] ) ) { // Discard non-scalars. 583 continue; 584 } 585 $this->query_string .= $wpvar . '=' . rawurlencode( $this->query_vars[ $wpvar ] ); 586 } 587 } 588 589 if ( has_filter( 'query_string' ) ) { // Don't bother filtering and parsing if no plugins are hooked in. 590 /** 591 * Filters the query string before parsing. 592 * 593 * @since 1.5.0 594 * @deprecated 2.1.0 Use {@see 'query_vars'} or {@see 'request'} filters instead. 595 * 596 * @param string $query_string The query string to modify. 597 */ 598 $this->query_string = apply_filters_deprecated( 599 'query_string', 600 array( $this->query_string ), 601 '2.1.0', 602 'query_vars, request' 603 ); 604 parse_str( $this->query_string, $this->query_vars ); 605 } 606 } 607 608 /** 609 * Set up the Loop based on the query variables. 610 * 611 * @since 2.0.0 612 * 613 * @global WP_Query $wp_the_query WordPress Query object. 614 */ 615 public function query_posts() { 616 $this->build_query_string(); 617 $this->wp_query->query( $this->query_vars ); 618 } 619 620 /** 621 * Sets up all of the variables required by the WordPress environment. 622 * 623 * The action {@see 'wp'} has one parameter that references the WP object. It 624 * allows for accessing the properties and methods to further manipulate the 625 * object. 626 * 627 * @since 2.0.0 628 * 629 * @param string|array $query_args Passed to parse_request(). 630 */ 631 public function main( $query_args = '' ) { 632 633 /** 634 * Filters wether to parse multiple rules if first match results in 404 635 * Default: false - Only match the first rule. 636 * 637 * @since x.x.x 638 */ 639 $this->parse_multiple_rules = apply_filters( 'parse_multiple_rules', false ); 640 641 $this->parse_request( $query_args ); 642 $this->query_posts(); 643 644 if ( $this->parse_multiple_rules ){ 645 $this->_reparse_request(); 646 } 647 648 } 649 } 650 No newline at end of file -
wp-includes/class-wp.php
diff --git a/wp-includes/class-wp.php b/wp-includes/class-wp.php index ba1f15d033..a3c1123835 100644
a b 5 5 * @package WordPress 6 6 * @since 2.0.0 7 7 */ 8 class WP { 9 /** 10 * Public query variables. 11 * 12 * Long list of public query variables. 13 * 14 * @since 2.0.0 15 * @var string[] 16 */ 17 public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'favicon', 'taxonomy', 'term', 'cpage', 'post_type', 'embed' ); 18 19 /** 20 * Private query variables. 21 * 22 * Long list of private query variables. 23 * 24 * @since 2.0.0 25 * @var string[] 26 */ 27 public $private_query_vars = array( 'offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in', 'post_parent', 'post_parent__in', 'post_parent__not_in', 'title', 'fields' ); 28 29 /** 30 * Extra query variables set by the user. 31 * 32 * @since 2.1.0 33 * @var array 34 */ 35 public $extra_query_vars = array(); 36 37 /** 38 * Query variables for setting up the WordPress Query Loop. 39 * 40 * @since 2.0.0 41 * @var array 42 */ 43 public $query_vars; 44 45 /** 46 * String parsed to set the query variables. 47 * 48 * @since 2.0.0 49 * @var string 50 */ 51 public $query_string; 52 53 /** 54 * The request path, e.g. 2015/05/06. 55 * 56 * @since 2.0.0 57 * @var string 58 */ 59 public $request; 60 61 /** 62 * Rewrite rule the request matched. 63 * 64 * @since 2.0.0 65 * @var string 66 */ 67 public $matched_rule; 68 69 /** 70 * Rewrite query the request matched. 71 * 72 * @since 2.0.0 73 * @var string 74 */ 75 public $matched_query; 76 77 /** 78 * Whether already did the permalink. 79 * 80 * @since 2.0.0 81 * @var bool 82 */ 83 public $did_permalink = false; 84 85 /** 86 * Add name to list of public query variables. 87 * 88 * @since 2.1.0 89 * 90 * @param string $qv Query variable name. 91 */ 92 public function add_query_var( $qv ) { 93 if ( ! in_array( $qv, $this->public_query_vars, true ) ) { 94 $this->public_query_vars[] = $qv; 95 } 96 } 97 98 /** 99 * Removes a query variable from a list of public query variables. 100 * 101 * @since 4.5.0 102 * 103 * @param string $name Query variable name. 104 */ 105 public function remove_query_var( $name ) { 106 $this->public_query_vars = array_diff( $this->public_query_vars, array( $name ) ); 107 } 108 109 /** 110 * Set the value of a query variable. 111 * 112 * @since 2.3.0 113 * 114 * @param string $key Query variable name. 115 * @param mixed $value Query variable value. 116 */ 117 public function set_query_var( $key, $value ) { 118 $this->query_vars[ $key ] = $value; 119 } 120 121 /** 122 * Parse request to find correct WordPress query. 123 * 124 * Sets up the query variables based on the request. There are also many 125 * filters and actions that can be used to further manipulate the result. 126 * 127 * @since 2.0.0 128 * 129 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 130 * 131 * @param array|string $extra_query_vars Set the extra query variables. 132 */ 133 public function parse_request( $extra_query_vars = '' ) { 134 global $wp_rewrite; 135 136 /** 137 * Filters whether to parse the request. 138 * 139 * @since 3.5.0 140 * 141 * @param bool $bool Whether or not to parse the request. Default true. 142 * @param WP $this Current WordPress environment instance. 143 * @param array|string $extra_query_vars Extra passed query variables. 144 */ 145 if ( ! apply_filters( 'do_parse_request', true, $this, $extra_query_vars ) ) { 146 return; 147 } 148 149 $this->query_vars = array(); 150 $post_type_query_vars = array(); 151 152 if ( is_array( $extra_query_vars ) ) { 153 $this->extra_query_vars = & $extra_query_vars; 154 } elseif ( ! empty( $extra_query_vars ) ) { 155 parse_str( $extra_query_vars, $this->extra_query_vars ); 156 } 157 // Process PATH_INFO, REQUEST_URI, and 404 for permalinks. 158 159 // Fetch the rewrite rules. 160 $rewrite = $wp_rewrite->wp_rewrite_rules(); 161 162 if ( ! empty( $rewrite ) ) { 163 // If we match a rewrite rule, this will be cleared. 164 $error = '404'; 165 $this->did_permalink = true; 166 167 $pathinfo = isset( $_SERVER['PATH_INFO'] ) ? $_SERVER['PATH_INFO'] : ''; 168 list( $pathinfo ) = explode( '?', $pathinfo ); 169 $pathinfo = str_replace( '%', '%25', $pathinfo ); 170 171 list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] ); 172 $self = $_SERVER['PHP_SELF']; 173 $home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' ); 174 $home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) ); 175 176 /* 177 * Trim path info from the end and the leading home path from the front. 178 * For path info requests, this leaves us with the requesting filename, if any. 179 * For 404 requests, this leaves us with the requested permalink. 180 */ 181 $req_uri = str_replace( $pathinfo, '', $req_uri ); 182 $req_uri = trim( $req_uri, '/' ); 183 $req_uri = preg_replace( $home_path_regex, '', $req_uri ); 184 $req_uri = trim( $req_uri, '/' ); 185 $pathinfo = trim( $pathinfo, '/' ); 186 $pathinfo = preg_replace( $home_path_regex, '', $pathinfo ); 187 $pathinfo = trim( $pathinfo, '/' ); 188 $self = trim( $self, '/' ); 189 $self = preg_replace( $home_path_regex, '', $self ); 190 $self = trim( $self, '/' ); 191 192 // The requested permalink is in $pathinfo for path info requests and 193 // $req_uri for other requests. 194 if ( ! empty( $pathinfo ) && ! preg_match( '|^.*' . $wp_rewrite->index . '$|', $pathinfo ) ) { 195 $requested_path = $pathinfo; 196 } else { 197 // If the request uri is the index, blank it out so that we don't try to match it against a rule. 198 if ( $req_uri == $wp_rewrite->index ) { 199 $req_uri = ''; 200 } 201 $requested_path = $req_uri; 202 } 203 $requested_file = $req_uri; 204 205 $this->request = $requested_path; 206 207 // Look for matches. 208 $request_match = $requested_path; 209 if ( empty( $request_match ) ) { 210 // An empty request could only match against ^$ regex. 211 if ( isset( $rewrite['$'] ) ) { 212 $this->matched_rule = '$'; 213 $query = $rewrite['$']; 214 $matches = array( '' ); 215 } 216 } else { 217 foreach ( (array) $rewrite as $match => $query ) { 218 // If the requested file is the anchor of the match, prepend it to the path info. 219 if ( ! empty( $requested_file ) && strpos( $match, $requested_file ) === 0 && $requested_file != $requested_path ) { 220 $request_match = $requested_file . '/' . $requested_path; 221 } 222 223 if ( preg_match( "#^$match#", $request_match, $matches ) || 224 preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { 225 226 if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 227 // This is a verbose page match, let's check to be sure about it. 228 $page = get_page_by_path( $matches[ $varmatch[1] ] ); 229 if ( ! $page ) { 230 continue; 231 } 232 233 $post_status_obj = get_post_status_object( $page->post_status ); 234 if ( ! $post_status_obj->public && ! $post_status_obj->protected 235 && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { 236 continue; 237 } 238 } 239 240 // Got a match. 241 $this->matched_rule = $match; 242 break; 243 } 244 } 245 } 246 247 if ( isset( $this->matched_rule ) ) { 248 // Trim the query of everything up to the '?'. 249 $query = preg_replace( '!^.+\?!', '', $query ); 250 251 // Substitute the substring matches into the query. 252 $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) ); 253 254 $this->matched_query = $query; 255 256 // Parse the query. 257 parse_str( $query, $perma_query_vars ); 258 259 // If we're processing a 404 request, clear the error var since we found something. 260 if ( '404' == $error ) { 261 unset( $error, $_GET['error'] ); 262 } 263 } 264 265 // If req_uri is empty or if it is a request for ourself, unset error. 266 if ( empty( $requested_path ) || $requested_file == $self || strpos( $_SERVER['PHP_SELF'], 'wp-admin/' ) !== false ) { 267 unset( $error, $_GET['error'] ); 268 269 if ( isset( $perma_query_vars ) && strpos( $_SERVER['PHP_SELF'], 'wp-admin/' ) !== false ) { 270 unset( $perma_query_vars ); 271 } 272 273 $this->did_permalink = false; 274 } 275 } 276 277 /** 278 * Filters the query variables whitelist before processing. 279 * 280 * Allows (publicly allowed) query vars to be added, removed, or changed prior 281 * to executing the query. Needed to allow custom rewrite rules using your own arguments 282 * to work, or any other custom query variables you want to be publicly available. 283 * 284 * @since 1.5.0 285 * 286 * @param string[] $public_query_vars The array of whitelisted query variable names. 287 */ 288 $this->public_query_vars = apply_filters( 'query_vars', $this->public_query_vars ); 289 290 foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ) { 291 if ( is_post_type_viewable( $t ) && $t->query_var ) { 292 $post_type_query_vars[ $t->query_var ] = $post_type; 293 } 294 } 295 296 foreach ( $this->public_query_vars as $wpvar ) { 297 if ( isset( $this->extra_query_vars[ $wpvar ] ) ) { 298 $this->query_vars[ $wpvar ] = $this->extra_query_vars[ $wpvar ]; 299 } elseif ( isset( $_GET[ $wpvar ] ) && isset( $_POST[ $wpvar ] ) && $_GET[ $wpvar ] !== $_POST[ $wpvar ] ) { 300 wp_die( __( 'A variable mismatch has been detected.' ), __( 'Sorry, you are not allowed to view this item.' ), 400 ); 301 } elseif ( isset( $_POST[ $wpvar ] ) ) { 302 $this->query_vars[ $wpvar ] = $_POST[ $wpvar ]; 303 } elseif ( isset( $_GET[ $wpvar ] ) ) { 304 $this->query_vars[ $wpvar ] = $_GET[ $wpvar ]; 305 } elseif ( isset( $perma_query_vars[ $wpvar ] ) ) { 306 $this->query_vars[ $wpvar ] = $perma_query_vars[ $wpvar ]; 307 } 308 309 if ( ! empty( $this->query_vars[ $wpvar ] ) ) { 310 if ( ! is_array( $this->query_vars[ $wpvar ] ) ) { 311 $this->query_vars[ $wpvar ] = (string) $this->query_vars[ $wpvar ]; 312 } else { 313 foreach ( $this->query_vars[ $wpvar ] as $vkey => $v ) { 314 if ( is_scalar( $v ) ) { 315 $this->query_vars[ $wpvar ][ $vkey ] = (string) $v; 316 } 317 } 318 } 319 320 if ( isset( $post_type_query_vars[ $wpvar ] ) ) { 321 $this->query_vars['post_type'] = $post_type_query_vars[ $wpvar ]; 322 $this->query_vars['name'] = $this->query_vars[ $wpvar ]; 323 } 324 } 325 } 326 327 // Convert urldecoded spaces back into '+'. 328 foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) { 329 if ( $t->query_var && isset( $this->query_vars[ $t->query_var ] ) ) { 330 $this->query_vars[ $t->query_var ] = str_replace( ' ', '+', $this->query_vars[ $t->query_var ] ); 331 } 332 } 333 334 // Don't allow non-publicly queryable taxonomies to be queried from the front end. 335 if ( ! is_admin() ) { 336 foreach ( get_taxonomies( array( 'publicly_queryable' => false ), 'objects' ) as $taxonomy => $t ) { 337 /* 338 * Disallow when set to the 'taxonomy' query var. 339 * Non-publicly queryable taxonomies cannot register custom query vars. See register_taxonomy(). 340 */ 341 if ( isset( $this->query_vars['taxonomy'] ) && $taxonomy === $this->query_vars['taxonomy'] ) { 342 unset( $this->query_vars['taxonomy'], $this->query_vars['term'] ); 343 } 344 } 345 } 346 347 // Limit publicly queried post_types to those that are 'publicly_queryable'. 348 if ( isset( $this->query_vars['post_type'] ) ) { 349 $queryable_post_types = get_post_types( array( 'publicly_queryable' => true ) ); 350 if ( ! is_array( $this->query_vars['post_type'] ) ) { 351 if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types, true ) ) { 352 unset( $this->query_vars['post_type'] ); 353 } 354 } else { 355 $this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types ); 356 } 357 } 358 359 // Resolve conflicts between posts with numeric slugs and date archive queries. 360 $this->query_vars = wp_resolve_numeric_slug_conflicts( $this->query_vars ); 361 362 foreach ( (array) $this->private_query_vars as $var ) { 363 if ( isset( $this->extra_query_vars[ $var ] ) ) { 364 $this->query_vars[ $var ] = $this->extra_query_vars[ $var ]; 365 } 366 } 367 368 if ( isset( $error ) ) { 369 $this->query_vars['error'] = $error; 370 } 371 372 /** 373 * Filters the array of parsed query variables. 374 * 375 * @since 2.1.0 376 * 377 * @param array $query_vars The array of requested query variables. 378 */ 379 $this->query_vars = apply_filters( 'request', $this->query_vars ); 380 381 /** 382 * Fires once all query variables for the current request have been parsed. 383 * 384 * @since 2.1.0 385 * 386 * @param WP $this Current WordPress environment instance (passed by reference). 387 */ 388 do_action_ref_array( 'parse_request', array( &$this ) ); 389 } 8 class WP extends WP_Request_Environment{ 9 390 10 391 11 /** 392 12 * Sends additional HTTP headers for caching, content type, etc. … … class WP { 454 74 $headers['ETag'] = $wp_etag; 455 75 456 76 // Support for conditional GET. 457 if ( isset( $ _SERVER['HTTP_IF_NONE_MATCH'] ) ) {458 $client_etag = wp_unslash( $ _SERVER['HTTP_IF_NONE_MATCH'] );77 if ( isset( $this->server['HTTP_IF_NONE_MATCH'] ) ) { 78 $client_etag = wp_unslash( $this->server['HTTP_IF_NONE_MATCH'] ); 459 79 } else { 460 80 $client_etag = false; 461 81 } 462 82 463 $client_last_modified = empty( $ _SERVER['HTTP_IF_MODIFIED_SINCE'] ) ? '' : trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );83 $client_last_modified = empty( $this->server['HTTP_IF_MODIFIED_SINCE'] ) ? '' : trim( $this->server['HTTP_IF_MODIFIED_SINCE'] ); 464 84 // If string is empty, return 0. If not, attempt to parse into a timestamp. 465 85 $client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0; 466 86 … … class WP { 519 139 } 520 140 521 141 /** 522 * Sets the query string property based off of the query variable property. 523 * 524 * The {@see 'query_string'} filter is deprecated, but still works. Plugins should 525 * use the {@see 'request'} filter instead. 526 * 527 * @since 2.0.0 142 * Reset WP_Query object 143 * Used on _reparse_request() 144 * Reset global $wp_query if necessary 145 * 146 * note: some plugins use pre_handle_404 incorrectly. 147 * They don't used passed $wp_query parameter. Instead they modify global $wp_query directly. 148 * So class WP must update global $wp_query every time. 149 * 150 * @since x.x.x 528 151 */ 529 public function build_query_string() { 530 $this->query_string = ''; 531 foreach ( (array) array_keys( $this->query_vars ) as $wpvar ) { 532 if ( '' != $this->query_vars[ $wpvar ] ) { 533 $this->query_string .= ( strlen( $this->query_string ) < 1 ) ? '' : '&'; 534 if ( ! is_scalar( $this->query_vars[ $wpvar ] ) ) { // Discard non-scalars. 535 continue; 536 } 537 $this->query_string .= $wpvar . '=' . rawurlencode( $this->query_vars[ $wpvar ] ); 538 } 539 } 152 public function _reset_query(){ 153 global $wp_query; 154 global $wp_the_query; 155 156 parent::_reset_query(); 540 157 541 if ( has_filter( 'query_string' ) ) { // Don't bother filtering and parsing if no plugins are hooked in. 542 /** 543 * Filters the query string before parsing. 544 * 545 * @since 1.5.0 546 * @deprecated 2.1.0 Use {@see 'query_vars'} or {@see 'request'} filters instead. 547 * 548 * @param string $query_string The query string to modify. 549 */ 550 $this->query_string = apply_filters_deprecated( 551 'query_string', 552 array( $this->query_string ), 553 '2.1.0', 554 'query_vars, request' 555 ); 556 parse_str( $this->query_string, $this->query_vars ); 158 // if we've created new WP_Query object - let's insert it back into globals 159 // The following condition will only execute if parse_multiple_rules == true and first matched rule has failed 160 if ($wp_query !== $this->wp_query){ 161 $wp_query = $this->wp_query; 162 $wp_the_query = $wp_query; 557 163 } 558 164 } 559 165 … … class WP { 578 184 public function register_globals() { 579 185 global $wp_query; 580 186 187 // moved here from _parse_request() 188 if ( null == $this->error ){ 189 unset( $_GET['error'] ); 190 } 191 581 192 // Extract updated query vars back into global namespace. 582 193 foreach ( (array) $wp_query->query_vars as $key => $value ) { 583 194 $GLOBALS[ $key ] = $value; … … class WP { 607 218 wp_get_current_user(); 608 219 } 609 220 610 /**611 * Set up the Loop based on the query variables.612 *613 * @since 2.0.0614 *615 * @global WP_Query $wp_the_query WordPress Query object.616 */617 public function query_posts() {618 global $wp_the_query;619 $this->build_query_string();620 $wp_the_query->query( $this->query_vars );621 }622 623 221 /** 624 222 * Set the Headers for 404, if nothing is found for requested URL. 625 223 * … … class WP { 737 335 * @param string|array $query_args Passed to parse_request(). 738 336 */ 739 337 public function main( $query_args = '' ) { 338 global $wp_the_query; 339 global $wp_rewrite; 340 740 341 $this->init(); 741 $this->parse_request( $query_args ); 742 $this->send_headers(); 743 $this->query_posts(); 342 343 $this->setup_request_environment( $_SERVER, $_GET, $_POST, $wp_the_query, $wp_rewrite ); 344 345 parent::main(); 346 744 347 $this->handle_404(); 348 349 $this->send_headers(); 350 745 351 $this->register_globals(); 746 352 747 353 /** -
wp-settings.php
diff --git a/wp-settings.php b/wp-settings.php index 1a5f296733..125e095545 100644
a b require ABSPATH . WPINC . '/meta.php'; 111 111 require ABSPATH . WPINC . '/functions.php'; 112 112 require ABSPATH . WPINC . '/class-wp-meta-query.php'; 113 113 require ABSPATH . WPINC . '/class-wp-matchesmapregex.php'; 114 require ABSPATH . WPINC . '/class-wp-request-environment.php'; 114 115 require ABSPATH . WPINC . '/class-wp.php'; 115 116 require ABSPATH . WPINC . '/class-wp-error.php'; 116 117 require ABSPATH . WPINC . '/pomo/mo.php';