PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-includes/load.php

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