[ Index ]

PHP Cross Reference of WordPress

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(
1017                          /* translators: %s: User's display name. */
1018                          'text' => sprintf( __( '%s is currently editing' ), $user->display_name ),
1019                      );
1020  
1021                      $avatar = get_avatar( $user->ID, 18 );
1022                      if ( $avatar && preg_match( "|src='([^']+)'|", $avatar, $matches ) ) {
1023                          $send['avatar_src'] = $matches[1];
1024                      }
1025  
1026                      $checked[ $key ] = $send;
1027                  }
1028              }
1029          }
1030      }
1031  
1032      if ( ! empty( $checked ) ) {
1033          $response['wp-check-locked-posts'] = $checked;
1034      }
1035  
1036      return $response;
1037  }
1038  
1039  /**
1040   * Check lock status on the New/Edit Post screen and refresh the lock
1041   *
1042   * @since 3.6.0
1043   *
1044   * @param array  $response  The Heartbeat response.
1045   * @param array  $data      The $_POST data sent.
1046   * @param string $screen_id The screen id.
1047   * @return array The Heartbeat response.
1048   */
1049  function wp_refresh_post_lock( $response, $data, $screen_id ) {
1050      if ( array_key_exists( 'wp-refresh-post-lock', $data ) ) {
1051          $received = $data['wp-refresh-post-lock'];
1052          $send     = array();
1053  
1054          $post_id = absint( $received['post_id'] );
1055          if ( ! $post_id ) {
1056              return $response;
1057          }
1058  
1059          if ( ! current_user_can( 'edit_post', $post_id ) ) {
1060              return $response;
1061          }
1062  
1063          $user_id = wp_check_post_lock( $post_id );
1064          $user    = get_userdata( $user_id );
1065          if ( $user ) {
1066              $error = array(
1067                  /* translators: %s: User's display name. */
1068                  'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name ),
1069              );
1070  
1071              $avatar = get_avatar( $user->ID, 64 );
1072              if ( $avatar ) {
1073                  if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) {
1074                      $error['avatar_src'] = $matches[1];
1075                  }
1076              }
1077  
1078              $send['lock_error'] = $error;
1079          } else {
1080              $new_lock = wp_set_post_lock( $post_id );
1081              if ( $new_lock ) {
1082                  $send['new_lock'] = implode( ':', $new_lock );
1083              }
1084          }
1085  
1086          $response['wp-refresh-post-lock'] = $send;
1087      }
1088  
1089      return $response;
1090  }
1091  
1092  /**
1093   * Check nonce expiration on the New/Edit Post screen and refresh if needed
1094   *
1095   * @since 3.6.0
1096   *
1097   * @param array  $response  The Heartbeat response.
1098   * @param array  $data      The $_POST data sent.
1099   * @param string $screen_id The screen id.
1100   * @return array The Heartbeat response.
1101   */
1102  function wp_refresh_post_nonces( $response, $data, $screen_id ) {
1103      if ( array_key_exists( 'wp-refresh-post-nonces', $data ) ) {
1104          $received                           = $data['wp-refresh-post-nonces'];
1105          $response['wp-refresh-post-nonces'] = array( 'check' => 1 );
1106  
1107          $post_id = absint( $received['post_id'] );
1108          if ( ! $post_id ) {
1109              return $response;
1110          }
1111  
1112          if ( ! current_user_can( 'edit_post', $post_id ) ) {
1113              return $response;
1114          }
1115  
1116          $response['wp-refresh-post-nonces'] = array(
1117              'replace' => array(
1118                  'getpermalinknonce'    => wp_create_nonce( 'getpermalink' ),
1119                  'samplepermalinknonce' => wp_create_nonce( 'samplepermalink' ),
1120                  'closedpostboxesnonce' => wp_create_nonce( 'closedpostboxes' ),
1121                  '_ajax_linking_nonce'  => wp_create_nonce( 'internal-linking' ),
1122                  '_wpnonce'             => wp_create_nonce( 'update-post_' . $post_id ),
1123              ),
1124          );
1125      }
1126  
1127      return $response;
1128  }
1129  
1130  /**
1131   * Add the latest Heartbeat and REST-API nonce to the Heartbeat response.
1132   *
1133   * @since 5.0.0
1134   *
1135   * @param array  $response  The Heartbeat response.
1136   * @return array The Heartbeat response.
1137   */
1138  function wp_refresh_heartbeat_nonces( $response ) {
1139      // Refresh the Rest API nonce.
1140      $response['rest_nonce'] = wp_create_nonce( 'wp_rest' );
1141  
1142      // Refresh the Heartbeat nonce.
1143      $response['heartbeat_nonce'] = wp_create_nonce( 'heartbeat-nonce' );
1144      return $response;
1145  }
1146  
1147  /**
1148   * Disable suspension of Heartbeat on the Add/Edit Post screens.
1149   *
1150   * @since 3.8.0
1151   *
1152   * @global string $pagenow
1153   *
1154   * @param array $settings An array of Heartbeat settings.
1155   * @return array Filtered Heartbeat settings.
1156   */
1157  function wp_heartbeat_set_suspension( $settings ) {
1158      global $pagenow;
1159  
1160      if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
1161          $settings['suspension'] = 'disable';
1162      }
1163  
1164      return $settings;
1165  }
1166  
1167  /**
1168   * Autosave with heartbeat
1169   *
1170   * @since 3.9.0
1171   *
1172   * @param array $response The Heartbeat response.
1173   * @param array $data     The $_POST data sent.
1174   * @return array The Heartbeat response.
1175   */
1176  function heartbeat_autosave( $response, $data ) {
1177      if ( ! empty( $data['wp_autosave'] ) ) {
1178          $saved = wp_autosave( $data['wp_autosave'] );
1179  
1180          if ( is_wp_error( $saved ) ) {
1181              $response['wp_autosave'] = array(
1182                  'success' => false,
1183                  'message' => $saved->get_error_message(),
1184              );
1185          } elseif ( empty( $saved ) ) {
1186              $response['wp_autosave'] = array(
1187                  'success' => false,
1188                  'message' => __( 'Error while saving.' ),
1189              );
1190          } else {
1191              /* translators: Draft saved date format, see https://secure.php.net/date */
1192              $draft_saved_date_format = __( 'g:i:s a' );
1193              $response['wp_autosave'] = array(
1194                  'success' => true,
1195                  /* translators: %s: Date and time. */
1196                  'message' => sprintf( __( 'Draft saved at %s.' ), date_i18n( $draft_saved_date_format ) ),
1197              );
1198          }
1199      }
1200  
1201      return $response;
1202  }
1203  
1204  /**
1205   * Remove single-use URL parameters and create canonical link based on new URL.
1206   *
1207   * Remove specific query string parameters from a URL, create the canonical link,
1208   * put it in the admin header, and change the current URL to match.
1209   *
1210   * @since 4.2.0
1211   */
1212  function wp_admin_canonical_url() {
1213      $removable_query_args = wp_removable_query_args();
1214  
1215      if ( empty( $removable_query_args ) ) {
1216          return;
1217      }
1218  
1219      // Ensure we're using an absolute URL.
1220      $current_url  = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
1221      $filtered_url = remove_query_arg( $removable_query_args, $current_url );
1222      ?>
1223      <link id="wp-admin-canonical" rel="canonical" href="<?php echo esc_url( $filtered_url ); ?>" />
1224      <script>
1225          if ( window.history.replaceState ) {
1226              window.history.replaceState( null, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash );
1227          }
1228      </script>
1229      <?php
1230  }
1231  
1232  /**
1233   * Send a referrer policy header so referrers are not sent externally from administration screens.
1234   *
1235   * @since 4.9.0
1236   */
1237  function wp_admin_headers() {
1238      $policy = 'strict-origin-when-cross-origin';
1239  
1240      /**
1241       * Filters the admin referrer policy header value.
1242       *
1243       * @since 4.9.0
1244       * @since 4.9.5 The default value was changed to 'strict-origin-when-cross-origin'.
1245       *
1246       * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
1247       *
1248       * @param string $policy The admin referrer policy header value. Default 'strict-origin-when-cross-origin'.
1249       */
1250      $policy = apply_filters( 'admin_referrer_policy', $policy );
1251  
1252      header( sprintf( 'Referrer-Policy: %s', $policy ) );
1253  }
1254  
1255  /**
1256   * Outputs JS that reloads the page if the user navigated to it with the Back or Forward button.
1257   *
1258   * Used on the Edit Post and Add New Post screens. Needed to ensure the page is not loaded from browser cache,
1259   * so the post title and editor content are the last saved versions. Ideally this script should run first in the head.
1260   *
1261   * @since 4.6.0
1262   */
1263  function wp_page_reload_on_back_button_js() {
1264      ?>
1265      <script>
1266          if ( typeof performance !== 'undefined' && performance.navigation && performance.navigation.type === 2 ) {
1267              document.location.reload( true );
1268          }
1269      </script>
1270      <?php
1271  }
1272  
1273  /**
1274   * Send a confirmation request email when a change of site admin email address is attempted.
1275   *
1276   * The new site admin address will not become active until confirmed.
1277   *
1278   * @since 3.0.0
1279   * @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
1280   *
1281   * @param string $old_value The old site admin email address.
1282   * @param string $value     The proposed new site admin email address.
1283   */
1284  function update_option_new_admin_email( $old_value, $value ) {
1285      if ( $value == get_option( 'admin_email' ) || ! is_email( $value ) ) {
1286          return;
1287      }
1288  
1289      $hash            = md5( $value . time() . wp_rand() );
1290      $new_admin_email = array(
1291          'hash'     => $hash,
1292          'newemail' => $value,
1293      );
1294      update_option( 'adminhash', $new_admin_email );
1295  
1296      $switched_locale = switch_to_locale( get_user_locale() );
1297  
1298      /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
1299      $email_text = __(
1300          'Howdy ###USERNAME###,
1301  
1302  You recently requested to have the administration email address on
1303  your site changed.
1304  
1305  If this is correct, please click on the following link to change it:
1306  ###ADMIN_URL###
1307  
1308  You can safely ignore and delete this email if you do not want to
1309  take this action.
1310  
1311  This email has been sent to ###EMAIL###
1312  
1313  Regards,
1314  All at ###SITENAME###
1315  ###SITEURL###'
1316      );
1317  
1318      /**
1319       * Filters the text of the email sent when a change of site admin email address is attempted.
1320       *
1321       * The following strings have a special meaning and will get replaced dynamically:
1322       * ###USERNAME###  The current user's username.
1323       * ###ADMIN_URL### The link to click on to confirm the email change.
1324       * ###EMAIL###     The proposed new site admin email address.
1325       * ###SITENAME###  The name of the site.
1326       * ###SITEURL###   The URL to the site.
1327       *
1328       * @since MU (3.0.0)
1329       * @since 4.9.0 This filter is no longer Multisite specific.
1330       *
1331       * @param string $email_text      Text in the email.
1332       * @param array  $new_admin_email {
1333       *     Data relating to the new site admin email address.
1334       *
1335       *     @type string $hash     The secure hash used in the confirmation link URL.
1336       *     @type string $newemail The proposed new site admin email address.
1337       * }
1338       */
1339      $content = apply_filters( 'new_admin_email_content', $email_text, $new_admin_email );
1340  
1341      $current_user = wp_get_current_user();
1342      $content      = str_replace( '###USERNAME###', $current_user->user_login, $content );
1343      $content      = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash=' . $hash ) ), $content );
1344      $content      = str_replace( '###EMAIL###', $value, $content );
1345      $content      = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $content );
1346      $content      = str_replace( '###SITEURL###', home_url(), $content );
1347  
1348      wp_mail(
1349          $value,
1350          sprintf(
1351              /* translators: New admin email address notification email subject. %s: Site title. */
1352              __( '[%s] New Admin Email Address' ),
1353              wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES )
1354          ),
1355          $content
1356      );
1357  
1358      if ( $switched_locale ) {
1359          restore_previous_locale();
1360      }
1361  }
1362  
1363  /**
1364   * Appends '(Draft)' to draft page titles in the privacy page dropdown
1365   * so that unpublished content is obvious.
1366   *
1367   * @since 4.9.8
1368   * @access private
1369   *
1370   * @param string  $title Page title.
1371   * @param WP_Post $page  Page data object.
1372   *
1373   * @return string Page title.
1374   */
1375  function _wp_privacy_settings_filter_draft_page_titles( $title, $page ) {
1376      if ( 'draft' === $page->post_status && 'privacy' === get_current_screen()->id ) {
1377          /* translators: %s: Page title. */
1378          $title = sprintf( __( '%s (Draft)' ), $title );
1379      }
1380  
1381      return $title;
1382  }
1383  
1384  /**
1385   * Checks if the user needs to update PHP.
1386   *
1387   * @since 5.1.0
1388   * @since 5.1.1 Added the {@see 'wp_is_php_version_acceptable'} filter.
1389   *
1390   * @return array|false $response Array of PHP version data. False on failure.
1391   */
1392  function wp_check_php_version() {
1393      $version = phpversion();
1394      $key     = md5( $version );
1395  
1396      $response = get_site_transient( 'php_check_' . $key );
1397      if ( false === $response ) {
1398          $url = 'http://api.wordpress.org/core/serve-happy/1.0/';
1399          if ( wp_http_supports( array( 'ssl' ) ) ) {
1400              $url = set_url_scheme( $url, 'https' );
1401          }
1402  
1403          $url = add_query_arg( 'php_version', $version, $url );
1404  
1405          $response = wp_remote_get( $url );
1406  
1407          if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
1408              return false;
1409          }
1410  
1411          /**
1412           * Response should be an array with:
1413           *  'recommended_version' - string - The PHP version recommended by WordPress.
1414           *  'is_supported' - boolean - Whether the PHP version is actively supported.
1415           *  'is_secure' - boolean - Whether the PHP version receives security updates.
1416           *  'is_acceptable' - boolean - Whether the PHP version is still acceptable for WordPress.
1417           */
1418          $response = json_decode( wp_remote_retrieve_body( $response ), true );
1419  
1420          if ( ! is_array( $response ) ) {
1421              return false;
1422          }
1423  
1424          set_site_transient( 'php_check_' . $key, $response, WEEK_IN_SECONDS );
1425      }
1426  
1427      if ( isset( $response['is_acceptable'] ) && $response['is_acceptable'] ) {
1428          /**
1429           * Filters whether the active PHP version is considered acceptable by WordPress.
1430           *
1431           * Returning false will trigger a PHP version warning to show up in the admin dashboard to administrators.
1432           *
1433           * This filter is only run if the wordpress.org Serve Happy API considers the PHP version acceptable, ensuring
1434           * that this filter can only make this check stricter, but not loosen it.
1435           *
1436           * @since 5.1.1
1437           *
1438           * @param bool   $is_acceptable Whether the PHP version is considered acceptable. Default true.
1439           * @param string $version       PHP version checked.
1440           */
1441          $response['is_acceptable'] = (bool) apply_filters( 'wp_is_php_version_acceptable', true, $version );
1442      }
1443  
1444      return $response;
1445  }


Generated: Thu Sep 19 01:00:03 2019 Cross-referenced by PHPXref 0.7.1