[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-admin/includes/ -> misc.php (source)

   1  <?php
   2  /**
   3   * Misc WordPress Administration API.
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   */
   8  
   9  /**
  10   * Returns whether the server is running Apache with the mod_rewrite module loaded.
  11   *
  12   * @since 2.0.0
  13   *
  14   * @return bool Whether the server is running Apache with the mod_rewrite module loaded.
  15   */
  16  function got_mod_rewrite() {
  17      $got_rewrite = apache_mod_loaded( 'mod_rewrite', true );
  18  
  19      /**
  20       * Filters whether Apache and mod_rewrite are present.
  21       *
  22       * This filter was previously used to force URL rewriting for other servers,
  23       * like nginx. Use the {@see 'got_url_rewrite'} filter in got_url_rewrite() instead.
  24       *
  25       * @since 2.5.0
  26       *
  27       * @see got_url_rewrite()
  28       *
  29       * @param bool $got_rewrite Whether Apache and mod_rewrite are present.
  30       */
  31      return apply_filters( 'got_rewrite', $got_rewrite );
  32  }
  33  
  34  /**
  35   * Returns whether the server supports URL rewriting.
  36   *
  37   * Detects Apache's mod_rewrite, IIS 7.0+ permalink support, and nginx.
  38   *
  39   * @since 3.7.0
  40   *
  41   * @global bool $is_nginx
  42   *
  43   * @return bool Whether the server supports URL rewriting.
  44   */
  45  function got_url_rewrite() {
  46      $got_url_rewrite = ( got_mod_rewrite() || $GLOBALS['is_nginx'] || iis7_supports_permalinks() );
  47  
  48      /**
  49       * Filters whether URL rewriting is available.
  50       *
  51       * @since 3.7.0
  52       *
  53       * @param bool $got_url_rewrite Whether URL rewriting is available.
  54       */
  55      return apply_filters( 'got_url_rewrite', $got_url_rewrite );
  56  }
  57  
  58  /**
  59   * Extracts strings from between the BEGIN and END markers in the .htaccess file.
  60   *
  61   * @since 1.5.0
  62   *
  63   * @param string $filename Filename to extract the strings from.
  64   * @param string $marker   The marker to extract the strings from.
  65   * @return array An array of strings from a file (.htaccess) from between BEGIN and END markers.
  66   */
  67  function extract_from_markers( $filename, $marker ) {
  68      $result = array();
  69  
  70      if ( ! file_exists( $filename ) ) {
  71          return $result;
  72      }
  73  
  74      $markerdata = explode( "\n", implode( '', file( $filename ) ) );
  75  
  76      $state = false;
  77      foreach ( $markerdata as $markerline ) {
  78          if ( false !== strpos( $markerline, '# END ' . $marker ) ) {
  79              $state = false;
  80          }
  81          if ( $state ) {
  82              if ( '#' === substr( $markerline, 0, 1 ) ) {
  83                  continue;
  84              }
  85              $result[] = $markerline;
  86          }
  87          if ( false !== strpos( $markerline, '# BEGIN ' . $marker ) ) {
  88              $state = true;
  89          }
  90      }
  91  
  92      return $result;
  93  }
  94  
  95  /**
  96   * Inserts an array of strings into a file (.htaccess), placing it between
  97   * BEGIN and END markers.
  98   *
  99   * Replaces existing marked info. Retains surrounding
 100   * data. Creates file if none exists.
 101   *
 102   * @since 1.5.0
 103   *
 104   * @param string       $filename  Filename to alter.
 105   * @param string       $marker    The marker to alter.
 106   * @param array|string $insertion The new content to insert.
 107   * @return bool True on write success, false on failure.
 108   */
 109  function insert_with_markers( $filename, $marker, $insertion ) {
 110      if ( ! file_exists( $filename ) ) {
 111          if ( ! is_writable( dirname( $filename ) ) ) {
 112              return false;
 113          }
 114          if ( ! touch( $filename ) ) {
 115              return false;
 116          }
 117      } elseif ( ! is_writeable( $filename ) ) {
 118          return false;
 119      }
 120  
 121      if ( ! is_array( $insertion ) ) {
 122          $insertion = explode( "\n", $insertion );
 123      }
 124  
 125      $switched_locale = switch_to_locale( get_locale() );
 126  
 127      $instructions = sprintf(
 128          /* translators: 1: marker */
 129          __(
 130              'The directives (lines) between `BEGIN %1$s` and `END %1$s` are
 131  dynamically generated, and should only be modified via WordPress filters.
 132  Any changes to the directives between these markers will be overwritten.'
 133          ),
 134          $marker
 135      );
 136  
 137      $instructions = explode( "\n", $instructions );
 138      foreach ( $instructions as $line => $text ) {
 139          $instructions[ $line ] = '# ' . $text;
 140      }
 141  
 142      /**
 143       * Filters the inline instructions inserted before the dynamically generated content.
 144       *
 145       * @since 5.3.0
 146       *
 147       * @param string[] $instructions Array of lines with inline instructions.
 148       * @param string   $marker       The marker being inserted.
 149       */
 150      $instructions = apply_filters( 'insert_with_markers_inline_instructions', $instructions, $marker );
 151  
 152      if ( $switched_locale ) {
 153          restore_previous_locale();
 154      }
 155  
 156      $insertion = array_merge( $instructions, $insertion );
 157  
 158      $start_marker = "# BEGIN {$marker}";
 159      $end_marker   = "# END {$marker}";
 160  
 161      $fp = fopen( $filename, 'r+' );
 162      if ( ! $fp ) {
 163          return false;
 164      }
 165  
 166      // Attempt to get a lock. If the filesystem supports locking, this will block until the lock is acquired.
 167      flock( $fp, LOCK_EX );
 168  
 169      $lines = array();
 170      while ( ! feof( $fp ) ) {
 171          $lines[] = rtrim( fgets( $fp ), "\r\n" );
 172      }
 173  
 174      // Split out the existing file into the preceding lines, and those that appear after the marker
 175      $pre_lines        = array();
 176      $post_lines       = array();
 177      $existing_lines   = array();
 178      $found_marker     = false;
 179      $found_end_marker = false;
 180      foreach ( $lines as $line ) {
 181          if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) {
 182              $found_marker = true;
 183              continue;
 184          } elseif ( ! $found_end_marker && false !== strpos( $line, $end_marker ) ) {
 185              $found_end_marker = true;
 186              continue;
 187          }
 188          if ( ! $found_marker ) {
 189              $pre_lines[] = $line;
 190          } elseif ( $found_marker && $found_end_marker ) {
 191              $post_lines[] = $line;
 192          } else {
 193              $existing_lines[] = $line;
 194          }
 195      }
 196  
 197      // Check to see if there was a change
 198      if ( $existing_lines === $insertion ) {
 199          flock( $fp, LOCK_UN );
 200          fclose( $fp );
 201  
 202          return true;
 203      }
 204  
 205      // Generate the new file data
 206      $new_file_data = implode(
 207          "\n",
 208          array_merge(
 209              $pre_lines,
 210              array( $start_marker ),
 211              $insertion,
 212              array( $end_marker ),
 213              $post_lines
 214          )
 215      );
 216  
 217      // Write to the start of the file, and truncate it to that length
 218      fseek( $fp, 0 );
 219      $bytes = fwrite( $fp, $new_file_data );
 220      if ( $bytes ) {
 221          ftruncate( $fp, ftell( $fp ) );
 222      }
 223      fflush( $fp );
 224      flock( $fp, LOCK_UN );
 225      fclose( $fp );
 226  
 227      return (bool) $bytes;
 228  }
 229  
 230  /**
 231   * Updates the htaccess file with the current rules if it is writable.
 232   *
 233   * Always writes to the file if it exists and is writable to ensure that we
 234   * blank out old rules.
 235   *
 236   * @since 1.5.0
 237   *
 238   * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
 239   *
 240   * @return bool|null True on write success, false on failure. Null in multisite.
 241   */
 242  function save_mod_rewrite_rules() {
 243      if ( is_multisite() ) {
 244          return;
 245      }
 246  
 247      global $wp_rewrite;
 248  
 249      // Ensure get_home_path() is declared.
 250      require_once ( ABSPATH . 'wp-admin/includes/file.php' );
 251  
 252      $home_path     = get_home_path();
 253      $htaccess_file = $home_path . '.htaccess';
 254  
 255      /*
 256       * If the file doesn't already exist check for write access to the directory
 257       * and whether we have some rules. Else check for write access to the file.
 258       */
 259      if ( ( ! file_exists( $htaccess_file ) && is_writable( $home_path ) && $wp_rewrite->using_mod_rewrite_permalinks() ) || is_writable( $htaccess_file ) ) {
 260          if ( got_mod_rewrite() ) {
 261              $rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() );
 262              return insert_with_markers( $htaccess_file, 'WordPress', $rules );
 263          }
 264      }
 265  
 266      return false;
 267  }
 268  
 269  /**
 270   * Updates the IIS web.config file with the current rules if it is writable.
 271   * If the permalinks do not require rewrite rules then the rules are deleted from the web.config file.
 272   *
 273   * @since 2.8.0
 274   *
 275   * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
 276   *
 277   * @return bool|null True on write success, false on failure. Null in multisite.
 278   */
 279  function iis7_save_url_rewrite_rules() {
 280      if ( is_multisite() ) {
 281          return;
 282      }
 283  
 284      global $wp_rewrite;
 285  
 286      // Ensure get_home_path() is declared.
 287      require_once ( ABSPATH . 'wp-admin/includes/file.php' );
 288  
 289      $home_path       = get_home_path();
 290      $web_config_file = $home_path . 'web.config';
 291  
 292      // Using win_is_writable() instead of is_writable() because of a bug in Windows PHP
 293      if ( iis7_supports_permalinks() && ( ( ! file_exists( $web_config_file ) && win_is_writable( $home_path ) && $wp_rewrite->using_mod_rewrite_permalinks() ) || win_is_writable( $web_config_file ) ) ) {
 294          $rule = $wp_rewrite->iis7_url_rewrite_rules( false );
 295          if ( ! empty( $rule ) ) {
 296              return iis7_add_rewrite_rule( $web_config_file, $rule );
 297          } else {
 298              return iis7_delete_rewrite_rule( $web_config_file );
 299          }
 300      }
 301      return false;
 302  }
 303  
 304  /**
 305   * Update the "recently-edited" file for the plugin or theme editor.
 306   *
 307   * @since 1.5.0
 308   *
 309   * @param string $file
 310   */
 311  function update_recently_edited( $file ) {
 312      $oldfiles = (array) get_option( 'recently_edited' );
 313      if ( $oldfiles ) {
 314          $oldfiles   = array_reverse( $oldfiles );
 315          $oldfiles[] = $file;
 316          $oldfiles   = array_reverse( $oldfiles );
 317          $oldfiles   = array_unique( $oldfiles );
 318          if ( 5 < count( $oldfiles ) ) {
 319              array_pop( $oldfiles );
 320          }
 321      } else {
 322          $oldfiles[] = $file;
 323      }
 324      update_option( 'recently_edited', $oldfiles );
 325  }
 326  
 327  /**
 328   * Makes a tree structure for the theme editor's file list.
 329   *
 330   * @since 4.9.0
 331   * @access private
 332   *
 333   * @param array $allowed_files List of theme file paths.
 334   * @return array Tree structure for listing theme files.
 335   */
 336  function wp_make_theme_file_tree( $allowed_files ) {
 337      $tree_list = array();
 338      foreach ( $allowed_files as $file_name => $absolute_filename ) {
 339          $list     = explode( '/', $file_name );
 340          $last_dir = &$tree_list;
 341          foreach ( $list as $dir ) {
 342              $last_dir =& $last_dir[ $dir ];
 343          }
 344          $last_dir = $file_name;
 345      }
 346      return $tree_list;
 347  }
 348  
 349  /**
 350   * Outputs the formatted file list for the theme editor.
 351   *
 352   * @since 4.9.0
 353   * @access private
 354   *
 355   * @global string $relative_file Name of the file being edited relative to the
 356   *                               theme directory.
 357   * @global string $stylesheet    The stylesheet name of the theme being edited.
 358   *
 359   * @param array|string $tree  List of file/folder paths, or filename.
 360   * @param int          $level The aria-level for the current iteration.
 361   * @param int          $size  The aria-setsize for the current iteration.
 362   * @param int          $index The aria-posinset for the current iteration.
 363   */
 364  function wp_print_theme_file_tree( $tree, $level = 2, $size = 1, $index = 1 ) {
 365      global $relative_file, $stylesheet;
 366  
 367      if ( is_array( $tree ) ) {
 368          $index = 0;
 369          $size  = count( $tree );
 370          foreach ( $tree as $label => $theme_file ) :
 371              $index++;
 372              if ( ! is_array( $theme_file ) ) {
 373                  wp_print_theme_file_tree( $theme_file, $level, $index, $size );
 374                  continue;
 375              }
 376              ?>
 377              <li role="treeitem" aria-expanded="true" tabindex="-1"
 378                  aria-level="<?php echo esc_attr( $level ); ?>"
 379                  aria-setsize="<?php echo esc_attr( $size ); ?>"
 380                  aria-posinset="<?php echo esc_attr( $index ); ?>">
 381                  <span class="folder-label"><?php echo esc_html( $label ); ?> <span class="screen-reader-text"><?php _e( 'folder' ); ?></span><span aria-hidden="true" class="icon"></span></span>
 382                  <ul role="group" class="tree-folder"><?php wp_print_theme_file_tree( $theme_file, $level + 1, $index, $size ); ?></ul>
 383              </li>
 384              <?php
 385          endforeach;
 386      } else {
 387          $filename = $tree;
 388          $url      = add_query_arg(
 389              array(
 390                  'file'  => rawurlencode( $tree ),
 391                  'theme' => rawurlencode( $stylesheet ),
 392              ),
 393              self_admin_url( 'theme-editor.php' )
 394          );
 395          ?>
 396          <li role="none" class="<?php echo esc_attr( $relative_file === $filename ? 'current-file' : '' ); ?>">
 397              <a role="treeitem" tabindex="<?php echo esc_attr( $relative_file === $filename ? '0' : '-1' ); ?>"
 398                  href="<?php echo esc_url( $url ); ?>"
 399                  aria-level="<?php echo esc_attr( $level ); ?>"
 400                  aria-setsize="<?php echo esc_attr( $size ); ?>"
 401                  aria-posinset="<?php echo esc_attr( $index ); ?>">
 402                  <?php
 403                  $file_description = esc_html( get_file_description( $filename ) );
 404                  if ( $file_description !== $filename && wp_basename( $filename ) !== $file_description ) {
 405                      $file_description .= '<br /><span class="nonessential">(' . esc_html( $filename ) . ')</span>';
 406                  }
 407  
 408                  if ( $relative_file === $filename ) {
 409                      echo '<span class="notice notice-info">' . $file_description . '</span>';
 410                  } else {
 411                      echo $file_description;
 412                  }
 413                  ?>
 414              </a>
 415          </li>
 416          <?php
 417      }
 418  }
 419  
 420  /**
 421   * Makes a tree structure for the plugin editor's file list.
 422   *
 423   * @since 4.9.0
 424   * @access private
 425   *
 426   * @param array $plugin_editable_files List of plugin file paths.
 427   * @return array Tree structure for listing plugin files.
 428   */
 429  function wp_make_plugin_file_tree( $plugin_editable_files ) {
 430      $tree_list = array();
 431      foreach ( $plugin_editable_files as $plugin_file ) {
 432          $list     = explode( '/', preg_replace( '#^.+?/#', '', $plugin_file ) );
 433          $last_dir = &$tree_list;
 434          foreach ( $list as $dir ) {
 435              $last_dir =& $last_dir[ $dir ];
 436          }
 437          $last_dir = $plugin_file;
 438      }
 439      return $tree_list;
 440  }
 441  
 442  /**
 443   * Outputs the formatted file list for the plugin editor.
 444   *
 445   * @since 4.9.0
 446   * @access private
 447   *
 448   * @param array|string $tree  List of file/folder paths, or filename.
 449   * @param string       $label Name of file or folder to print.
 450   * @param int          $level The aria-level for the current iteration.
 451   * @param int          $size  The aria-setsize for the current iteration.
 452   * @param int          $index The aria-posinset for the current iteration.
 453   */
 454  function wp_print_plugin_file_tree( $tree, $label = '', $level = 2, $size = 1, $index = 1 ) {
 455      global $file, $plugin;
 456      if ( is_array( $tree ) ) {
 457          $index = 0;
 458          $size  = count( $tree );
 459          foreach ( $tree as $label => $plugin_file ) :
 460              $index++;
 461              if ( ! is_array( $plugin_file ) ) {
 462                  wp_print_plugin_file_tree( $plugin_file, $label, $level, $index, $size );
 463                  continue;
 464              }
 465              ?>
 466              <li role="treeitem" aria-expanded="true" tabindex="-1"
 467                  aria-level="<?php echo esc_attr( $level ); ?>"
 468                  aria-setsize="<?php echo esc_attr( $size ); ?>"
 469                  aria-posinset="<?php echo esc_attr( $index ); ?>">
 470                  <span class="folder-label"><?php echo esc_html( $label ); ?> <span class="screen-reader-text"><?php _e( 'folder' ); ?></span><span aria-hidden="true" class="icon"></span></span>
 471                  <ul role="group" class="tree-folder"><?php wp_print_plugin_file_tree( $plugin_file, '', $level + 1, $index, $size ); ?></ul>
 472              </li>
 473              <?php
 474          endforeach;
 475      } else {
 476          $url = add_query_arg(
 477              array(
 478                  'file'   => rawurlencode( $tree ),
 479                  'plugin' => rawurlencode( $plugin ),
 480              ),
 481              self_admin_url( 'plugin-editor.php' )
 482          );
 483          ?>
 484          <li role="none" class="<?php echo esc_attr( $file === $tree ? 'current-file' : '' ); ?>">
 485              <a role="treeitem" tabindex="<?php echo esc_attr( $file === $tree ? '0' : '-1' ); ?>"
 486                  href="<?php echo esc_url( $url ); ?>"
 487                  aria-level="<?php echo esc_attr( $level ); ?>"
 488                  aria-setsize="<?php echo esc_attr( $size ); ?>"
 489                  aria-posinset="<?php echo esc_attr( $index ); ?>">
 490                  <?php
 491                  if ( $file === $tree ) {
 492                      echo '<span class="notice notice-info">' . esc_html( $label ) . '</span>';
 493                  } else {
 494                      echo esc_html( $label );
 495                  }
 496                  ?>
 497              </a>
 498          </li>
 499          <?php
 500      }
 501  }
 502  
 503  /**
 504   * Flushes rewrite rules if siteurl, home or page_on_front changed.
 505   *
 506   * @since 2.1.0
 507   *
 508   * @param string $old_value
 509   * @param string $value
 510   */
 511  function update_home_siteurl( $old_value, $value ) {
 512      if ( wp_installing() ) {
 513          return;
 514      }
 515  
 516      if ( is_multisite() && ms_is_switched() ) {
 517          delete_option( 'rewrite_rules' );
 518      } else {
 519          flush_rewrite_rules();
 520      }
 521  }
 522  
 523  
 524  /**
 525   * Resets global variables based on $_GET and $_POST
 526   *
 527   * This function resets global variables based on the names passed
 528   * in the $vars array to the value of $_POST[$var] or $_GET[$var] or ''
 529   * if neither is defined.
 530   *
 531   * @since 2.0.0
 532   *
 533   * @param array $vars An array of globals to reset.
 534   */
 535  function wp_reset_vars( $vars ) {
 536      foreach ( $vars as $var ) {
 537          if ( empty( $_POST[ $var ] ) ) {
 538              if ( empty( $_GET[ $var ] ) ) {
 539                  $GLOBALS[ $var ] = '';
 540              } else {
 541                  $GLOBALS[ $var ] = $_GET[ $var ];
 542              }
 543          } else {
 544              $GLOBALS[ $var ] = $_POST[ $var ];
 545          }
 546      }
 547  }
 548  
 549  /**
 550   * Displays the given administration message.
 551   *
 552   * @since 2.1.0
 553   *
 554   * @param string|WP_Error $message
 555   */
 556  function show_message( $message ) {
 557      if ( is_wp_error( $message ) ) {
 558          if ( $message->get_error_data() && is_string( $message->get_error_data() ) ) {
 559              $message = $message->get_error_message() . ': ' . $message->get_error_data();
 560          } else {
 561              $message = $message->get_error_message();
 562          }
 563      }
 564      echo "<p>$message</p>\n";
 565      wp_ob_end_flush_all();
 566      flush();
 567  }
 568  
 569  /**
 570   * @since 2.8.0
 571   *
 572   * @param string $content
 573   * @return array
 574   */
 575  function wp_doc_link_parse( $content ) {
 576      if ( ! is_string( $content ) || empty( $content ) ) {
 577          return array();
 578      }
 579  
 580      if ( ! function_exists( 'token_get_all' ) ) {
 581          return array();
 582      }
 583  
 584      $tokens           = token_get_all( $content );
 585      $count            = count( $tokens );
 586      $functions        = array();
 587      $ignore_functions = array();
 588      for ( $t = 0; $t < $count - 2; $t++ ) {
 589          if ( ! is_array( $tokens[ $t ] ) ) {
 590              continue;
 591          }
 592  
 593          if ( T_STRING == $tokens[ $t ][0] && ( '(' == $tokens[ $t + 1 ] || '(' == $tokens[ $t + 2 ] ) ) {
 594              // If it's a function or class defined locally, there's not going to be any docs available
 595              if ( ( isset( $tokens[ $t - 2 ][1] ) && in_array( $tokens[ $t - 2 ][1], array( 'function', 'class' ) ) ) || ( isset( $tokens[ $t - 2 ][0] ) && T_OBJECT_OPERATOR == $tokens[ $t - 1 ][0] ) ) {
 596                  $ignore_functions[] = $tokens[ $t ][1];
 597              }
 598              // Add this to our stack of unique references
 599              $functions[] = $tokens[ $t ][1];
 600          }
 601      }
 602  
 603      $functions = array_unique( $functions );
 604      sort( $functions );
 605  
 606      /**
 607       * Filters the list of functions and classes to be ignored from the documentation lookup.
 608       *
 609       * @since 2.8.0
 610       *
 611       * @param string[] $ignore_functions Array of names of functions and classes to be ignored.
 612       */
 613      $ignore_functions = apply_filters( 'documentation_ignore_functions', $ignore_functions );
 614  
 615      $ignore_functions = array_unique( $ignore_functions );
 616  
 617      $out = array();
 618      foreach ( $functions as $function ) {
 619          if ( in_array( $function, $ignore_functions ) ) {
 620              continue;
 621          }
 622          $out[] = $function;
 623      }
 624  
 625      return $out;
 626  }
 627  
 628  /**
 629   * Saves option for number of rows when listing posts, pages, comments, etc.
 630   *
 631   * @since 2.8.0
 632   */
 633  function set_screen_options() {
 634  
 635      if ( isset( $_POST['wp_screen_options'] ) && is_array( $_POST['wp_screen_options'] ) ) {
 636          check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
 637  
 638          $user = wp_get_current_user();
 639          if ( ! $user ) {
 640              return;
 641          }
 642          $option = $_POST['wp_screen_options']['option'];
 643          $value  = $_POST['wp_screen_options']['value'];
 644  
 645          if ( $option != sanitize_key( $option ) ) {
 646              return;
 647          }
 648  
 649          $map_option = $option;
 650          $type       = str_replace( 'edit_', '', $map_option );
 651          $type       = str_replace( '_per_page', '', $type );
 652          if ( in_array( $type, get_taxonomies() ) ) {
 653              $map_option = 'edit_tags_per_page';
 654          } elseif ( in_array( $type, get_post_types() ) ) {
 655              $map_option = 'edit_per_page';
 656          } else {
 657              $option = str_replace( '-', '_', $option );
 658          }
 659  
 660          switch ( $map_option ) {
 661              case 'edit_per_page':
 662              case 'users_per_page':
 663              case 'edit_comments_per_page':
 664              case 'upload_per_page':
 665              case 'edit_tags_per_page':
 666              case 'plugins_per_page':
 667              case 'export_personal_data_requests_per_page':
 668              case 'remove_personal_data_requests_per_page':
 669                  // Network admin
 670              case 'sites_network_per_page':
 671              case 'users_network_per_page':
 672              case 'site_users_network_per_page':
 673              case 'plugins_network_per_page':
 674              case 'themes_network_per_page':
 675              case 'site_themes_network_per_page':
 676                  $value = (int) $value;
 677                  if ( $value < 1 || $value > 999 ) {
 678                      return;
 679                  }
 680                  break;
 681              default:
 682                  /**
 683                   * Filters a screen option value before it is set.
 684                   *
 685                   * The filter can also be used to modify non-standard [items]_per_page
 686                   * settings. See the parent function for a full list of standard options.
 687                   *
 688                   * Returning false to the filter will skip saving the current option.
 689                   *
 690                   * @since 2.8.0
 691                   *
 692                   * @see set_screen_options()
 693                   *
 694                   * @param bool     $keep   Whether to save or skip saving the screen option value. Default false.
 695                   * @param string   $option The option name.
 696                   * @param int      $value  The number of rows to use.
 697                   */
 698                  $value = apply_filters( 'set-screen-option', false, $option, $value );  // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
 699  
 700                  if ( false === $value ) {
 701                      return;
 702                  }
 703                  break;
 704          }
 705  
 706          update_user_meta( $user->ID, $option, $value );
 707  
 708          $url = remove_query_arg( array( 'pagenum', 'apage', 'paged' ), wp_get_referer() );
 709          if ( isset( $_POST['mode'] ) ) {
 710              $url = add_query_arg( array( 'mode' => $_POST['mode'] ), $url );
 711          }
 712  
 713          wp_safe_redirect( $url );
 714          exit;
 715      }
 716  }
 717  
 718  /**
 719   * Check if rewrite rule for WordPress already exists in the IIS 7+ configuration file
 720   *
 721   * @since 2.8.0
 722   *
 723   * @return bool
 724   * @param string $filename The file path to the configuration file
 725   */
 726  function iis7_rewrite_rule_exists( $filename ) {
 727      if ( ! file_exists( $filename ) ) {
 728          return false;
 729      }
 730      if ( ! class_exists( 'DOMDocument', false ) ) {
 731          return false;
 732      }
 733  
 734      $doc = new DOMDocument();
 735      if ( $doc->load( $filename ) === false ) {
 736          return false;
 737      }
 738      $xpath = new DOMXPath( $doc );
 739      $rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' );
 740      if ( $rules->length == 0 ) {
 741          return false;
 742      } else {
 743          return true;
 744      }
 745  }
 746  
 747  /**
 748   * Delete WordPress rewrite rule from web.config file if it exists there
 749   *
 750   * @since 2.8.0
 751   *
 752   * @param string $filename Name of the configuration file
 753   * @return bool
 754   */
 755  function iis7_delete_rewrite_rule( $filename ) {
 756      // If configuration file does not exist then rules also do not exist so there is nothing to delete
 757      if ( ! file_exists( $filename ) ) {
 758          return true;
 759      }
 760  
 761      if ( ! class_exists( 'DOMDocument', false ) ) {
 762          return false;
 763      }
 764  
 765      $doc                     = new DOMDocument();
 766      $doc->preserveWhiteSpace = false;
 767  
 768      if ( $doc->load( $filename ) === false ) {
 769          return false;
 770      }
 771      $xpath = new DOMXPath( $doc );
 772      $rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' );
 773      if ( $rules->length > 0 ) {
 774          $child  = $rules->item( 0 );
 775          $parent = $child->parentNode;
 776          $parent->removeChild( $child );
 777          $doc->formatOutput = true;
 778          saveDomDocument( $doc, $filename );
 779      }
 780      return true;
 781  }
 782  
 783  /**
 784   * Add WordPress rewrite rule to the IIS 7+ configuration file.
 785   *
 786   * @since 2.8.0
 787   *
 788   * @param string $filename The file path to the configuration file
 789   * @param string $rewrite_rule The XML fragment with URL Rewrite rule
 790   * @return bool
 791   */
 792  function iis7_add_rewrite_rule( $filename, $rewrite_rule ) {
 793      if ( ! class_exists( 'DOMDocument', false ) ) {
 794          return false;
 795      }
 796  
 797      // If configuration file does not exist then we create one.
 798      if ( ! file_exists( $filename ) ) {
 799          $fp = fopen( $filename, 'w' );
 800          fwrite( $fp, '<configuration/>' );
 801          fclose( $fp );
 802      }
 803  
 804      $doc                     = new DOMDocument();
 805      $doc->preserveWhiteSpace = false;
 806  
 807      if ( $doc->load( $filename ) === false ) {
 808          return false;
 809      }
 810  
 811      $xpath = new DOMXPath( $doc );
 812  
 813      // First check if the rule already exists as in that case there is no need to re-add it
 814      $wordpress_rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' );
 815      if ( $wordpress_rules->length > 0 ) {
 816          return true;
 817      }
 818  
 819      // Check the XPath to the rewrite rule and create XML nodes if they do not exist
 820      $xmlnodes = $xpath->query( '/configuration/system.webServer/rewrite/rules' );
 821      if ( $xmlnodes->length > 0 ) {
 822          $rules_node = $xmlnodes->item( 0 );
 823      } else {
 824          $rules_node = $doc->createElement( 'rules' );
 825  
 826          $xmlnodes = $xpath->query( '/configuration/system.webServer/rewrite' );
 827          if ( $xmlnodes->length > 0 ) {
 828              $rewrite_node = $xmlnodes->item( 0 );
 829              $rewrite_node->appendChild( $rules_node );
 830          } else {
 831              $rewrite_node = $doc->createElement( 'rewrite' );
 832              $rewrite_node->appendChild( $rules_node );
 833  
 834              $xmlnodes = $xpath->query( '/configuration/system.webServer' );
 835              if ( $xmlnodes->length > 0 ) {
 836                  $system_webServer_node = $xmlnodes->item( 0 );
 837                  $system_webServer_node->appendChild( $rewrite_node );
 838              } else {
 839                  $system_webServer_node = $doc->createElement( 'system.webServer' );
 840                  $system_webServer_node->appendChild( $rewrite_node );
 841  
 842                  $xmlnodes = $xpath->query( '/configuration' );
 843                  if ( $xmlnodes->length > 0 ) {
 844                      $config_node = $xmlnodes->item( 0 );
 845                      $config_node->appendChild( $system_webServer_node );
 846                  } else {
 847                      $config_node = $doc->createElement( 'configuration' );
 848                      $doc->appendChild( $config_node );
 849                      $config_node->appendChild( $system_webServer_node );
 850                  }
 851              }
 852          }
 853      }
 854  
 855      $rule_fragment = $doc->createDocumentFragment();
 856      $rule_fragment->appendXML( $rewrite_rule );
 857      $rules_node->appendChild( $rule_fragment );
 858  
 859      $doc->encoding     = 'UTF-8';
 860      $doc->formatOutput = true;
 861      saveDomDocument( $doc, $filename );
 862  
 863      return true;
 864  }
 865  
 866  /**
 867   * Saves the XML document into a file
 868   *
 869   * @since 2.8.0
 870   *
 871   * @param DOMDocument $doc
 872   * @param string $filename
 873   */
 874  function saveDomDocument( $doc, $filename ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
 875      $config = $doc->saveXML();
 876      $config = preg_replace( "/([^\r])\n/", "$1\r\n", $config );
 877      $fp     = fopen( $filename, 'w' );
 878      fwrite( $fp, $config );
 879      fclose( $fp );
 880  }
 881  
 882  /**
 883   * Display the default admin color scheme picker (Used in user-edit.php)
 884   *
 885   * @since 3.0.0
 886   *
 887   * @global array $_wp_admin_css_colors
 888   *
 889   * @param int $user_id User ID.
 890   */
 891  function admin_color_scheme_picker( $user_id ) {
 892      global $_wp_admin_css_colors;
 893  
 894      ksort( $_wp_admin_css_colors );
 895  
 896      if ( isset( $_wp_admin_css_colors['fresh'] ) ) {
 897          // Set Default ('fresh') and Light should go first.
 898          $_wp_admin_css_colors = array_filter(
 899              array_merge(
 900                  array(
 901                      'fresh' => '',
 902                      'light' => '',
 903                  ),
 904                  $_wp_admin_css_colors
 905              )
 906          );
 907      }
 908  
 909      $current_color = get_user_option( 'admin_color', $user_id );
 910  
 911      if ( empty( $current_color ) || ! isset( $_wp_admin_css_colors[ $current_color ] ) ) {
 912          $current_color = 'fresh';
 913      }
 914  
 915      ?>
 916      <fieldset id="color-picker" class="scheme-list">
 917          <legend class="screen-reader-text"><span><?php _e( 'Admin Color Scheme' ); ?></span></legend>
 918          <?php
 919          wp_nonce_field( 'save-color-scheme', 'color-nonce', false );
 920          foreach ( $_wp_admin_css_colors as $color => $color_info ) :
 921  
 922              ?>
 923              <div class="color-option <?php echo ( $color == $current_color ) ? 'selected' : ''; ?>">
 924                  <input name="admin_color" id="admin_color_<?php echo esc_attr( $color ); ?>" type="radio" value="<?php echo esc_attr( $color ); ?>" class="tog" <?php checked( $color, $current_color ); ?> />
 925                  <input type="hidden" class="css_url" value="<?php echo esc_url( $color_info->url ); ?>" />
 926                  <input type="hidden" class="icon_colors" value="<?php echo esc_attr( wp_json_encode( array( 'icons' => $color_info->icon_colors ) ) ); ?>" />
 927                  <label for="admin_color_<?php echo esc_attr( $color ); ?>"><?php echo esc_html( $color_info->name ); ?></label>
 928                  <table class="color-palette">
 929                      <tr>
 930                      <?php
 931  
 932                      foreach ( $color_info->colors as $html_color ) {
 933                          ?>
 934                          <td style="background-color: <?php echo esc_attr( $html_color ); ?>">&nbsp;</td>
 935                          <?php
 936                      }
 937  
 938                      ?>
 939                      </tr>
 940                  </table>
 941              </div>
 942              <?php
 943  
 944          endforeach;
 945  
 946          ?>
 947      </fieldset>
 948      <?php
 949  }
 950  
 951  /**
 952   *
 953   * @global array $_wp_admin_css_colors
 954   */
 955  function wp_color_scheme_settings() {
 956      global $_wp_admin_css_colors;
 957  
 958      $color_scheme = get_user_option( 'admin_color' );
 959  
 960      // It's possible to have a color scheme set that is no longer registered.
 961      if ( empty( $_wp_admin_css_colors[ $color_scheme ] ) ) {
 962          $color_scheme = 'fresh';
 963      }
 964  
 965      if ( ! empty( $_wp_admin_css_colors[ $color_scheme ]->icon_colors ) ) {
 966          $icon_colors = $_wp_admin_css_colors[ $color_scheme ]->icon_colors;
 967      } elseif ( ! empty( $_wp_admin_css_colors['fresh']->icon_colors ) ) {
 968          $icon_colors = $_wp_admin_css_colors['fresh']->icon_colors;
 969      } else {
 970          // Fall back to the default set of icon colors if the default scheme is missing.
 971          $icon_colors = array(
 972              'base'    => '#a0a5aa',
 973              'focus'   => '#00a0d2',
 974              'current' => '#fff',
 975          );
 976      }
 977  
 978      echo '<script type="text/javascript">var _wpColorScheme = ' . wp_json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n";
 979  }
 980  
 981  /**
 982   * @since 3.3.0
 983   */
 984  function _ipad_meta() {
 985      if ( wp_is_mobile() ) {
 986          ?>
 987          <meta name="viewport" id="viewport-meta" content="width=device-width, initial-scale=1">
 988          <?php
 989      }
 990  }
 991  
 992  /**
 993   * Check lock status for posts displayed on the Posts screen
 994   *
 995   * @since 3.6.0
 996   *
 997   * @param array  $response  The Heartbeat response.
 998   * @param array  $data      The $_POST data sent.
 999   * @param string $screen_id The screen id.
1000   * @return array The Heartbeat response.
1001   */
1002  function wp_check_locked_posts( $response, $data, $screen_id ) {
1003      $checked = array();
1004  
1005      if ( array_key_exists( 'wp-check-locked-posts', $data ) && is_array( $data['wp-check-locked-posts'] ) ) {
1006          foreach ( $data['wp-check-locked-posts'] as $key ) {
1007              $post_id = absint( substr( $key, 5 ) );
1008              if ( ! $post_id ) {
1009                  continue;
1010              }
1011  
1012              $user_id = wp_check_post_lock( $post_id );
1013              if ( $user_id ) {
1014                  $user = get_userdata( $user_id );
1015                  if ( $user && current_user_can( 'edit_post', $post_id ) ) {
1016                      $send = array( 'text' => sprintf( __( '%s is currently editing' ), $user->display_name ) );
1017  
1018                      $avatar = get_avatar( $user->ID, 18 );
1019                      if ( $avatar && preg_match( "|src='([^']+)'|", $avatar, $matches ) ) {
1020                          $send['avatar_src'] = $matches[1];
1021                      }
1022  
1023                      $checked[ $key ] = $send;
1024                  }
1025              }
1026          }
1027      }
1028  
1029      if ( ! empty( $checked ) ) {
1030          $response['wp-check-locked-posts'] = $checked;
1031      }
1032  
1033      return $response;
1034  }
1035  
1036  /**
1037   * Check lock status on the New/Edit Post screen and refresh the lock
1038   *
1039   * @since 3.6.0
1040   *
1041   * @param array  $response  The Heartbeat response.
1042   * @param array  $data      The $_POST data sent.
1043   * @param string $screen_id The screen id.
1044   * @return array The Heartbeat response.
1045   */
1046  function wp_refresh_post_lock( $response, $data, $screen_id ) {
1047      if ( array_key_exists( 'wp-refresh-post-lock', $data ) ) {
1048          $received = $data['wp-refresh-post-lock'];
1049          $send     = array();
1050  
1051          $post_id = absint( $received['post_id'] );
1052          if ( ! $post_id ) {
1053              return $response;
1054          }
1055  
1056          if ( ! current_user_can( 'edit_post', $post_id ) ) {
1057              return $response;
1058          }
1059  
1060          $user_id = wp_check_post_lock( $post_id );
1061          $user    = get_userdata( $user_id );
1062          if ( $user ) {
1063              $error = array(
1064                  'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name ),
1065              );
1066  
1067              $avatar = get_avatar( $user->ID, 64 );
1068              if ( $avatar ) {
1069                  if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) {
1070                      $error['avatar_src'] = $matches[1];
1071                  }
1072              }
1073  
1074              $send['lock_error'] = $error;
1075          } else {
1076              $new_lock = wp_set_post_lock( $post_id );
1077              if ( $new_lock ) {
1078                  $send['new_lock'] = implode( ':', $new_lock );
1079              }
1080          }
1081  
1082          $response['wp-refresh-post-lock'] = $send;
1083      }
1084  
1085      return $response;
1086  }
1087  
1088  /**
1089   * Check nonce expiration on the New/Edit Post screen and refresh if needed
1090   *
1091   * @since 3.6.0
1092   *
1093   * @param array  $response  The Heartbeat response.
1094   * @param array  $data      The $_POST data sent.
1095   * @param string $screen_id The screen id.
1096   * @return array The Heartbeat response.
1097   */
1098  function wp_refresh_post_nonces( $response, $data, $screen_id ) {
1099      if ( array_key_exists( 'wp-refresh-post-nonces', $data ) ) {
1100          $received                           = $data['wp-refresh-post-nonces'];
1101          $response['wp-refresh-post-nonces'] = array( 'check' => 1 );
1102  
1103          $post_id = absint( $received['post_id'] );
1104          if ( ! $post_id ) {
1105              return $response;
1106          }
1107  
1108          if ( ! current_user_can( 'edit_post', $post_id ) ) {
1109              return $response;
1110          }
1111  
1112          $response['wp-refresh-post-nonces'] = array(
1113              'replace' => array(
1114                  'getpermalinknonce'    => wp_create_nonce( 'getpermalink' ),
1115                  'samplepermalinknonce' => wp_create_nonce( 'samplepermalink' ),
1116                  'closedpostboxesnonce' => wp_create_nonce( 'closedpostboxes' ),
1117                  '_ajax_linking_nonce'  => wp_create_nonce( 'internal-linking' ),
1118                  '_wpnonce'             => wp_create_nonce( 'update-post_' . $post_id ),
1119              ),
1120          );
1121      }
1122  
1123      return $response;
1124  }
1125  
1126  /**
1127   * Add the latest Heartbeat and REST-API nonce to the Heartbeat response.
1128   *
1129   * @since 5.0.0
1130   *
1131   * @param array  $response  The Heartbeat response.
1132   * @return array The Heartbeat response.
1133   */
1134  function wp_refresh_heartbeat_nonces( $response ) {
1135      // Refresh the Rest API nonce.
1136      $response['rest_nonce'] = wp_create_nonce( 'wp_rest' );
1137  
1138      // Refresh the Heartbeat nonce.
1139      $response['heartbeat_nonce'] = wp_create_nonce( 'heartbeat-nonce' );
1140      return $response;
1141  }
1142  
1143  /**
1144   * Disable suspension of Heartbeat on the Add/Edit Post screens.
1145   *
1146   * @since 3.8.0
1147   *
1148   * @global string $pagenow
1149   *
1150   * @param array $settings An array of Heartbeat settings.
1151   * @return array Filtered Heartbeat settings.
1152   */
1153  function wp_heartbeat_set_suspension( $settings ) {
1154      global $pagenow;
1155  
1156      if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
1157          $settings['suspension'] = 'disable';
1158      }
1159  
1160      return $settings;
1161  }
1162  
1163  /**
1164   * Autosave with heartbeat
1165   *
1166   * @since 3.9.0
1167   *
1168   * @param array $response The Heartbeat response.
1169   * @param array $data     The $_POST data sent.
1170   * @return array The Heartbeat response.
1171   */
1172  function heartbeat_autosave( $response, $data ) {
1173      if ( ! empty( $data['wp_autosave'] ) ) {
1174          $saved = wp_autosave( $data['wp_autosave'] );
1175  
1176          if ( is_wp_error( $saved ) ) {
1177              $response['wp_autosave'] = array(
1178                  'success' => false,
1179                  'message' => $saved->get_error_message(),
1180              );
1181          } elseif ( empty( $saved ) ) {
1182              $response['wp_autosave'] = array(
1183                  'success' => false,
1184                  'message' => __( 'Error while saving.' ),
1185              );
1186          } else {
1187              /* translators: draft saved date format, see https://secure.php.net/date */
1188              $draft_saved_date_format = __( 'g:i:s a' );
1189              /* translators: %s: date and time */
1190              $response['wp_autosave'] = array(
1191                  'success' => true,
1192                  'message' => sprintf( __( 'Draft saved at %s.' ), date_i18n( $draft_saved_date_format ) ),
1193              );
1194          }
1195      }
1196  
1197      return $response;
1198  }
1199  
1200  /**
1201   * Remove single-use URL parameters and create canonical link based on new URL.
1202   *
1203   * Remove specific query string parameters from a URL, create the canonical link,
1204   * put it in the admin header, and change the current URL to match.
1205   *
1206   * @since 4.2.0
1207   */
1208  function wp_admin_canonical_url() {
1209      $removable_query_args = wp_removable_query_args();
1210  
1211      if ( empty( $removable_query_args ) ) {
1212          return;
1213      }
1214  
1215      // Ensure we're using an absolute URL.
1216      $current_url  = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
1217      $filtered_url = remove_query_arg( $removable_query_args, $current_url );
1218      ?>
1219      <link id="wp-admin-canonical" rel="canonical" href="<?php echo esc_url( $filtered_url ); ?>" />
1220      <script>
1221          if ( window.history.replaceState ) {
1222              window.history.replaceState( null, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash );
1223          }
1224      </script>
1225      <?php
1226  }
1227  
1228  /**
1229   * Send a referrer policy header so referrers are not sent externally from administration screens.
1230   *
1231   * @since 4.9.0
1232   */
1233  function wp_admin_headers() {
1234      $policy = 'strict-origin-when-cross-origin';
1235  
1236      /**
1237       * Filters the admin referrer policy header value.
1238       *
1239       * @since 4.9.0
1240       * @since 4.9.5 The default value was changed to 'strict-origin-when-cross-origin'.
1241       *
1242       * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
1243       *
1244       * @param string $policy The admin referrer policy header value. Default 'strict-origin-when-cross-origin'.
1245       */
1246      $policy = apply_filters( 'admin_referrer_policy', $policy );
1247  
1248      header( sprintf( 'Referrer-Policy: %s', $policy ) );
1249  }
1250  
1251  /**
1252   * Outputs JS that reloads the page if the user navigated to it with the Back or Forward button.
1253   *
1254   * Used on the Edit Post and Add New Post screens. Needed to ensure the page is not loaded from browser cache,
1255   * so the post title and editor content are the last saved versions. Ideally this script should run first in the head.
1256   *
1257   * @since 4.6.0
1258   */
1259  function wp_page_reload_on_back_button_js() {
1260      ?>
1261      <script>
1262          if ( typeof performance !== 'undefined' && performance.navigation && performance.navigation.type === 2 ) {
1263              document.location.reload( true );
1264          }
1265      </script>
1266      <?php
1267  }
1268  
1269  /**
1270   * Send a confirmation request email when a change of site admin email address is attempted.
1271   *
1272   * The new site admin address will not become active until confirmed.
1273   *
1274   * @since 3.0.0
1275   * @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
1276   *
1277   * @param string $old_value The old site admin email address.
1278   * @param string $value     The proposed new site admin email address.
1279   */
1280  function update_option_new_admin_email( $old_value, $value ) {
1281      if ( $value == get_option( 'admin_email' ) || ! is_email( $value ) ) {
1282          return;
1283      }
1284  
1285      $hash            = md5( $value . time() . wp_rand() );
1286      $new_admin_email = array(
1287          'hash'     => $hash,
1288          'newemail' => $value,
1289      );
1290      update_option( 'adminhash', $new_admin_email );
1291  
1292      $switched_locale = switch_to_locale( get_user_locale() );
1293  
1294      /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
1295      $email_text = __(
1296          'Howdy ###USERNAME###,
1297  
1298  You recently requested to have the administration email address on
1299  your site changed.
1300  
1301  If this is correct, please click on the following link to change it:
1302  ###ADMIN_URL###
1303  
1304  You can safely ignore and delete this email if you do not want to
1305  take this action.
1306  
1307  This email has been sent to ###EMAIL###
1308  
1309  Regards,
1310  All at ###SITENAME###
1311  ###SITEURL###'
1312      );
1313  
1314      /**
1315       * Filters the text of the email sent when a change of site admin email address is attempted.
1316       *
1317       * The following strings have a special meaning and will get replaced dynamically:
1318       * ###USERNAME###  The current user's username.
1319       * ###ADMIN_URL### The link to click on to confirm the email change.
1320       * ###EMAIL###     The proposed new site admin email address.
1321       * ###SITENAME###  The name of the site.
1322       * ###SITEURL###   The URL to the site.
1323       *
1324       * @since MU (3.0.0)
1325       * @since 4.9.0 This filter is no longer Multisite specific.
1326       *
1327       * @param string $email_text      Text in the email.
1328       * @param array  $new_admin_email {
1329       *     Data relating to the new site admin email address.
1330       *
1331       *     @type string $hash     The secure hash used in the confirmation link URL.
1332       *     @type string $newemail The proposed new site admin email address.
1333       * }
1334       */
1335      $content = apply_filters( 'new_admin_email_content', $email_text, $new_admin_email );
1336  
1337      $current_user = wp_get_current_user();
1338      $content      = str_replace( '###USERNAME###', $current_user->user_login, $content );
1339      $content      = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash=' . $hash ) ), $content );
1340      $content      = str_replace( '###EMAIL###', $value, $content );
1341      $content      = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $content );
1342      $content      = str_replace( '###SITEURL###', home_url(), $content );
1343  
1344      /* translators: New admin email address notification email subject. %s: Site title */
1345      wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content );
1346  
1347      if ( $switched_locale ) {
1348          restore_previous_locale();
1349      }
1350  }
1351  
1352  /**
1353   * Appends '(Draft)' to draft page titles in the privacy page dropdown
1354   * so that unpublished content is obvious.
1355   *
1356   * @since 4.9.8
1357   * @access private
1358   *
1359   * @param string  $title Page title.
1360   * @param WP_Post $page  Page data object.
1361   *
1362   * @return string Page title.
1363   */
1364  function _wp_privacy_settings_filter_draft_page_titles( $title, $page ) {
1365      if ( 'draft' === $page->post_status && 'privacy' === get_current_screen()->id ) {
1366          /* translators: %s: Page Title */
1367          $title = sprintf( __( '%s (Draft)' ), $title );
1368      }
1369  
1370      return $title;
1371  }
1372  
1373  /**
1374   * Checks if the user needs to update PHP.
1375   *
1376   * @since 5.1.0
1377   * @since 5.1.1 Added the {@see 'wp_is_php_version_acceptable'} filter.
1378   *
1379   * @return array|false $response Array of PHP version data. False on failure.
1380   */
1381  function wp_check_php_version() {
1382      $version = phpversion();
1383      $key     = md5( $version );
1384  
1385      $response = get_site_transient( 'php_check_' . $key );
1386      if ( false === $response ) {
1387          $url = 'http://api.wordpress.org/core/serve-happy/1.0/';
1388          if ( wp_http_supports( array( 'ssl' ) ) ) {
1389              $url = set_url_scheme( $url, 'https' );
1390          }
1391  
1392          $url = add_query_arg( 'php_version', $version, $url );
1393  
1394          $response = wp_remote_get( $url );
1395  
1396          if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
1397              return false;
1398          }
1399  
1400          /**
1401           * Response should be an array with:
1402           *  'recommended_version' - string - The PHP version recommended by WordPress.
1403           *  'is_supported' - boolean - Whether the PHP version is actively supported.
1404           *  'is_secure' - boolean - Whether the PHP version receives security updates.
1405           *  'is_acceptable' - boolean - Whether the PHP version is still acceptable for WordPress.
1406           */
1407          $response = json_decode( wp_remote_retrieve_body( $response ), true );
1408  
1409          if ( ! is_array( $response ) ) {
1410              return false;
1411          }
1412  
1413          set_site_transient( 'php_check_' . $key, $response, WEEK_IN_SECONDS );
1414      }
1415  
1416      if ( isset( $response['is_acceptable'] ) && $response['is_acceptable'] ) {
1417          /**
1418           * Filters whether the active PHP version is considered acceptable by WordPress.
1419           *
1420           * Returning false will trigger a PHP version warning to show up in the admin dashboard to administrators.
1421           *
1422           * This filter is only run if the wordpress.org Serve Happy API considers the PHP version acceptable, ensuring
1423           * that this filter can only make this check stricter, but not loosen it.
1424           *
1425           * @since 5.1.1
1426           *
1427           * @param bool   $is_acceptable Whether the PHP version is considered acceptable. Default true.
1428           * @param string $version       PHP version checked.
1429           */
1430          $response['is_acceptable'] = (bool) apply_filters( 'wp_is_php_version_acceptable', true, $version );
1431      }
1432  
1433      return $response;
1434  }


Generated: Tue Aug 20 08:20:01 2019 Cross-referenced by PHPXref 0.7