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


Generated: Sat Jan 18 01:00:03 2020 Cross-referenced by PHPXref 0.7.1