[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> load.php (source)

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


Generated: Thu Feb 25 01:00:09 2021 Cross-referenced by PHPXref 0.7.1