at path:ROOT / wp-includes / load.php
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
📄load.php
1<?php
2/**
3 * These functions are needed to load WordPress.
4 *
5 * @package WordPress
6 */
7
8/**
9 * Returns the HTTP protocol sent by the server.
10 *
11 * @since 4.4.0
12 *
13 * @return string The HTTP protocol. Default: HTTP/1.0.
14 */
15function wp_get_server_protocol() {
16 $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : '';
17
18 if ( ! in_array( $protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0', 'HTTP/3' ), true ) ) {
19 $protocol = 'HTTP/1.0';
20 }
21
22 return $protocol;
23}
24
25/**
26 * Fixes `$_SERVER` variables for various setups.
27 *
28 * @since 3.0.0
29 * @access private
30 *
31 * @global string $PHP_SELF The filename of the currently executing script,
32 * relative to the document root.
33 */
34function wp_fix_server_vars() {
35 global $PHP_SELF;
36
37 $default_server_values = array(
38 'SERVER_SOFTWARE' => '',
39 'REQUEST_URI' => '',
40 );
41
42 $_SERVER = array_merge( $default_server_values, $_SERVER );
43
44 // Fix for IIS when running with PHP ISAPI.
45 if ( empty( $_SERVER['REQUEST_URI'] )
46 || ( 'cgi-fcgi' !== PHP_SAPI && preg_match( '/^Microsoft-IIS\//', $_SERVER['SERVER_SOFTWARE'] ) )
47 ) {
48
49 if ( isset( $_SERVER['HTTP_X_ORIGINAL_URL'] ) ) {
50 // IIS Mod-Rewrite.
51 $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_ORIGINAL_URL'];
52 } elseif ( isset( $_SERVER['HTTP_X_REWRITE_URL'] ) ) {
53 // IIS Isapi_Rewrite.
54 $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL'];
55 } else {
56 // Use ORIG_PATH_INFO if there is no PATH_INFO.
57 if ( ! isset( $_SERVER['PATH_INFO'] ) && isset( $_SERVER['ORIG_PATH_INFO'] ) ) {
58 $_SERVER['PATH_INFO'] = $_SERVER['ORIG_PATH_INFO'];
59 }
60
61 // Some IIS + PHP configurations put the script-name in the path-info (no need to append it twice).
62 if ( isset( $_SERVER['PATH_INFO'] ) ) {
63 if ( $_SERVER['PATH_INFO'] === $_SERVER['SCRIPT_NAME'] ) {
64 $_SERVER['REQUEST_URI'] = $_SERVER['PATH_INFO'];
65 } else {
66 $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
67 }
68 }
69
70 // Append the query string if it exists and isn't null.
71 if ( ! empty( $_SERVER['QUERY_STRING'] ) ) {
72 $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
73 }
74 }
75 }
76
77 // Fix for PHP as CGI hosts that set SCRIPT_FILENAME to something ending in php.cgi for all requests.
78 if ( isset( $_SERVER['SCRIPT_FILENAME'] ) && str_ends_with( $_SERVER['SCRIPT_FILENAME'], 'php.cgi' ) ) {
79 $_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED'];
80 }
81
82 // Fix for Dreamhost and other PHP as CGI hosts.
83 if ( isset( $_SERVER['SCRIPT_NAME'] ) && str_contains( $_SERVER['SCRIPT_NAME'], 'php.cgi' ) ) {
84 unset( $_SERVER['PATH_INFO'] );
85 }
86
87 // Fix empty PHP_SELF.
88 $PHP_SELF = $_SERVER['PHP_SELF'];
89 if ( empty( $PHP_SELF ) ) {
90 $_SERVER['PHP_SELF'] = preg_replace( '/(\?.*)?$/', '', $_SERVER['REQUEST_URI'] );
91 $PHP_SELF = $_SERVER['PHP_SELF'];
92 }
93
94 wp_populate_basic_auth_from_authorization_header();
95}
96
97/**
98 * Populates the Basic Auth server details from the Authorization header.
99 *
100 * Some servers running in CGI or FastCGI mode don't pass the Authorization
101 * header on to WordPress. If it's been rewritten to the `HTTP_AUTHORIZATION` header,
102 * fill in the proper $_SERVER variables instead.
103 *
104 * @since 5.6.0
105 */
106function wp_populate_basic_auth_from_authorization_header() {
107 // If we don't have anything to pull from, return early.
108 if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) && ! isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) {
109 return;
110 }
111
112 // If either PHP_AUTH key is already set, do nothing.
113 if ( isset( $_SERVER['PHP_AUTH_USER'] ) || isset( $_SERVER['PHP_AUTH_PW'] ) ) {
114 return;
115 }
116
117 // From our prior conditional, one of these must be set.
118 $header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
119
120 // Test to make sure the pattern matches expected.
121 if ( ! preg_match( '%^Basic [a-z\d/+]*={0,2}$%i', $header ) ) {
122 return;
123 }
124
125 // Removing `Basic ` the token would start six characters in.
126 $token = substr( $header, 6 );
127 $userpass = base64_decode( $token );
128
129 // There must be at least one colon in the string.
130 if ( ! str_contains( $userpass, ':' ) ) {
131 return;
132 }
133
134 list( $user, $pass ) = explode( ':', $userpass, 2 );
135
136 // Now shove them in the proper keys where we're expecting later on.
137 $_SERVER['PHP_AUTH_USER'] = $user;
138 $_SERVER['PHP_AUTH_PW'] = $pass;
139}
140
141/**
142 * Checks the server requirements.
143 *
144 * - PHP version
145 * - PHP extensions
146 * - MySQL or MariaDB version (unless a database drop-in is present)
147 *
148 * Dies if requirements are not met.
149 *
150 * @since 3.0.0
151 * @access private
152 *
153 * @global string $required_php_version The minimum required PHP version string.
154 * @global string[] $required_php_extensions The names of required PHP extensions.
155 * @global string $wp_version The WordPress version string.
156 */
157function wp_check_php_mysql_versions() {
158 global $required_php_version, $required_php_extensions, $wp_version;
159
160 $php_version = PHP_VERSION;
161
162 if ( version_compare( $required_php_version, $php_version, '>' ) ) {
163 $protocol = wp_get_server_protocol();
164 header( sprintf( '%s 500 Internal Server Error', $protocol ), true, 500 );
165 header( 'Content-Type: text/html; charset=utf-8' );
166 printf(
167 'Your server is running PHP version %1$s but WordPress %2$s requires at least %3$s.',
168 $php_version,
169 $wp_version,
170 $required_php_version
171 );
172 exit( 1 );
173 }
174
175 $missing_extensions = array();
176
177 if ( isset( $required_php_extensions ) && is_array( $required_php_extensions ) ) {
178 foreach ( $required_php_extensions as $extension ) {
179 if ( extension_loaded( $extension ) ) {
180 continue;
181 }
182
183 $missing_extensions[] = sprintf(
184 'WordPress %1$s requires the <code>%2$s</code> PHP extension.',
185 $wp_version,
186 $extension
187 );
188 }
189 }
190
191 if ( count( $missing_extensions ) > 0 ) {
192 $protocol = wp_get_server_protocol();
193 header( sprintf( '%s 500 Internal Server Error', $protocol ), true, 500 );
194 header( 'Content-Type: text/html; charset=utf-8' );
195 echo implode( '<br>', $missing_extensions );
196 exit( 1 );
197 }
198
199 // This runs before default constants are defined, so we can't assume WP_CONTENT_DIR is set yet.
200 $wp_content_dir = defined( 'WP_CONTENT_DIR' ) ? WP_CONTENT_DIR : ABSPATH . 'wp-content';
201
202 if ( ! function_exists( 'mysqli_connect' )
203 && ! file_exists( $wp_content_dir . '/db.php' )
204 ) {
205 require_once ABSPATH . WPINC . '/functions.php';
206 wp_load_translations_early();
207
208 $message = '<p>' . __( 'Your PHP installation appears to be missing the MySQL extension which is required by WordPress.' ) . "</p>\n";
209
210 $message .= '<p>' . sprintf(
211 /* translators: %s: mysqli. */
212 __( 'Please check that the %s PHP extension is installed and enabled.' ),
213 '<code>mysqli</code>'
214 ) . "</p>\n";
215
216 $message .= '<p>' . sprintf(
217 /* translators: %s: Support forums URL. */
218 __( 'If you are unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href="%s">WordPress support forums</a>.' ),
219 __( 'https://wordpress.org/support/forums/' )
220 ) . "</p>\n";
221
222 $args = array(
223 'exit' => false,
224 'code' => 'mysql_not_found',
225 );
226 wp_die(
227 $message,
228 __( 'Requirements Not Met' ),
229 $args
230 );
231 exit( 1 );
232 }
233}
234
235/**
236 * Retrieves the current environment type.
237 *
238 * The type can be set via the `WP_ENVIRONMENT_TYPE` global system variable,
239 * or a constant of the same name.
240 *
241 * Possible values are 'local', 'development', 'staging', and 'production'.
242 * If not set, the type defaults to 'production'.
243 *
244 * @since 5.5.0
245 * @since 5.5.1 Added the 'local' type.
246 * @since 5.5.1 Removed the ability to alter the list of types.
247 *
248 * @return string The current environment type.
249 */
250function wp_get_environment_type() {
251 static $current_env = '';
252
253 if ( ! defined( 'WP_RUN_CORE_TESTS' ) && $current_env ) {
254 return $current_env;
255 }
256
257 $wp_environments = array(
258 'local',
259 'development',
260 'staging',
261 'production',
262 );
263
264 // Add a note about the deprecated WP_ENVIRONMENT_TYPES constant.
265 if ( defined( 'WP_ENVIRONMENT_TYPES' ) && function_exists( '_deprecated_argument' ) ) {
266 if ( function_exists( '__' ) ) {
267 /* translators: %s: WP_ENVIRONMENT_TYPES */
268 $message = sprintf( __( 'The %s constant is no longer supported.' ), 'WP_ENVIRONMENT_TYPES' );
269 } else {
270 $message = sprintf( 'The %s constant is no longer supported.', 'WP_ENVIRONMENT_TYPES' );
271 }
272
273 _deprecated_argument(
274 'define()',
275 '5.5.1',
276 $message
277 );
278 }
279
280 // Check if the environment variable has been set, if `getenv` is available on the system.
281 if ( function_exists( 'getenv' ) ) {
282 $has_env = getenv( 'WP_ENVIRONMENT_TYPE' );
283 if ( false !== $has_env ) {
284 $current_env = $has_env;
285 }
286 }
287
288 // Fetch the environment from a constant, this overrides the global system variable.
289 if ( defined( 'WP_ENVIRONMENT_TYPE' ) && WP_ENVIRONMENT_TYPE ) {
290 $current_env = WP_ENVIRONMENT_TYPE;
291 }
292
293 // Make sure the environment is an allowed one, and not accidentally set to an invalid value.
294 if ( ! in_array( $current_env, $wp_environments, true ) ) {
295 $current_env = 'production';
296 }
297
298 return $current_env;
299}
300
301/**
302 * Retrieves the current development mode.
303 *
304 * The development mode affects how certain parts of the WordPress application behave,
305 * which is relevant when developing for WordPress.
306 *
307 * Development mode can be set via the `WP_DEVELOPMENT_MODE` constant in `wp-config.php`.
308 * Possible values are 'core', 'plugin', 'theme', 'all', or an empty string to disable
309 * development mode. 'all' is a special value to signify that all three development modes
310 * ('core', 'plugin', and 'theme') are enabled.
311 *
312 * Development mode is considered separately from `WP_DEBUG` and wp_get_environment_type().
313 * It does not affect debugging output, but rather functional nuances in WordPress.
314 *
315 * This function retrieves the currently set development mode value. To check whether
316 * a specific development mode is enabled, use wp_is_development_mode().
317 *
318 * @since 6.3.0
319 *
320 * @return string The current development mode.
321 */
322function wp_get_development_mode() {
323 static $current_mode = null;
324
325 if ( ! defined( 'WP_RUN_CORE_TESTS' ) && null !== $current_mode ) {
326 return $current_mode;
327 }
328
329 $development_mode = WP_DEVELOPMENT_MODE;
330
331 // Exclusively for core tests, rely on the `$_wp_tests_development_mode` global.
332 if ( defined( 'WP_RUN_CORE_TESTS' ) && isset( $GLOBALS['_wp_tests_development_mode'] ) ) {
333 $development_mode = $GLOBALS['_wp_tests_development_mode'];
334 }
335
336 $valid_modes = array(
337 'core',
338 'plugin',
339 'theme',
340 'all',
341 '',
342 );
343
344 if ( ! in_array( $development_mode, $valid_modes, true ) ) {
345 $development_mode = '';
346 }
347
348 $current_mode = $development_mode;
349
350 return $current_mode;
351}
352
353/**
354 * Checks whether the site is in the given development mode.
355 *
356 * @since 6.3.0
357 *
358 * @param string $mode Development mode to check for. Either 'core', 'plugin', 'theme', or 'all'.
359 * @return bool True if the given mode is covered by the current development mode, false otherwise.
360 */
361function wp_is_development_mode( $mode ) {
362 $current_mode = wp_get_development_mode();
363 if ( empty( $current_mode ) ) {
364 return false;
365 }
366
367 // Return true if the current mode encompasses all modes.
368 if ( 'all' === $current_mode ) {
369 return true;
370 }
371
372 // Return true if the current mode is the given mode.
373 return $mode === $current_mode;
374}
375
376/**
377 * Ensures all of WordPress is not loaded when handling a favicon.ico request.
378 *
379 * Instead, send the headers for a zero-length favicon and bail.
380 *
381 * @since 3.0.0
382 * @deprecated 5.4.0 Deprecated in favor of do_favicon().
383 */
384function wp_favicon_request() {
385 if ( '/favicon.ico' === $_SERVER['REQUEST_URI'] ) {
386 header( 'Content-Type: image/vnd.microsoft.icon' );
387 exit;
388 }
389}
390
391/**
392 * Dies with a maintenance message when conditions are met.
393 *
394 * The default message can be replaced by using a drop-in (maintenance.php in
395 * the wp-content directory).
396 *
397 * @since 3.0.0
398 * @access private
399 */
400function wp_maintenance() {
401 // Return if maintenance mode is disabled.
402 if ( ! wp_is_maintenance_mode() ) {
403 return;
404 }
405
406 if ( file_exists( WP_CONTENT_DIR . '/maintenance.php' ) ) {
407 require_once WP_CONTENT_DIR . '/maintenance.php';
408 die();
409 }
410
411 require_once ABSPATH . WPINC . '/functions.php';
412 wp_load_translations_early();
413
414 header( 'Retry-After: 600' );
415
416 wp_die(
417 __( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ),
418 __( 'Maintenance' ),
419 503
420 );
421}
422
423/**
424 * Checks if maintenance mode is enabled.
425 *
426 * Checks for a file in the WordPress root directory named ".maintenance".
427 * This file will contain the variable $upgrading, set to the time the file
428 * was created. If the file was created less than 10 minutes ago, WordPress
429 * is in maintenance mode.
430 *
431 * @since 5.5.0
432 *
433 * @global int $upgrading The Unix timestamp marking when upgrading WordPress began.
434 *
435 * @return bool True if maintenance mode is enabled, false otherwise.
436 */
437function wp_is_maintenance_mode() {
438 global $upgrading;
439
440 if ( ! file_exists( ABSPATH . '.maintenance' ) || wp_installing() ) {
441 return false;
442 }
443
444 require ABSPATH . '.maintenance';
445
446 // If the $upgrading timestamp is older than 10 minutes, consider maintenance over.
447 if ( ( time() - $upgrading ) >= 10 * MINUTE_IN_SECONDS ) {
448 return false;
449 }
450
451 // Don't enable maintenance mode while scraping for fatal errors.
452 if ( is_int( $upgrading ) && isset( $_REQUEST['wp_scrape_key'], $_REQUEST['wp_scrape_nonce'] ) ) {
453 $key = stripslashes( $_REQUEST['wp_scrape_key'] );
454 $nonce = stripslashes( $_REQUEST['wp_scrape_nonce'] );
455
456 if ( md5( $upgrading ) === $key && (int) $nonce === $upgrading ) {
457 return false;
458 }
459 }
460
461 /**
462 * Filters whether to enable maintenance mode.
463 *
464 * This filter runs before it can be used by plugins. It is designed for
465 * non-web runtimes. If this filter returns true, maintenance mode will be
466 * active and the request will end. If false, the request will be allowed to
467 * continue processing even if maintenance mode should be active.
468 *
469 * @since 4.6.0
470 *
471 * @param bool $enable_checks Whether to enable maintenance mode. Default true.
472 * @param int $upgrading The timestamp set in the .maintenance file.
473 */
474 if ( ! apply_filters( 'enable_maintenance_mode', true, $upgrading ) ) {
475 return false;
476 }
477
478 return true;
479}
480
481/**
482 * Gets the time elapsed so far during this PHP script.
483 *
484 * @since 5.8.0
485 *
486 * @return float Seconds since the PHP script started.
487 */
488function timer_float() {
489 return microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT'];
490}
491
492/**
493 * Starts the WordPress micro-timer.
494 *
495 * @since 0.71
496 * @access private
497 *
498 * @see timer_stop()
499 *
500 * @global float $timestart Unix timestamp set at the beginning of the page load.
501 *
502 * @return bool Always returns true.
503 */
504function timer_start() {
505 global $timestart;
506
507 $timestart = microtime( true );
508
509 return true;
510}
511
512/**
513 * Retrieves or displays the time from the page start to when function is called.
514 *
515 * @since 0.71
516 *
517 * @global float $timestart Seconds from when timer_start() is called.
518 * @global float $timeend Seconds from when function is called.
519 *
520 * @param int|bool $display Whether to echo or return the results. Accepts 0|false for return,
521 * 1|true for echo. Default 0|false.
522 * @param int $precision The number of digits from the right of the decimal to display.
523 * Default 3.
524 * @return string The "second.microsecond" finished time calculation. The number is formatted
525 * for human consumption, both localized and rounded.
526 */
527function timer_stop( $display = 0, $precision = 3 ) {
528 global $timestart, $timeend;
529
530 $timeend = microtime( true );
531 $timetotal = $timeend - $timestart;
532
533 if ( function_exists( 'number_format_i18n' ) ) {
534 $r = number_format_i18n( $timetotal, $precision );
535 } else {
536 $r = number_format( $timetotal, $precision );
537 }
538
539 if ( $display ) {
540 echo $r;
541 }
542
543 return $r;
544}
545
546/**
547 * Sets PHP error reporting based on WordPress debug settings.
548 *
549 * Uses three constants: `WP_DEBUG`, `WP_DEBUG_DISPLAY`, and `WP_DEBUG_LOG`.
550 * All three can be defined in wp-config.php. By default, `WP_DEBUG` and
551 * `WP_DEBUG_LOG` are set to false, and `WP_DEBUG_DISPLAY` is set to true.
552 *
553 * When `WP_DEBUG` is true, all PHP notices are reported. WordPress will also
554 * display internal notices: when a deprecated WordPress function, function
555 * argument, or file is used. Deprecated code may be removed from a later
556 * version.
557 *
558 * It is strongly recommended that plugin and theme developers use `WP_DEBUG`
559 * in their development environments.
560 *
561 * `WP_DEBUG_DISPLAY` and `WP_DEBUG_LOG` perform no function unless `WP_DEBUG`
562 * is true.
563 *
564 * When `WP_DEBUG_DISPLAY` is true, WordPress will force errors to be displayed.
565 * `WP_DEBUG_DISPLAY` defaults to true. Defining it as null prevents WordPress
566 * from changing the global configuration setting. Defining `WP_DEBUG_DISPLAY`
567 * as false will force errors to be hidden.
568 *
569 * When `WP_DEBUG_LOG` is true, errors will be logged to `wp-content/debug.log`.
570 * When `WP_DEBUG_LOG` is a valid path, errors will be logged to the specified file.
571 *
572 * Errors are never displayed for XML-RPC, REST, `ms-files.php`, and Ajax requests.
573 *
574 * @since 3.0.0
575 * @since 5.1.0 `WP_DEBUG_LOG` can be a file path.
576 * @access private
577 */
578function wp_debug_mode() {
579 /**
580 * Filters whether to allow the debug mode check to occur.
581 *
582 * This filter runs before it can be used by plugins. It is designed for
583 * non-web runtimes. Returning false causes the `WP_DEBUG` and related
584 * constants to not be checked and the default PHP values for errors
585 * will be used unless you take care to update them yourself.
586 *
587 * To use this filter you must define a `$wp_filter` global before
588 * WordPress loads, usually in `wp-config.php`.
589 *
590 * Example:
591 *
592 * $GLOBALS['wp_filter'] = array(
593 * 'enable_wp_debug_mode_checks' => array(
594 * 10 => array(
595 * array(
596 * 'accepted_args' => 0,
597 * 'function' => function() {
598 * return false;
599 * },
600 * ),
601 * ),
602 * ),
603 * );
604 *
605 * @since 4.6.0
606 *
607 * @param bool $enable_debug_mode Whether to enable debug mode checks to occur. Default true.
608 */
609 if ( ! apply_filters( 'enable_wp_debug_mode_checks', true ) ) {
610 return;
611 }
612
613 if ( WP_DEBUG ) {
614 error_reporting( E_ALL );
615
616 if ( WP_DEBUG_DISPLAY ) {
617 ini_set( 'display_errors', 1 );
618 } elseif ( null !== WP_DEBUG_DISPLAY ) {
619 ini_set( 'display_errors', 0 );
620 }
621
622 if ( in_array( strtolower( (string) WP_DEBUG_LOG ), array( 'true', '1' ), true ) ) {
623 $log_path = WP_CONTENT_DIR . '/debug.log';
624 } elseif ( is_string( WP_DEBUG_LOG ) ) {
625 $log_path = WP_DEBUG_LOG;
626 } else {
627 $log_path = false;
628 }
629
630 if ( $log_path ) {
631 ini_set( 'log_errors', 1 );
632 ini_set( 'error_log', $log_path );
633 }
634 } else {
635 error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
636 }
637
638 /*
639 * The 'REST_REQUEST' check here is optimistic as the constant is most
640 * likely not set at this point even if it is in fact a REST request.
641 */
642 if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || defined( 'MS_FILES_REQUEST' )
643 || ( defined( 'WP_INSTALLING' ) && WP_INSTALLING )
644 || wp_doing_ajax() || wp_is_json_request()
645 ) {
646 ini_set( 'display_errors', 0 );
647 }
648}
649
650/**
651 * Sets the location of the language directory.
652 *
653 * To set directory manually, define the `WP_LANG_DIR` constant
654 * in wp-config.php.
655 *
656 * If the language directory exists within `WP_CONTENT_DIR`, it
657 * is used. Otherwise the language directory is assumed to live
658 * in `WPINC`.
659 *
660 * @since 3.0.0
661 * @access private
662 */
663function wp_set_lang_dir() {
664 if ( ! defined( 'WP_LANG_DIR' ) ) {
665 if ( file_exists( WP_CONTENT_DIR . '/languages' ) && @is_dir( WP_CONTENT_DIR . '/languages' )
666 || ! @is_dir( ABSPATH . WPINC . '/languages' )
667 ) {
668 /**
669 * Server path of the language directory.
670 *
671 * No leading slash, no trailing slash, full path, not relative to ABSPATH
672 *
673 * @since 2.1.0
674 */
675 define( 'WP_LANG_DIR', WP_CONTENT_DIR . '/languages' );
676
677 if ( ! defined( 'LANGDIR' ) ) {
678 // Old static relative path maintained for limited backward compatibility - won't work in some cases.
679 define( 'LANGDIR', 'wp-content/languages' );
680 }
681 } else {
682 /**
683 * Server path of the language directory.
684 *
685 * No leading slash, no trailing slash, full path, not relative to `ABSPATH`.
686 *
687 * @since 2.1.0
688 */
689 define( 'WP_LANG_DIR', ABSPATH . WPINC . '/languages' );
690
691 if ( ! defined( 'LANGDIR' ) ) {
692 // Old relative path maintained for backward compatibility.
693 define( 'LANGDIR', WPINC . '/languages' );
694 }
695 }
696 }
697}
698
699/**
700 * Loads the database class file and instantiates the `$wpdb` global.
701 *
702 * @since 2.5.0
703 *
704 * @global wpdb $wpdb WordPress database abstraction object.
705 */
706function require_wp_db() {
707 global $wpdb;
708
709 require_once ABSPATH . WPINC . '/class-wpdb.php';
710
711 if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
712 require_once WP_CONTENT_DIR . '/db.php';
713 }
714
715 if ( isset( $wpdb ) ) {
716 return;
717 }
718
719 $dbuser = defined( 'DB_USER' ) ? DB_USER : '';
720 $dbpassword = defined( 'DB_PASSWORD' ) ? DB_PASSWORD : '';
721 $dbname = defined( 'DB_NAME' ) ? DB_NAME : '';
722 $dbhost = defined( 'DB_HOST' ) ? DB_HOST : '';
723
724 $wpdb = new wpdb( $dbuser, $dbpassword, $dbname, $dbhost );
725}
726
727/**
728 * Sets the database table prefix and the format specifiers for database
729 * table columns.
730 *
731 * Columns not listed here default to `%s`.
732 *
733 * @since 3.0.0
734 * @access private
735 *
736 * @global wpdb $wpdb WordPress database abstraction object.
737 * @global string $table_prefix The database table prefix.
738 */
739function wp_set_wpdb_vars() {
740 global $wpdb, $table_prefix;
741
742 if ( ! empty( $wpdb->error ) ) {
743 dead_db();
744 }
745
746 $wpdb->field_types = array(
747 'post_author' => '%d',
748 'post_parent' => '%d',
749 'menu_order' => '%d',
750 'term_id' => '%d',
751 'term_group' => '%d',
752 'term_taxonomy_id' => '%d',
753 'parent' => '%d',
754 'count' => '%d',
755 'object_id' => '%d',
756 'term_order' => '%d',
757 'ID' => '%d',
758 'comment_ID' => '%d',
759 'comment_post_ID' => '%d',
760 'comment_parent' => '%d',
761 'user_id' => '%d',
762 'link_id' => '%d',
763 'link_owner' => '%d',
764 'link_rating' => '%d',
765 'option_id' => '%d',
766 'blog_id' => '%d',
767 'meta_id' => '%d',
768 'post_id' => '%d',
769 'user_status' => '%d',
770 'umeta_id' => '%d',
771 'comment_karma' => '%d',
772 'comment_count' => '%d',
773 // Multisite:
774 'active' => '%d',
775 'cat_id' => '%d',
776 'deleted' => '%d',
777 'lang_id' => '%d',
778 'mature' => '%d',
779 'public' => '%d',
780 'site_id' => '%d',
781 'spam' => '%d',
782 );
783
784 $prefix = $wpdb->set_prefix( $table_prefix );
785
786 if ( is_wp_error( $prefix ) ) {
787 wp_load_translations_early();
788 wp_die(
789 sprintf(
790 /* translators: 1: $table_prefix, 2: wp-config.php */
791 __( '<strong>Error:</strong> %1$s in %2$s can only contain numbers, letters, and underscores.' ),
792 '<code>$table_prefix</code>',
793 '<code>wp-config.php</code>'
794 )
795 );
796 }
797}
798
799/**
800 * Toggles `$_wp_using_ext_object_cache` on and off without directly
801 * touching global.
802 *
803 * @since 3.7.0
804 *
805 * @global bool $_wp_using_ext_object_cache
806 *
807 * @param bool $using Whether external object cache is being used.
808 * @return bool The current 'using' setting.
809 */
810function wp_using_ext_object_cache( $using = null ) {
811 global $_wp_using_ext_object_cache;
812
813 $current_using = $_wp_using_ext_object_cache;
814
815 if ( null !== $using ) {
816 $_wp_using_ext_object_cache = $using;
817 }
818
819 return $current_using;
820}
821
822/**
823 * Starts the WordPress object cache.
824 *
825 * If an object-cache.php file exists in the wp-content directory,
826 * it uses that drop-in as an external object cache.
827 *
828 * @since 3.0.0
829 * @access private
830 *
831 * @global array $wp_filter Stores all of the filters.
832 */
833function wp_start_object_cache() {
834 global $wp_filter;
835 static $first_init = true;
836
837 // Only perform the following checks once.
838
839 /**
840 * Filters whether to enable loading of the object-cache.php drop-in.
841 *
842 * This filter runs before it can be used by plugins. It is designed for non-web
843 * runtimes. If false is returned, object-cache.php will never be loaded.
844 *
845 * @since 5.8.0
846 *
847 * @param bool $enable_object_cache Whether to enable loading object-cache.php (if present).
848 * Default true.
849 */
850 if ( $first_init && apply_filters( 'enable_loading_object_cache_dropin', true ) ) {
851 if ( ! function_exists( 'wp_cache_init' ) ) {
852 /*
853 * This is the normal situation. First-run of this function. No
854 * caching backend has been loaded.
855 *
856 * We try to load a custom caching backend, and then, if it
857 * results in a wp_cache_init() function existing, we note
858 * that an external object cache is being used.
859 */
860 if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
861 require_once WP_CONTENT_DIR . '/object-cache.php';
862
863 if ( function_exists( 'wp_cache_init' ) ) {
864 wp_using_ext_object_cache( true );
865 }
866
867 // Re-initialize any hooks added manually by object-cache.php.
868 if ( $wp_filter ) {
869 $wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter );
870 }
871 }
872 } elseif ( ! wp_using_ext_object_cache() && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
873 /*
874 * Sometimes advanced-cache.php can load object-cache.php before
875 * this function is run. This breaks the function_exists() check
876 * above and can result in wp_using_ext_object_cache() returning
877 * false when actually an external cache is in use.
878 */
879 wp_using_ext_object_cache( true );
880 }
881 }
882
883 if ( ! wp_using_ext_object_cache() ) {
884 require_once ABSPATH . WPINC . '/cache.php';
885 }
886
887 require_once ABSPATH . WPINC . '/cache-compat.php';
888
889 /*
890 * If cache supports reset, reset instead of init if already
891 * initialized. Reset signals to the cache that global IDs
892 * have changed and it may need to update keys and cleanup caches.
893 */
894 if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) ) {
895 wp_cache_switch_to_blog( get_current_blog_id() );
896 } elseif ( function_exists( 'wp_cache_init' ) ) {
897 wp_cache_init();
898 }
899
900 if ( function_exists( 'wp_cache_add_global_groups' ) ) {
901 wp_cache_add_global_groups(
902 array(
903 'blog-details',
904 'blog-id-cache',
905 'blog-lookup',
906 'blog_meta',
907 'global-posts',
908 'image_editor',
909 'networks',
910 'network-queries',
911 'sites',
912 'site-details',
913 'site-options',
914 'site-queries',
915 'site-transient',
916 'theme_files',
917 'translation_files',
918 'rss',
919 'users',
920 'user-queries',
921 'user_meta',
922 'useremail',
923 'userlogins',
924 'userslugs',
925 )
926 );
927
928 wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) );
929 }
930
931 $first_init = false;
932}
933
934/**
935 * Redirects to the installer if WordPress is not installed.
936 *
937 * Dies with an error message when Multisite is enabled.
938 *
939 * @since 3.0.0
940 * @access private
941 */
942function wp_not_installed() {
943 if ( is_blog_installed() || wp_installing() ) {
944 return;
945 }
946
947 nocache_headers();
948
949 if ( is_multisite() ) {
950 wp_die( __( 'The site you have requested is not installed properly. Please contact the system administrator.' ) );
951 }
952
953 require ABSPATH . WPINC . '/kses.php';
954 require ABSPATH . WPINC . '/pluggable.php';
955
956 $link = wp_guess_url() . '/wp-admin/install.php';
957
958 wp_redirect( $link );
959 die();
960}
961
962/**
963 * Retrieves an array of must-use plugin files.
964 *
965 * The default directory is wp-content/mu-plugins. To change the default
966 * directory manually, define `WPMU_PLUGIN_DIR` and `WPMU_PLUGIN_URL`
967 * in wp-config.php.
968 *
969 * @since 3.0.0
970 * @access private
971 *
972 * @return string[] Array of absolute paths of files to include.
973 */
974function wp_get_mu_plugins() {
975 $mu_plugins = array();
976
977 if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
978 return $mu_plugins;
979 }
980
981 $dh = opendir( WPMU_PLUGIN_DIR );
982 if ( ! $dh ) {
983 return $mu_plugins;
984 }
985
986 while ( ( $plugin = readdir( $dh ) ) !== false ) {
987 if ( str_ends_with( $plugin, '.php' ) ) {
988 $mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin;
989 }
990 }
991
992 closedir( $dh );
993
994 sort( $mu_plugins );
995
996 return $mu_plugins;
997}
998
999/**
1000 * Retrieves an array of active and valid plugin files.
1001 *
1002 * While upgrading or installing WordPress, no plugins are returned.
1003 *
1004 * The default directory is `wp-content/plugins`. To change the default
1005 * directory manually, define `WP_PLUGIN_DIR` and `WP_PLUGIN_URL`
1006 * in `wp-config.php`.
1007 *
1008 * @since 3.0.0
1009 * @access private
1010 *
1011 * @return string[] Array of paths to plugin files relative to the plugins directory.
1012 */
1013function wp_get_active_and_valid_plugins() {
1014 $plugins = array();
1015 $active_plugins = (array) get_option( 'active_plugins', array() );
1016
1017 // Check for hacks file if the option is enabled.
1018 if ( get_option( 'hack_file' ) && file_exists( ABSPATH . 'my-hacks.php' ) ) {
1019 _deprecated_file( 'my-hacks.php', '1.5.0' );
1020 array_unshift( $plugins, ABSPATH . 'my-hacks.php' );
1021 }
1022
1023 if ( empty( $active_plugins ) || wp_installing() ) {
1024 return $plugins;
1025 }
1026
1027 $network_plugins = is_multisite() ? wp_get_active_network_plugins() : false;
1028
1029 foreach ( $active_plugins as $plugin ) {
1030 if ( ! validate_file( $plugin ) // $plugin must validate as file.
1031 && str_ends_with( $plugin, '.php' ) // $plugin must end with '.php'.
1032 && file_exists( WP_PLUGIN_DIR . '/' . $plugin ) // $plugin must exist.
1033 // Not already included as a network plugin.
1034 && ( ! $network_plugins || ! in_array( WP_PLUGIN_DIR . '/' . $plugin, $network_plugins, true ) )
1035 ) {
1036 $plugins[] = WP_PLUGIN_DIR . '/' . $plugin;
1037 }
1038 }
1039
1040 /*
1041 * Remove plugins from the list of active plugins when we're on an endpoint
1042 * that should be protected against WSODs and the plugin is paused.
1043 */
1044 if ( wp_is_recovery_mode() ) {
1045 $plugins = wp_skip_paused_plugins( $plugins );
1046 }
1047
1048 return $plugins;
1049}
1050
1051/**
1052 * Filters a given list of plugins, removing any paused plugins from it.
1053 *
1054 * @since 5.2.0
1055 *
1056 * @global WP_Paused_Extensions_Storage $_paused_plugins
1057 *
1058 * @param string[] $plugins Array of absolute plugin main file paths.
1059 * @return string[] Filtered array of plugins, without any paused plugins.
1060 */
1061function wp_skip_paused_plugins( array $plugins ) {
1062 $paused_plugins = wp_paused_plugins()->get_all();
1063
1064 if ( empty( $paused_plugins ) ) {
1065 return $plugins;
1066 }
1067
1068 foreach ( $plugins as $index => $plugin ) {
1069 list( $plugin ) = explode( '/', plugin_basename( $plugin ) );
1070
1071 if ( array_key_exists( $plugin, $paused_plugins ) ) {
1072 unset( $plugins[ $index ] );
1073
1074 // Store list of paused plugins for displaying an admin notice.
1075 $GLOBALS['_paused_plugins'][ $plugin ] = $paused_plugins[ $plugin ];
1076 }
1077 }
1078
1079 return $plugins;
1080}
1081
1082/**
1083 * Retrieves an array of active and valid themes.
1084 *
1085 * While upgrading or installing WordPress, no themes are returned.
1086 *
1087 * @since 5.1.0
1088 * @access private
1089 *
1090 * @global string $pagenow The filename of the current screen.
1091 * @global string $wp_stylesheet_path Path to current theme's stylesheet directory.
1092 * @global string $wp_template_path Path to current theme's template directory.
1093 *
1094 * @return string[] Array of absolute paths to theme directories.
1095 */
1096function wp_get_active_and_valid_themes() {
1097 global $pagenow, $wp_stylesheet_path, $wp_template_path;
1098
1099 $themes = array();
1100
1101 if ( wp_installing() && 'wp-activate.php' !== $pagenow ) {
1102 return $themes;
1103 }
1104
1105 if ( is_child_theme() ) {
1106 $themes[] = $wp_stylesheet_path;
1107 }
1108
1109 $themes[] = $wp_template_path;
1110
1111 /*
1112 * Remove themes from the list of active themes when we're on an endpoint
1113 * that should be protected against WSODs and the theme is paused.
1114 */
1115 if ( wp_is_recovery_mode() ) {
1116 $themes = wp_skip_paused_themes( $themes );
1117
1118 // If no active and valid themes exist, skip loading themes.
1119 if ( empty( $themes ) ) {
1120 add_filter( 'wp_using_themes', '__return_false' );
1121 }
1122 }
1123
1124 return $themes;
1125}
1126
1127/**
1128 * Filters a given list of themes, removing any paused themes from it.
1129 *
1130 * @since 5.2.0
1131 *
1132 * @global WP_Paused_Extensions_Storage $_paused_themes
1133 *
1134 * @param string[] $themes Array of absolute theme directory paths.
1135 * @return string[] Filtered array of absolute paths to themes, without any paused themes.
1136 */
1137function wp_skip_paused_themes( array $themes ) {
1138 $paused_themes = wp_paused_themes()->get_all();
1139
1140 if ( empty( $paused_themes ) ) {
1141 return $themes;
1142 }
1143
1144 foreach ( $themes as $index => $theme ) {
1145 $theme = basename( $theme );
1146
1147 if ( array_key_exists( $theme, $paused_themes ) ) {
1148 unset( $themes[ $index ] );
1149
1150 // Store list of paused themes for displaying an admin notice.
1151 $GLOBALS['_paused_themes'][ $theme ] = $paused_themes[ $theme ];
1152 }
1153 }
1154
1155 return $themes;
1156}
1157
1158/**
1159 * Determines whether WordPress is in Recovery Mode.
1160 *
1161 * In this mode, plugins or themes that cause WSODs will be paused.
1162 *
1163 * @since 5.2.0
1164 *
1165 * @return bool
1166 */
1167function wp_is_recovery_mode() {
1168 return wp_recovery_mode()->is_active();
1169}
1170
1171/**
1172 * Determines whether we are currently on an endpoint that should be protected against WSODs.
1173 *
1174 * @since 5.2.0
1175 *
1176 * @global string $pagenow The filename of the current screen.
1177 *
1178 * @return bool True if the current endpoint should be protected.
1179 */
1180function is_protected_endpoint() {
1181 // Protect login pages.
1182 if ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] ) {
1183 return true;
1184 }
1185
1186 // Protect the admin backend.
1187 if ( is_admin() && ! wp_doing_ajax() ) {
1188 return true;
1189 }
1190
1191 // Protect Ajax actions that could help resolve a fatal error should be available.
1192 if ( is_protected_ajax_action() ) {
1193 return true;
1194 }
1195
1196 /**
1197 * Filters whether the current request is against a protected endpoint.
1198 *
1199 * This filter is only fired when an endpoint is requested which is not already protected by
1200 * WordPress core. As such, it exclusively allows providing further protected endpoints in
1201 * addition to the admin backend, login pages and protected Ajax actions.
1202 *
1203 * @since 5.2.0
1204 *
1205 * @param bool $is_protected_endpoint Whether the currently requested endpoint is protected.
1206 * Default false.
1207 */
1208 return (bool) apply_filters( 'is_protected_endpoint', false );
1209}
1210
1211/**
1212 * Determines whether we are currently handling an Ajax action that should be protected against WSODs.
1213 *
1214 * @since 5.2.0
1215 *
1216 * @return bool True if the current Ajax action should be protected.
1217 */
1218function is_protected_ajax_action() {
1219 if ( ! wp_doing_ajax() ) {
1220 return false;
1221 }
1222
1223 if ( ! isset( $_REQUEST['action'] ) ) {
1224 return false;
1225 }
1226
1227 $actions_to_protect = array(
1228 'edit-theme-plugin-file', // Saving changes in the core code editor.
1229 'heartbeat', // Keep the heart beating.
1230 'install-plugin', // Installing a new plugin.
1231 'install-theme', // Installing a new theme.
1232 'search-plugins', // Searching in the list of plugins.
1233 'search-install-plugins', // Searching for a plugin in the plugin install screen.
1234 'update-plugin', // Update an existing plugin.
1235 'update-theme', // Update an existing theme.
1236 'activate-plugin', // Activating an existing plugin.
1237 );
1238
1239 /**
1240 * Filters the array of protected Ajax actions.
1241 *
1242 * This filter is only fired when doing Ajax and the Ajax request has an 'action' property.
1243 *
1244 * @since 5.2.0
1245 *
1246 * @param string[] $actions_to_protect Array of strings with Ajax actions to protect.
1247 */
1248 $actions_to_protect = (array) apply_filters( 'wp_protected_ajax_actions', $actions_to_protect );
1249
1250 if ( ! in_array( $_REQUEST['action'], $actions_to_protect, true ) ) {
1251 return false;
1252 }
1253
1254 return true;
1255}
1256
1257/**
1258 * Sets internal encoding.
1259 *
1260 * In most cases the default internal encoding is latin1, which is
1261 * of no use, since we want to use the `mb_` functions for `utf-8` strings.
1262 *
1263 * @since 3.0.0
1264 * @access private
1265 */
1266function wp_set_internal_encoding() {
1267 if ( function_exists( 'mb_internal_encoding' ) ) {
1268 $charset = get_option( 'blog_charset' );
1269 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
1270 if ( ! $charset || ! @mb_internal_encoding( $charset ) ) {
1271 mb_internal_encoding( 'UTF-8' );
1272 }
1273 }
1274}
1275
1276/**
1277 * Adds magic quotes to `$_GET`, `$_POST`, `$_COOKIE`, and `$_SERVER`.
1278 *
1279 * Also forces `$_REQUEST` to be `$_GET + $_POST`. If `$_SERVER`,
1280 * `$_COOKIE`, or `$_ENV` are needed, use those superglobals directly.
1281 *
1282 * @since 3.0.0
1283 * @access private
1284 */
1285function wp_magic_quotes() {
1286 // Escape with wpdb.
1287 $_GET = add_magic_quotes( $_GET );
1288 $_POST = add_magic_quotes( $_POST );
1289 $_COOKIE = add_magic_quotes( $_COOKIE );
1290 $_SERVER = add_magic_quotes( $_SERVER );
1291
1292 // Force REQUEST to be GET + POST.
1293 $_REQUEST = array_merge( $_GET, $_POST );
1294}
1295
1296/**
1297 * Runs just before PHP shuts down execution.
1298 *
1299 * @since 1.2.0
1300 * @access private
1301 */
1302function shutdown_action_hook() {
1303 /**
1304 * Fires just before PHP shuts down execution.
1305 *
1306 * @since 1.2.0
1307 */
1308 do_action( 'shutdown' );
1309
1310 wp_cache_close();
1311}
1312
1313/**
1314 * Clones an object.
1315 *
1316 * @since 2.7.0
1317 * @deprecated 3.2.0
1318 *
1319 * @param object $input_object The object to clone.
1320 * @return object The cloned object.
1321 */
1322function wp_clone( $input_object ) {
1323 // Use parens for clone to accommodate PHP 4. See #17880.
1324 return clone( $input_object );
1325}
1326
1327/**
1328 * Determines whether the current request is for the login screen.
1329 *
1330 * @since 6.1.0
1331 *
1332 * @see wp_login_url()
1333 *
1334 * @return bool True if inside WordPress login screen, false otherwise.
1335 */
1336function is_login() {
1337 return false !== stripos( wp_login_url(), $_SERVER['SCRIPT_NAME'] );
1338}
1339
1340/**
1341 * Determines whether the current request is for an administrative interface page.
1342 *
1343 * Does not check if the user is an administrator; use current_user_can()
1344 * for checking roles and capabilities.
1345 *
1346 * For more information on this and similar theme functions, check out
1347 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
1348 * Conditional Tags} article in the Theme Developer Handbook.
1349 *
1350 * @since 1.5.1
1351 *
1352 * @global WP_Screen $current_screen WordPress current screen object.
1353 *
1354 * @return bool True if inside WordPress administration interface, false otherwise.
1355 */
1356function is_admin() {
1357 if ( isset( $GLOBALS['current_screen'] ) ) {
1358 return $GLOBALS['current_screen']->in_admin();
1359 } elseif ( defined( 'WP_ADMIN' ) ) {
1360 return WP_ADMIN;
1361 }
1362
1363 return false;
1364}
1365
1366/**
1367 * Determines whether the current request is for a site's administrative interface.
1368 *
1369 * e.g. `/wp-admin/`
1370 *
1371 * Does not check if the user is an administrator; use current_user_can()
1372 * for checking roles and capabilities.
1373 *
1374 * @since 3.1.0
1375 *
1376 * @global WP_Screen $current_screen WordPress current screen object.
1377 *
1378 * @return bool True if inside WordPress site administration pages.
1379 */
1380function is_blog_admin() {
1381 if ( isset( $GLOBALS['current_screen'] ) ) {
1382 return $GLOBALS['current_screen']->in_admin( 'site' );
1383 } elseif ( defined( 'WP_BLOG_ADMIN' ) ) {
1384 return WP_BLOG_ADMIN;
1385 }
1386
1387 return false;
1388}
1389
1390/**
1391 * Determines whether the current request is for the network administrative interface.
1392 *
1393 * e.g. `/wp-admin/network/`
1394 *
1395 * Does not check if the user is an administrator; use current_user_can()
1396 * for checking roles and capabilities.
1397 *
1398 * Does not check if the site is a Multisite network; use is_multisite()
1399 * for checking if Multisite is enabled.
1400 *
1401 * @since 3.1.0
1402 *
1403 * @global WP_Screen $current_screen WordPress current screen object.
1404 *
1405 * @return bool True if inside WordPress network administration pages.
1406 */
1407function is_network_admin() {
1408 if ( isset( $GLOBALS['current_screen'] ) ) {
1409 return $GLOBALS['current_screen']->in_admin( 'network' );
1410 } elseif ( defined( 'WP_NETWORK_ADMIN' ) ) {
1411 return WP_NETWORK_ADMIN;
1412 }
1413
1414 return false;
1415}
1416
1417/**
1418 * Determines whether the current request is for a user admin screen.
1419 *
1420 * e.g. `/wp-admin/user/`
1421 *
1422 * Does not check if the user is an administrator; use current_user_can()
1423 * for checking roles and capabilities.
1424 *
1425 * @since 3.1.0
1426 *
1427 * @global WP_Screen $current_screen WordPress current screen object.
1428 *
1429 * @return bool True if inside WordPress user administration pages.
1430 */
1431function is_user_admin() {
1432 if ( isset( $GLOBALS['current_screen'] ) ) {
1433 return $GLOBALS['current_screen']->in_admin( 'user' );
1434 } elseif ( defined( 'WP_USER_ADMIN' ) ) {
1435 return WP_USER_ADMIN;
1436 }
1437
1438 return false;
1439}
1440
1441/**
1442 * Determines whether Multisite is enabled.
1443 *
1444 * @since 3.0.0
1445 *
1446 * @return bool True if Multisite is enabled, false otherwise.
1447 */
1448function is_multisite() {
1449 if ( defined( 'MULTISITE' ) ) {
1450 return MULTISITE;
1451 }
1452
1453 if ( defined( 'SUBDOMAIN_INSTALL' ) || defined( 'VHOST' ) || defined( 'SUNRISE' ) ) {
1454 return true;
1455 }
1456
1457 return false;
1458}
1459
1460/**
1461 * Converts a value to non-negative integer.
1462 *
1463 * @since 2.5.0
1464 *
1465 * @param mixed $maybeint Data you wish to have converted to a non-negative integer.
1466 * @return int A non-negative integer.
1467 */
1468function absint( $maybeint ) {
1469 return abs( (int) $maybeint );
1470}
1471
1472/**
1473 * Retrieves the current site ID.
1474 *
1475 * @since 3.1.0
1476 *
1477 * @global int $blog_id
1478 *
1479 * @return int Site ID.
1480 */
1481function get_current_blog_id() {
1482 global $blog_id;
1483
1484 return absint( $blog_id );
1485}
1486
1487/**
1488 * Retrieves the current network ID.
1489 *
1490 * @since 4.6.0
1491 *
1492 * @return int The ID of the current network.
1493 */
1494function get_current_network_id() {
1495 if ( ! is_multisite() ) {
1496 return 1;
1497 }
1498
1499 $current_network = get_network();
1500
1501 if ( ! isset( $current_network->id ) ) {
1502 return get_main_network_id();
1503 }
1504
1505 return absint( $current_network->id );
1506}
1507
1508/**
1509 * Attempts an early load of translations.
1510 *
1511 * Used for errors encountered during the initial loading process, before
1512 * the locale has been properly detected and loaded.
1513 *
1514 * Designed for unusual load sequences (like setup-config.php) or for when
1515 * the script will then terminate with an error, otherwise there is a risk
1516 * that a file can be double-included.
1517 *
1518 * @since 3.4.0
1519 * @access private
1520 *
1521 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1522 * @global WP_Locale $wp_locale WordPress date and time locale object.
1523 */
1524function wp_load_translations_early() {
1525 global $wp_textdomain_registry, $wp_locale;
1526 static $loaded = false;
1527
1528 if ( $loaded ) {
1529 return;
1530 }
1531
1532 $loaded = true;
1533
1534 if ( function_exists( 'did_action' ) && did_action( 'init' ) ) {
1535 return;
1536 }
1537
1538 // We need $wp_local_package.
1539 require ABSPATH . WPINC . '/version.php';
1540
1541 // Translation and localization.
1542 require_once ABSPATH . WPINC . '/pomo/mo.php';
1543 require_once ABSPATH . WPINC . '/l10n/class-wp-translation-controller.php';
1544 require_once ABSPATH . WPINC . '/l10n/class-wp-translations.php';
1545 require_once ABSPATH . WPINC . '/l10n/class-wp-translation-file.php';
1546 require_once ABSPATH . WPINC . '/l10n/class-wp-translation-file-mo.php';
1547 require_once ABSPATH . WPINC . '/l10n/class-wp-translation-file-php.php';
1548 require_once ABSPATH . WPINC . '/l10n.php';
1549 require_once ABSPATH . WPINC . '/class-wp-textdomain-registry.php';
1550 require_once ABSPATH . WPINC . '/class-wp-locale.php';
1551 require_once ABSPATH . WPINC . '/class-wp-locale-switcher.php';
1552
1553 // General libraries.
1554 require_once ABSPATH . WPINC . '/plugin.php';
1555
1556 $locales = array();
1557 $locations = array();
1558
1559 if ( ! $wp_textdomain_registry instanceof WP_Textdomain_Registry ) {
1560 $wp_textdomain_registry = new WP_Textdomain_Registry();
1561 }
1562
1563 while ( true ) {
1564 if ( defined( 'WPLANG' ) ) {
1565 if ( '' === WPLANG ) {
1566 break;
1567 }
1568 $locales[] = WPLANG;
1569 }
1570
1571 if ( isset( $wp_local_package ) ) {
1572 $locales[] = $wp_local_package;
1573 }
1574
1575 if ( ! $locales ) {
1576 break;
1577 }
1578
1579 if ( defined( 'WP_LANG_DIR' ) && @is_dir( WP_LANG_DIR ) ) {
1580 $locations[] = WP_LANG_DIR;
1581 }
1582
1583 if ( defined( 'WP_CONTENT_DIR' ) && @is_dir( WP_CONTENT_DIR . '/languages' ) ) {
1584 $locations[] = WP_CONTENT_DIR . '/languages';
1585 }
1586
1587 if ( @is_dir( ABSPATH . 'wp-content/languages' ) ) {
1588 $locations[] = ABSPATH . 'wp-content/languages';
1589 }
1590
1591 if ( @is_dir( ABSPATH . WPINC . '/languages' ) ) {
1592 $locations[] = ABSPATH . WPINC . '/languages';
1593 }
1594
1595 if ( ! $locations ) {
1596 break;
1597 }
1598
1599 $locations = array_unique( $locations );
1600
1601 foreach ( $locales as $locale ) {
1602 foreach ( $locations as $location ) {
1603 if ( file_exists( $location . '/' . $locale . '.mo' ) ) {
1604 load_textdomain( 'default', $location . '/' . $locale . '.mo', $locale );
1605
1606 if ( defined( 'WP_SETUP_CONFIG' ) && file_exists( $location . '/admin-' . $locale . '.mo' ) ) {
1607 load_textdomain( 'default', $location . '/admin-' . $locale . '.mo', $locale );
1608 }
1609
1610 break 2;
1611 }
1612 }
1613 }
1614
1615 break;
1616 }
1617
1618 $wp_locale = new WP_Locale();
1619}
1620
1621/**
1622 * Checks or sets whether WordPress is in "installation" mode.
1623 *
1624 * If the `WP_INSTALLING` constant is defined during the bootstrap, `wp_installing()` will default to `true`.
1625 *
1626 * @since 4.4.0
1627 *
1628 * @param bool $is_installing Optional. True to set WP into Installing mode, false to turn Installing mode off.
1629 * Omit this parameter if you only want to fetch the current status.
1630 * @return bool True if WP is installing, otherwise false. When a `$is_installing` is passed, the function will
1631 * report whether WP was in installing mode prior to the change to `$is_installing`.
1632 */
1633function wp_installing( $is_installing = null ) {
1634 static $installing = null;
1635
1636 // Support for the `WP_INSTALLING` constant, defined before WP is loaded.
1637 if ( is_null( $installing ) ) {
1638 $installing = defined( 'WP_INSTALLING' ) && WP_INSTALLING;
1639 }
1640
1641 if ( ! is_null( $is_installing ) ) {
1642 $old_installing = $installing;
1643 $installing = $is_installing;
1644
1645 return (bool) $old_installing;
1646 }
1647
1648 return (bool) $installing;
1649}
1650
1651/**
1652 * Determines if SSL is used.
1653 *
1654 * @since 2.6.0
1655 * @since 4.6.0 Moved from functions.php to load.php.
1656 *
1657 * @return bool True if SSL, otherwise false.
1658 */
1659function is_ssl() {
1660 if ( isset( $_SERVER['HTTPS'] ) ) {
1661 if ( 'on' === strtolower( $_SERVER['HTTPS'] ) ) {
1662 return true;
1663 }
1664
1665 if ( '1' === (string) $_SERVER['HTTPS'] ) {
1666 return true;
1667 }
1668 } elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' === (string) $_SERVER['SERVER_PORT'] ) ) {
1669 return true;
1670 }
1671
1672 return false;
1673}
1674
1675/**
1676 * Converts a shorthand byte value to an integer byte value.
1677 *
1678 * @since 2.3.0
1679 * @since 4.6.0 Moved from media.php to load.php.
1680 *
1681 * @link https://www.php.net/manual/en/function.ini-get.php
1682 * @link https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
1683 *
1684 * @param string $value A (PHP ini) byte value, either shorthand or ordinary.
1685 * @return int An integer byte value.
1686 */
1687function wp_convert_hr_to_bytes( $value ) {
1688 $value = strtolower( trim( $value ) );
1689 $bytes = (int) $value;
1690
1691 if ( str_contains( $value, 'g' ) ) {
1692 $bytes *= GB_IN_BYTES;
1693 } elseif ( str_contains( $value, 'm' ) ) {
1694 $bytes *= MB_IN_BYTES;
1695 } elseif ( str_contains( $value, 'k' ) ) {
1696 $bytes *= KB_IN_BYTES;
1697 }
1698
1699 // Deal with large (float) values which run into the maximum integer size.
1700 return min( $bytes, PHP_INT_MAX );
1701}
1702
1703/**
1704 * Determines whether a PHP ini value is changeable at runtime.
1705 *
1706 * @since 4.6.0
1707 *
1708 * @link https://www.php.net/manual/en/function.ini-get-all.php
1709 *
1710 * @param string $setting The name of the ini setting to check.
1711 * @return bool True if the value is changeable at runtime. False otherwise.
1712 */
1713function wp_is_ini_value_changeable( $setting ) {
1714 static $ini_all;
1715
1716 if ( ! isset( $ini_all ) ) {
1717 $ini_all = false;
1718 // Sometimes `ini_get_all()` is disabled via the `disable_functions` option for "security purposes".
1719 if ( function_exists( 'ini_get_all' ) ) {
1720 $ini_all = ini_get_all();
1721 }
1722 }
1723
1724 if ( isset( $ini_all[ $setting ]['access'] )
1725 && ( INI_ALL === $ini_all[ $setting ]['access'] || INI_USER === $ini_all[ $setting ]['access'] )
1726 ) {
1727 return true;
1728 }
1729
1730 // If we were unable to retrieve the details, fail gracefully to assume it's changeable.
1731 if ( ! is_array( $ini_all ) ) {
1732 return true;
1733 }
1734
1735 return false;
1736}
1737
1738/**
1739 * Determines whether the current request is a WordPress Ajax request.
1740 *
1741 * @since 4.7.0
1742 *
1743 * @return bool True if it's a WordPress Ajax request, false otherwise.
1744 */
1745function wp_doing_ajax() {
1746 /**
1747 * Filters whether the current request is a WordPress Ajax request.
1748 *
1749 * @since 4.7.0
1750 *
1751 * @param bool $wp_doing_ajax Whether the current request is a WordPress Ajax request.
1752 */
1753 return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
1754}
1755
1756/**
1757 * Determines whether the current request should use themes.
1758 *
1759 * @since 5.1.0
1760 *
1761 * @return bool True if themes should be used, false otherwise.
1762 */
1763function wp_using_themes() {
1764 /**
1765 * Filters whether the current request should use themes.
1766 *
1767 * @since 5.1.0
1768 *
1769 * @param bool $wp_using_themes Whether the current request should use themes.
1770 */
1771 return apply_filters( 'wp_using_themes', defined( 'WP_USE_THEMES' ) && WP_USE_THEMES );
1772}
1773
1774/**
1775 * Determines whether the current request is a WordPress cron request.
1776 *
1777 * @since 4.8.0
1778 *
1779 * @return bool True if it's a WordPress cron request, false otherwise.
1780 */
1781function wp_doing_cron() {
1782 /**
1783 * Filters whether the current request is a WordPress cron request.
1784 *
1785 * @since 4.8.0
1786 *
1787 * @param bool $wp_doing_cron Whether the current request is a WordPress cron request.
1788 */
1789 return apply_filters( 'wp_doing_cron', defined( 'DOING_CRON' ) && DOING_CRON );
1790}
1791
1792/**
1793 * Checks whether the given variable is a WordPress Error.
1794 *
1795 * Returns whether `$thing` is an instance of the `WP_Error` class.
1796 *
1797 * @since 2.1.0
1798 *
1799 * @param mixed $thing The variable to check.
1800 * @return bool Whether the variable is an instance of WP_Error.
1801 */
1802function is_wp_error( $thing ) {
1803 $is_wp_error = ( $thing instanceof WP_Error );
1804
1805 if ( $is_wp_error ) {
1806 /**
1807 * Fires when `is_wp_error()` is called and its parameter is an instance of `WP_Error`.
1808 *
1809 * @since 5.6.0
1810 *
1811 * @param WP_Error $thing The error object passed to `is_wp_error()`.
1812 */
1813 do_action( 'is_wp_error_instance', $thing );
1814 }
1815
1816 return $is_wp_error;
1817}
1818
1819/**
1820 * Determines whether file modifications are allowed.
1821 *
1822 * @since 4.8.0
1823 *
1824 * @param string $context The usage context.
1825 * @return bool True if file modification is allowed, false otherwise.
1826 */
1827function wp_is_file_mod_allowed( $context ) {
1828 /**
1829 * Filters whether file modifications are allowed.
1830 *
1831 * @since 4.8.0
1832 *
1833 * @param bool $file_mod_allowed Whether file modifications are allowed.
1834 * @param string $context The usage context.
1835 */
1836 return apply_filters( 'file_mod_allowed', ! defined( 'DISALLOW_FILE_MODS' ) || ! DISALLOW_FILE_MODS, $context );
1837}
1838
1839/**
1840 * Starts scraping edited file errors.
1841 *
1842 * @since 4.9.0
1843 */
1844function wp_start_scraping_edited_file_errors() {
1845 if ( ! isset( $_REQUEST['wp_scrape_key'] ) || ! isset( $_REQUEST['wp_scrape_nonce'] ) ) {
1846 return;
1847 }
1848
1849 $key = substr( sanitize_key( wp_unslash( $_REQUEST['wp_scrape_key'] ) ), 0, 32 );
1850 $nonce = wp_unslash( $_REQUEST['wp_scrape_nonce'] );
1851 if ( empty( $key ) || empty( $nonce ) ) {
1852 return;
1853 }
1854
1855 $transient = get_transient( 'scrape_key_' . $key );
1856 if ( false === $transient ) {
1857 return;
1858 }
1859
1860 if ( $transient !== $nonce ) {
1861 if ( ! headers_sent() ) {
1862 header( 'X-Robots-Tag: noindex' );
1863 nocache_headers();
1864 }
1865 echo "###### wp_scraping_result_start:$key ######";
1866 echo wp_json_encode(
1867 array(
1868 'code' => 'scrape_nonce_failure',
1869 'message' => __( 'Scrape key check failed. Please try again.' ),
1870 )
1871 );
1872 echo "###### wp_scraping_result_end:$key ######";
1873 die();
1874 }
1875
1876 if ( ! defined( 'WP_SANDBOX_SCRAPING' ) ) {
1877 define( 'WP_SANDBOX_SCRAPING', true );
1878 }
1879
1880 register_shutdown_function( 'wp_finalize_scraping_edited_file_errors', $key );
1881}
1882
1883/**
1884 * Finalizes scraping for edited file errors.
1885 *
1886 * @since 4.9.0
1887 *
1888 * @param string $scrape_key Scrape key.
1889 */
1890function wp_finalize_scraping_edited_file_errors( $scrape_key ) {
1891 $error = error_get_last();
1892
1893 echo "\n###### wp_scraping_result_start:$scrape_key ######\n";
1894
1895 if ( ! empty( $error )
1896 && in_array( $error['type'], array( E_CORE_ERROR, E_COMPILE_ERROR, E_ERROR, E_PARSE, E_USER_ERROR, E_RECOVERABLE_ERROR ), true )
1897 ) {
1898 $error = str_replace( ABSPATH, '', $error );
1899 echo wp_json_encode( $error );
1900 } else {
1901 echo wp_json_encode( true );
1902 }
1903
1904 echo "\n###### wp_scraping_result_end:$scrape_key ######\n";
1905}
1906
1907/**
1908 * Checks whether current request is a JSON request, or is expecting a JSON response.
1909 *
1910 * @since 5.0.0
1911 *
1912 * @return bool True if `Accepts` or `Content-Type` headers contain `application/json`.
1913 * False otherwise.
1914 */
1915function wp_is_json_request() {
1916 if ( isset( $_SERVER['HTTP_ACCEPT'] ) && wp_is_json_media_type( $_SERVER['HTTP_ACCEPT'] ) ) {
1917 return true;
1918 }
1919
1920 if ( isset( $_SERVER['CONTENT_TYPE'] ) && wp_is_json_media_type( $_SERVER['CONTENT_TYPE'] ) ) {
1921 return true;
1922 }
1923
1924 return false;
1925}
1926
1927/**
1928 * Checks whether current request is a JSONP request, or is expecting a JSONP response.
1929 *
1930 * @since 5.2.0
1931 *
1932 * @return bool True if JSONP request, false otherwise.
1933 */
1934function wp_is_jsonp_request() {
1935 if ( ! isset( $_GET['_jsonp'] ) ) {
1936 return false;
1937 }
1938
1939 if ( ! function_exists( 'wp_check_jsonp_callback' ) ) {
1940 require_once ABSPATH . WPINC . '/functions.php';
1941 }
1942
1943 $jsonp_callback = $_GET['_jsonp'];
1944 if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) {
1945 return false;
1946 }
1947
1948 /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
1949 $jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true );
1950
1951 return $jsonp_enabled;
1952}
1953
1954/**
1955 * Checks whether a string is a valid JSON Media Type.
1956 *
1957 * @since 5.6.0
1958 *
1959 * @param string $media_type A Media Type string to check.
1960 * @return bool True if string is a valid JSON Media Type.
1961 */
1962function wp_is_json_media_type( $media_type ) {
1963 static $cache = array();
1964
1965 if ( ! isset( $cache[ $media_type ] ) ) {
1966 $cache[ $media_type ] = (bool) preg_match( '/(^|\s|,)application\/([\w!#\$&-\^\.\+]+\+)?json(\+oembed)?($|\s|;|,)/i', $media_type );
1967 }
1968
1969 return $cache[ $media_type ];
1970}
1971
1972/**
1973 * Checks whether current request is an XML request, or is expecting an XML response.
1974 *
1975 * @since 5.2.0
1976 *
1977 * @return bool True if `Accepts` or `Content-Type` headers contain `text/xml`
1978 * or one of the related MIME types. False otherwise.
1979 */
1980function wp_is_xml_request() {
1981 $accepted = array(
1982 'text/xml',
1983 'application/rss+xml',
1984 'application/atom+xml',
1985 'application/rdf+xml',
1986 'text/xml+oembed',
1987 'application/xml+oembed',
1988 );
1989
1990 if ( isset( $_SERVER['HTTP_ACCEPT'] ) ) {
1991 foreach ( $accepted as $type ) {
1992 if ( str_contains( $_SERVER['HTTP_ACCEPT'], $type ) ) {
1993 return true;
1994 }
1995 }
1996 }
1997
1998 if ( isset( $_SERVER['CONTENT_TYPE'] ) && in_array( $_SERVER['CONTENT_TYPE'], $accepted, true ) ) {
1999 return true;
2000 }
2001
2002 return false;
2003}
2004
2005/**
2006 * Checks if this site is protected by HTTP Basic Auth.
2007 *
2008 * At the moment, this merely checks for the present of Basic Auth credentials. Therefore, calling
2009 * this function with a context different from the current context may give inaccurate results.
2010 * In a future release, this evaluation may be made more robust.
2011 *
2012 * Currently, this is only used by Application Passwords to prevent a conflict since it also utilizes
2013 * Basic Auth.
2014 *
2015 * @since 5.6.1
2016 *
2017 * @global string $pagenow The filename of the current screen.
2018 *
2019 * @param string $context The context to check for protection. Accepts 'login', 'admin', and 'front'.
2020 * Defaults to the current context.
2021 * @return bool Whether the site is protected by Basic Auth.
2022 */
2023function wp_is_site_protected_by_basic_auth( $context = '' ) {
2024 global $pagenow;
2025
2026 if ( ! $context ) {
2027 if ( 'wp-login.php' === $pagenow ) {
2028 $context = 'login';
2029 } elseif ( is_admin() ) {
2030 $context = 'admin';
2031 } else {
2032 $context = 'front';
2033 }
2034 }
2035
2036 $is_protected = ! empty( $_SERVER['PHP_AUTH_USER'] ) || ! empty( $_SERVER['PHP_AUTH_PW'] );
2037
2038 /**
2039 * Filters whether a site is protected by HTTP Basic Auth.
2040 *
2041 * @since 5.6.1
2042 *
2043 * @param bool $is_protected Whether the site is protected by Basic Auth.
2044 * @param string $context The context to check for protection. One of 'login', 'admin', or 'front'.
2045 */
2046 return apply_filters( 'wp_is_site_protected_by_basic_auth', $is_protected, $context );
2047}
2048