[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

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


Generated : Thu Apr 10 08:20:01 2025 Cross-referenced by PHPXref