run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄class-wp.php
1<?php
2/**
3 * WordPress environment setup class.
4 *
5 * @package WordPress
6 * @since 2.0.0
7 */
8#[AllowDynamicProperties]
9class WP {
10 /**
11 * Public query variables.
12 *
13 * Long list of public query variables.
14 *
15 * @since 2.0.0
16 * @var string[]
17 */
18 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' );
19
20 /**
21 * Private query variables.
22 *
23 * Long list of private query variables.
24 *
25 * @since 2.0.0
26 * @var string[]
27 */
28 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' );
29
30 /**
31 * Extra query variables set by the user.
32 *
33 * @since 2.1.0
34 * @var array
35 */
36 public $extra_query_vars = array();
37
38 /**
39 * Query variables for setting up the WordPress Query Loop.
40 *
41 * @since 2.0.0
42 * @var array
43 */
44 public $query_vars = array();
45
46 /**
47 * String parsed to set the query variables.
48 *
49 * @since 2.0.0
50 * @var string
51 */
52 public $query_string = '';
53
54 /**
55 * The request path, e.g. 2015/05/06.
56 *
57 * @since 2.0.0
58 * @var string
59 */
60 public $request = '';
61
62 /**
63 * Rewrite rule the request matched.
64 *
65 * @since 2.0.0
66 * @var string
67 */
68 public $matched_rule = '';
69
70 /**
71 * Rewrite query the request matched.
72 *
73 * @since 2.0.0
74 * @var string
75 */
76 public $matched_query = '';
77
78 /**
79 * Whether already did the permalink.
80 *
81 * @since 2.0.0
82 * @var bool
83 */
84 public $did_permalink = false;
85
86 /**
87 * Adds a query variable to the list of public query variables.
88 *
89 * @since 2.1.0
90 *
91 * @param string $qv Query variable name.
92 */
93 public function add_query_var( $qv ) {
94 if ( ! in_array( $qv, $this->public_query_vars, true ) ) {
95 $this->public_query_vars[] = $qv;
96 }
97 }
98
99 /**
100 * Removes a query variable from a list of public query variables.
101 *
102 * @since 4.5.0
103 *
104 * @param string $name Query variable name.
105 */
106 public function remove_query_var( $name ) {
107 $this->public_query_vars = array_diff( $this->public_query_vars, array( $name ) );
108 }
109
110 /**
111 * Sets the value of a query variable.
112 *
113 * @since 2.3.0
114 *
115 * @param string $key Query variable name.
116 * @param mixed $value Query variable value.
117 */
118 public function set_query_var( $key, $value ) {
119 $this->query_vars[ $key ] = $value;
120 }
121
122 /**
123 * Parses the request to find the correct WordPress query.
124 *
125 * Sets up the query variables based on the request. There are also many
126 * filters and actions that can be used to further manipulate the result.
127 *
128 * @since 2.0.0
129 * @since 6.0.0 A return value was added.
130 *
131 * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
132 *
133 * @param array|string $extra_query_vars Set the extra query variables.
134 * @return bool Whether the request was parsed.
135 */
136 public function parse_request( $extra_query_vars = '' ) {
137 global $wp_rewrite;
138
139 /**
140 * Filters whether to parse the request.
141 *
142 * @since 3.5.0
143 *
144 * @param bool $bool Whether or not to parse the request. Default true.
145 * @param WP $wp Current WordPress environment instance.
146 * @param array|string $extra_query_vars Extra passed query variables.
147 */
148 if ( ! apply_filters( 'do_parse_request', true, $this, $extra_query_vars ) ) {
149 return false;
150 }
151
152 $this->query_vars = array();
153 $post_type_query_vars = array();
154
155 if ( is_array( $extra_query_vars ) ) {
156 $this->extra_query_vars = & $extra_query_vars;
157 } elseif ( ! empty( $extra_query_vars ) ) {
158 parse_str( $extra_query_vars, $this->extra_query_vars );
159 }
160 // Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
161
162 // Fetch the rewrite rules.
163 $rewrite = $wp_rewrite->wp_rewrite_rules();
164
165 if ( ! empty( $rewrite ) ) {
166 // If we match a rewrite rule, this will be cleared.
167 $error = '404';
168 $this->did_permalink = true;
169
170 $pathinfo = isset( $_SERVER['PATH_INFO'] ) ? $_SERVER['PATH_INFO'] : '';
171 list( $pathinfo ) = explode( '?', $pathinfo );
172 $pathinfo = str_replace( '%', '%25', $pathinfo );
173
174 list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] );
175 $self = $_SERVER['PHP_SELF'];
176
177 $home_path = parse_url( home_url(), PHP_URL_PATH );
178 $home_path_regex = '';
179 if ( is_string( $home_path ) && '' !== $home_path ) {
180 $home_path = trim( $home_path, '/' );
181 $home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) );
182 }
183
184 /*
185 * Trim path info from the end and the leading home path from the front.
186 * For path info requests, this leaves us with the requesting filename, if any.
187 * For 404 requests, this leaves us with the requested permalink.
188 */
189 $req_uri = str_replace( $pathinfo, '', $req_uri );
190 $req_uri = trim( $req_uri, '/' );
191 $pathinfo = trim( $pathinfo, '/' );
192 $self = trim( $self, '/' );
193
194 if ( ! empty( $home_path_regex ) ) {
195 $req_uri = preg_replace( $home_path_regex, '', $req_uri );
196 $req_uri = trim( $req_uri, '/' );
197 $pathinfo = preg_replace( $home_path_regex, '', $pathinfo );
198 $pathinfo = trim( $pathinfo, '/' );
199 $self = preg_replace( $home_path_regex, '', $self );
200 $self = trim( $self, '/' );
201 }
202
203 // The requested permalink is in $pathinfo for path info requests and $req_uri for other requests.
204 if ( ! empty( $pathinfo ) && ! preg_match( '|^.*' . $wp_rewrite->index . '$|', $pathinfo ) ) {
205 $requested_path = $pathinfo;
206 } else {
207 // If the request uri is the index, blank it out so that we don't try to match it against a rule.
208 if ( $req_uri === $wp_rewrite->index ) {
209 $req_uri = '';
210 }
211
212 $requested_path = $req_uri;
213 }
214
215 $requested_file = $req_uri;
216
217 $this->request = $requested_path;
218
219 // Look for matches.
220 $request_match = $requested_path;
221 if ( empty( $request_match ) ) {
222 // An empty request could only match against ^$ regex.
223 if ( isset( $rewrite['$'] ) ) {
224 $this->matched_rule = '$';
225 $query = $rewrite['$'];
226 $matches = array( '' );
227 }
228 } else {
229 foreach ( (array) $rewrite as $match => $query ) {
230 // If the requested file is the anchor of the match, prepend it to the path info.
231 if ( ! empty( $requested_file )
232 && str_starts_with( $match, $requested_file )
233 && $requested_file !== $requested_path
234 ) {
235 $request_match = $requested_file . '/' . $requested_path;
236 }
237
238 if ( preg_match( "#^$match#", $request_match, $matches )
239 || preg_match( "#^$match#", urldecode( $request_match ), $matches )
240 ) {
241
242 if ( $wp_rewrite->use_verbose_page_rules
243 && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch )
244 ) {
245 // This is a verbose page match, let's check to be sure about it.
246 $page = get_page_by_path( $matches[ $varmatch[1] ] );
247
248 if ( ! $page ) {
249 continue;
250 }
251
252 $post_status_obj = get_post_status_object( $page->post_status );
253
254 if ( ! $post_status_obj->public && ! $post_status_obj->protected
255 && ! $post_status_obj->private && $post_status_obj->exclude_from_search
256 ) {
257 continue;
258 }
259 }
260
261 // Got a match.
262 $this->matched_rule = $match;
263 break;
264 }
265 }
266 }
267
268 if ( ! empty( $this->matched_rule ) ) {
269 // Trim the query of everything up to the '?'.
270 $query = preg_replace( '!^.+\?!', '', $query );
271
272 // Substitute the substring matches into the query.
273 $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) );
274
275 $this->matched_query = $query;
276
277 // Parse the query.
278 parse_str( $query, $perma_query_vars );
279
280 // If we're processing a 404 request, clear the error var since we found something.
281 if ( '404' === $error ) {
282 unset( $error, $_GET['error'] );
283 }
284 }
285
286 // If req_uri is empty or if it is a request for ourself, unset error.
287 if ( empty( $requested_path ) || $requested_file === $self
288 || str_contains( $_SERVER['PHP_SELF'], 'wp-admin/' )
289 ) {
290 unset( $error, $_GET['error'] );
291
292 if ( isset( $perma_query_vars ) && str_contains( $_SERVER['PHP_SELF'], 'wp-admin/' ) ) {
293 unset( $perma_query_vars );
294 }
295
296 $this->did_permalink = false;
297 }
298 }
299
300 /**
301 * Filters the query variables allowed before processing.
302 *
303 * Allows (publicly allowed) query vars to be added, removed, or changed prior
304 * to executing the query. Needed to allow custom rewrite rules using your own arguments
305 * to work, or any other custom query variables you want to be publicly available.
306 *
307 * @since 1.5.0
308 *
309 * @param string[] $public_query_vars The array of allowed query variable names.
310 */
311 $this->public_query_vars = apply_filters( 'query_vars', $this->public_query_vars );
312
313 foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ) {
314 if ( is_post_type_viewable( $t ) && $t->query_var ) {
315 $post_type_query_vars[ $t->query_var ] = $post_type;
316 }
317 }
318
319 foreach ( $this->public_query_vars as $wpvar ) {
320 if ( isset( $this->extra_query_vars[ $wpvar ] ) ) {
321 $this->query_vars[ $wpvar ] = $this->extra_query_vars[ $wpvar ];
322 } elseif ( isset( $_GET[ $wpvar ] ) && isset( $_POST[ $wpvar ] )
323 && $_GET[ $wpvar ] !== $_POST[ $wpvar ]
324 ) {
325 wp_die(
326 __( 'A variable mismatch has been detected.' ),
327 __( 'Sorry, you are not allowed to view this item.' ),
328 400
329 );
330 } elseif ( isset( $_POST[ $wpvar ] ) ) {
331 $this->query_vars[ $wpvar ] = $_POST[ $wpvar ];
332 } elseif ( isset( $_GET[ $wpvar ] ) ) {
333 $this->query_vars[ $wpvar ] = $_GET[ $wpvar ];
334 } elseif ( isset( $perma_query_vars[ $wpvar ] ) ) {
335 $this->query_vars[ $wpvar ] = $perma_query_vars[ $wpvar ];
336 }
337
338 if ( ! empty( $this->query_vars[ $wpvar ] ) ) {
339 if ( ! is_array( $this->query_vars[ $wpvar ] ) ) {
340 $this->query_vars[ $wpvar ] = (string) $this->query_vars[ $wpvar ];
341 } else {
342 foreach ( $this->query_vars[ $wpvar ] as $vkey => $v ) {
343 if ( is_scalar( $v ) ) {
344 $this->query_vars[ $wpvar ][ $vkey ] = (string) $v;
345 }
346 }
347 }
348
349 if ( isset( $post_type_query_vars[ $wpvar ] ) ) {
350 $this->query_vars['post_type'] = $post_type_query_vars[ $wpvar ];
351 $this->query_vars['name'] = $this->query_vars[ $wpvar ];
352 }
353 }
354 }
355
356 // Convert urldecoded spaces back into '+'.
357 foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) {
358 if ( $t->query_var && isset( $this->query_vars[ $t->query_var ] ) ) {
359 $this->query_vars[ $t->query_var ] = str_replace( ' ', '+', $this->query_vars[ $t->query_var ] );
360 }
361 }
362
363 // Don't allow non-publicly queryable taxonomies to be queried from the front end.
364 if ( ! is_admin() ) {
365 foreach ( get_taxonomies( array( 'publicly_queryable' => false ), 'objects' ) as $taxonomy => $t ) {
366 /*
367 * Disallow when set to the 'taxonomy' query var.
368 * Non-publicly queryable taxonomies cannot register custom query vars. See register_taxonomy().
369 */
370 if ( isset( $this->query_vars['taxonomy'] ) && $taxonomy === $this->query_vars['taxonomy'] ) {
371 unset( $this->query_vars['taxonomy'], $this->query_vars['term'] );
372 }
373 }
374 }
375
376 // Limit publicly queried post_types to those that are 'publicly_queryable'.
377 if ( isset( $this->query_vars['post_type'] ) ) {
378 $queryable_post_types = get_post_types( array( 'publicly_queryable' => true ) );
379
380 if ( ! is_array( $this->query_vars['post_type'] ) ) {
381 if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types, true ) ) {
382 unset( $this->query_vars['post_type'] );
383 }
384 } else {
385 $this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types );
386 }
387 }
388
389 // Resolve conflicts between posts with numeric slugs and date archive queries.
390 $this->query_vars = wp_resolve_numeric_slug_conflicts( $this->query_vars );
391
392 foreach ( (array) $this->private_query_vars as $var ) {
393 if ( isset( $this->extra_query_vars[ $var ] ) ) {
394 $this->query_vars[ $var ] = $this->extra_query_vars[ $var ];
395 }
396 }
397
398 if ( isset( $error ) ) {
399 $this->query_vars['error'] = $error;
400 }
401
402 /**
403 * Filters the array of parsed query variables.
404 *
405 * @since 2.1.0
406 *
407 * @param array $query_vars The array of requested query variables.
408 */
409 $this->query_vars = apply_filters( 'request', $this->query_vars );
410
411 /**
412 * Fires once all query variables for the current request have been parsed.
413 *
414 * @since 2.1.0
415 *
416 * @param WP $wp Current WordPress environment instance (passed by reference).
417 */
418 do_action_ref_array( 'parse_request', array( &$this ) );
419
420 return true;
421 }
422
423 /**
424 * Sends additional HTTP headers for caching, content type, etc.
425 *
426 * Sets the Content-Type header. Sets the 'error' status (if passed) and optionally exits.
427 * If showing a feed, it will also send Last-Modified, ETag, and 304 status if needed.
428 *
429 * @since 2.0.0
430 * @since 4.4.0 `X-Pingback` header is added conditionally for single posts that allow pings.
431 * @since 6.1.0 Runs after posts have been queried.
432 *
433 * @global WP_Query $wp_query WordPress Query object.
434 */
435 public function send_headers() {
436 global $wp_query;
437
438 $headers = array();
439 $status = null;
440 $exit_required = false;
441 $date_format = 'D, d M Y H:i:s';
442
443 if ( is_user_logged_in() ) {
444 $headers = array_merge( $headers, wp_get_nocache_headers() );
445 } elseif ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) {
446 // Unmoderated comments are only visible for 10 minutes via the moderation hash.
447 $expires = 10 * MINUTE_IN_SECONDS;
448
449 $headers['Expires'] = gmdate( $date_format, time() + $expires );
450 $headers['Cache-Control'] = sprintf(
451 'max-age=%d, must-revalidate',
452 $expires
453 );
454 }
455 if ( ! empty( $this->query_vars['error'] ) ) {
456 $status = (int) $this->query_vars['error'];
457
458 if ( 404 === $status ) {
459 if ( ! is_user_logged_in() ) {
460 $headers = array_merge( $headers, wp_get_nocache_headers() );
461 }
462
463 $headers['Content-Type'] = get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' );
464 } elseif ( in_array( $status, array( 403, 500, 502, 503 ), true ) ) {
465 $exit_required = true;
466 }
467 } elseif ( empty( $this->query_vars['feed'] ) ) {
468 $headers['Content-Type'] = get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' );
469 } else {
470 // Set the correct content type for feeds.
471 $type = $this->query_vars['feed'];
472 if ( 'feed' === $this->query_vars['feed'] ) {
473 $type = get_default_feed();
474 }
475
476 $headers['Content-Type'] = feed_content_type( $type ) . '; charset=' . get_option( 'blog_charset' );
477
478 // We're showing a feed, so WP is indeed the only thing that last changed.
479 if ( ! empty( $this->query_vars['withcomments'] )
480 || str_contains( $this->query_vars['feed'], 'comments-' )
481 || ( empty( $this->query_vars['withoutcomments'] )
482 && ( ! empty( $this->query_vars['p'] )
483 || ! empty( $this->query_vars['name'] )
484 || ! empty( $this->query_vars['page_id'] )
485 || ! empty( $this->query_vars['pagename'] )
486 || ! empty( $this->query_vars['attachment'] )
487 || ! empty( $this->query_vars['attachment_id'] )
488 )
489 )
490 ) {
491 $wp_last_modified_post = mysql2date( $date_format, get_lastpostmodified( 'GMT' ), false );
492 $wp_last_modified_comment = mysql2date( $date_format, get_lastcommentmodified( 'GMT' ), false );
493
494 if ( strtotime( $wp_last_modified_post ) > strtotime( $wp_last_modified_comment ) ) {
495 $wp_last_modified = $wp_last_modified_post;
496 } else {
497 $wp_last_modified = $wp_last_modified_comment;
498 }
499 } else {
500 $wp_last_modified = mysql2date( $date_format, get_lastpostmodified( 'GMT' ), false );
501 }
502
503 if ( ! $wp_last_modified ) {
504 $wp_last_modified = gmdate( $date_format );
505 }
506
507 $wp_last_modified .= ' GMT';
508 $wp_etag = '"' . md5( $wp_last_modified ) . '"';
509
510 $headers['Last-Modified'] = $wp_last_modified;
511 $headers['ETag'] = $wp_etag;
512
513 // Support for conditional GET.
514 if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) {
515 $client_etag = wp_unslash( $_SERVER['HTTP_IF_NONE_MATCH'] );
516 } else {
517 $client_etag = '';
518 }
519
520 if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
521 $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
522 } else {
523 $client_last_modified = '';
524 }
525
526 // If string is empty, return 0. If not, attempt to parse into a timestamp.
527 $client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;
528
529 // Make a timestamp for our most recent modification.
530 $wp_modified_timestamp = strtotime( $wp_last_modified );
531
532 if ( ( $client_last_modified && $client_etag )
533 ? ( ( $client_modified_timestamp >= $wp_modified_timestamp ) && ( $client_etag === $wp_etag ) )
534 : ( ( $client_modified_timestamp >= $wp_modified_timestamp ) || ( $client_etag === $wp_etag ) )
535 ) {
536 $status = 304;
537 $exit_required = true;
538 }
539 }
540
541 if ( is_singular() ) {
542 $post = isset( $wp_query->post ) ? $wp_query->post : null;
543
544 // Only set X-Pingback for single posts that allow pings.
545 if ( $post && pings_open( $post ) ) {
546 $headers['X-Pingback'] = get_bloginfo( 'pingback_url', 'display' );
547 }
548
549 // Send nocache headers for password protected posts to avoid unwanted caching.
550 if ( ! empty( $post->post_password ) ) {
551 $headers = array_merge( $headers, wp_get_nocache_headers() );
552 }
553 }
554
555 /**
556 * Filters the HTTP headers before they're sent to the browser.
557 *
558 * @since 2.8.0
559 *
560 * @param string[] $headers Associative array of headers to be sent.
561 * @param WP $wp Current WordPress environment instance.
562 */
563 $headers = apply_filters( 'wp_headers', $headers, $this );
564
565 if ( ! empty( $status ) ) {
566 status_header( $status );
567 }
568
569 // If Last-Modified is set to false, it should not be sent (no-cache situation).
570 if ( isset( $headers['Last-Modified'] ) && false === $headers['Last-Modified'] ) {
571 unset( $headers['Last-Modified'] );
572
573 if ( ! headers_sent() ) {
574 header_remove( 'Last-Modified' );
575 }
576 }
577
578 if ( ! headers_sent() ) {
579 foreach ( (array) $headers as $name => $field_value ) {
580 header( "{$name}: {$field_value}" );
581 }
582 }
583
584 if ( $exit_required ) {
585 exit;
586 }
587
588 /**
589 * Fires once the requested HTTP headers for caching, content type, etc. have been sent.
590 *
591 * The {@see 'wp_finalized_template_enhancement_output_buffer'} action may be used to send
592 * headers after rendering the template into an output buffer.
593 *
594 * @since 2.1.0
595 *
596 * @param WP $wp Current WordPress environment instance (passed by reference).
597 */
598 do_action_ref_array( 'send_headers', array( &$this ) );
599 }
600
601 /**
602 * Sets the query string property based off of the query variable property.
603 *
604 * The {@see 'query_string'} filter is deprecated, but still works. Plugins should
605 * use the {@see 'request'} filter instead.
606 *
607 * @since 2.0.0
608 */
609 public function build_query_string() {
610 $this->query_string = '';
611
612 foreach ( (array) array_keys( $this->query_vars ) as $wpvar ) {
613 if ( '' !== $this->query_vars[ $wpvar ] ) {
614 $this->query_string .= ( strlen( $this->query_string ) < 1 ) ? '' : '&';
615
616 if ( ! is_scalar( $this->query_vars[ $wpvar ] ) ) { // Discard non-scalars.
617 continue;
618 }
619
620 $this->query_string .= $wpvar . '=' . rawurlencode( $this->query_vars[ $wpvar ] );
621 }
622 }
623
624 if ( has_filter( 'query_string' ) ) { // Don't bother filtering and parsing if no plugins are hooked in.
625 /**
626 * Filters the query string before parsing.
627 *
628 * @since 1.5.0
629 * @deprecated 2.1.0 Use {@see 'query_vars'} or {@see 'request'} filters instead.
630 *
631 * @param string $query_string The query string to modify.
632 */
633 $this->query_string = apply_filters_deprecated(
634 'query_string',
635 array( $this->query_string ),
636 '2.1.0',
637 'query_vars, request'
638 );
639
640 parse_str( $this->query_string, $this->query_vars );
641 }
642 }
643
644 /**
645 * Set up the WordPress Globals.
646 *
647 * The query_vars property will be extracted to the GLOBALS. So care should
648 * be taken when naming global variables that might interfere with the
649 * WordPress environment.
650 *
651 * @since 2.0.0
652 *
653 * @global WP_Query $wp_query WordPress Query object.
654 * @global string $query_string Query string for the loop.
655 * @global array $posts The found posts.
656 * @global WP_Post|null $post The current post, if available.
657 * @global string $request The SQL statement for the request.
658 * @global int $more Only set, if single page or post.
659 * @global int $single If single page or post. Only set, if single page or post.
660 * @global WP_User $authordata Only set, if author archive.
661 */
662 public function register_globals() {
663 global $wp_query;
664
665 // Extract updated query vars back into global namespace.
666 foreach ( (array) $wp_query->query_vars as $key => $value ) {
667 $GLOBALS[ $key ] = $value;
668 }
669
670 $GLOBALS['query_string'] = $this->query_string;
671 $GLOBALS['posts'] = & $wp_query->posts;
672 $GLOBALS['post'] = isset( $wp_query->post ) ? $wp_query->post : null;
673 $GLOBALS['request'] = $wp_query->request;
674
675 if ( $wp_query->is_single() || $wp_query->is_page() ) {
676 $GLOBALS['more'] = 1;
677 $GLOBALS['single'] = 1;
678 }
679
680 if ( $wp_query->is_author() ) {
681 $GLOBALS['authordata'] = get_userdata( get_queried_object_id() );
682 }
683 }
684
685 /**
686 * Set up the current user.
687 *
688 * @since 2.0.0
689 */
690 public function init() {
691 wp_get_current_user();
692 }
693
694 /**
695 * Set up the Loop based on the query variables.
696 *
697 * @since 2.0.0
698 *
699 * @global WP_Query $wp_the_query WordPress Query object.
700 */
701 public function query_posts() {
702 global $wp_the_query;
703 $this->build_query_string();
704 $wp_the_query->query( $this->query_vars );
705 }
706
707 /**
708 * Set the Headers for 404, if nothing is found for requested URL.
709 *
710 * Issue a 404 if a request doesn't match any posts and doesn't match any object
711 * (e.g. an existing-but-empty category, tag, author) and a 404 was not already issued,
712 * and if the request was not a search or the homepage.
713 *
714 * Otherwise, issue a 200.
715 *
716 * This sets headers after posts have been queried. handle_404() really means "handle status".
717 * By inspecting the result of querying posts, seemingly successful requests can be switched to
718 * a 404 so that canonical redirection logic can kick in.
719 *
720 * @since 2.0.0
721 *
722 * @global WP_Query $wp_query WordPress Query object.
723 */
724 public function handle_404() {
725 global $wp_query;
726
727 /**
728 * Filters whether to short-circuit default header status handling.
729 *
730 * Returning a non-false value from the filter will short-circuit the handling
731 * and return early.
732 *
733 * @since 4.5.0
734 *
735 * @param bool $preempt Whether to short-circuit default header status handling. Default false.
736 * @param WP_Query $wp_query WordPress Query object.
737 */
738 if ( false !== apply_filters( 'pre_handle_404', false, $wp_query ) ) {
739 return;
740 }
741
742 // If we've already issued a 404, bail.
743 if ( is_404() ) {
744 return;
745 }
746
747 $set_404 = true;
748
749 // Never 404 for the admin, robots, or favicon.
750 if ( is_admin() || is_robots() || is_favicon() ) {
751 $set_404 = false;
752
753 // If posts were found, check for paged content.
754 } elseif ( $wp_query->posts ) {
755 $content_found = true;
756
757 if ( is_singular() ) {
758 $post = isset( $wp_query->post ) ? $wp_query->post : null;
759 $next = '<!--nextpage-->';
760
761 // Check for paged content that exceeds the max number of pages.
762 if ( $post && ! empty( $this->query_vars['page'] ) ) {
763 // Check if content is actually intended to be paged.
764 if ( str_contains( $post->post_content, $next ) ) {
765 $page = trim( $this->query_vars['page'], '/' );
766 $content_found = (int) $page <= ( substr_count( $post->post_content, $next ) + 1 );
767 } else {
768 $content_found = false;
769 }
770 }
771 }
772
773 // The posts page does not support the <!--nextpage--> pagination.
774 if ( $wp_query->is_posts_page && ! empty( $this->query_vars['page'] ) ) {
775 $content_found = false;
776 }
777
778 if ( $content_found ) {
779 $set_404 = false;
780 }
781
782 // We will 404 for paged queries, as no posts were found.
783 } elseif ( ! is_paged() ) {
784 $author = get_query_var( 'author' );
785
786 // Don't 404 for authors without posts as long as they matched an author on this site.
787 if ( is_author() && is_numeric( $author ) && $author > 0 && is_user_member_of_blog( $author )
788 // Don't 404 for these queries if they matched an object.
789 || ( is_tag() || is_category() || is_tax() || is_post_type_archive() ) && get_queried_object()
790 // Don't 404 for these queries either.
791 || is_home() || is_search() || is_feed()
792 ) {
793 $set_404 = false;
794 }
795 }
796
797 if ( $set_404 ) {
798 // Guess it's time to 404.
799 $wp_query->set_404();
800 status_header( 404 );
801 nocache_headers();
802 } else {
803 status_header( 200 );
804 }
805 }
806
807 /**
808 * Sets up all of the variables required by the WordPress environment.
809 *
810 * The action {@see 'wp'} has one parameter that references the WP object. It
811 * allows for accessing the properties and methods to further manipulate the
812 * object.
813 *
814 * @since 2.0.0
815 *
816 * @param string|array $query_args Passed to parse_request().
817 */
818 public function main( $query_args = '' ) {
819 $this->init();
820
821 $parsed = $this->parse_request( $query_args );
822
823 if ( $parsed ) {
824 $this->query_posts();
825 $this->handle_404();
826 $this->register_globals();
827 }
828
829 $this->send_headers();
830
831 /**
832 * Fires once the WordPress environment has been set up.
833 *
834 * @since 2.1.0
835 *
836 * @param WP $wp Current WordPress environment instance (passed by reference).
837 */
838 do_action_ref_array( 'wp', array( &$this ) );
839 }
840}
841