balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

load.php (50040B)


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