[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/ -> options.php (source)

   1  <?php
   2  /**
   3   * Options Management Administration Screen.
   4   *
   5   * If accessed directly in a browser this page shows a list of all saved options
   6   * along with editable fields for their values. Serialized data is not supported
   7   * and there is no way to remove options via this page. It is not linked to from
   8   * anywhere else in the admin.
   9   *
  10   * This file is also the target of the forms in core and custom options pages
  11   * that use the Settings API. In this case it saves the new option values
  12   * and returns the user to their page of origin.
  13   *
  14   * @package WordPress
  15   * @subpackage Administration
  16   */
  17  
  18  /** WordPress Administration Bootstrap */
  19  require_once  __DIR__ . '/admin.php';
  20  
  21  // Used in the HTML title tag.
  22  $title       = __( 'Settings' );
  23  $this_file   = 'options.php';
  24  $parent_file = 'options-general.php';
  25  
  26  $action      = ! empty( $_REQUEST['action'] ) ? sanitize_text_field( $_REQUEST['action'] ) : '';
  27  $option_page = ! empty( $_REQUEST['option_page'] ) ? sanitize_text_field( $_REQUEST['option_page'] ) : '';
  28  
  29  $capability = 'manage_options';
  30  
  31  // This is for back compat and will eventually be removed.
  32  if ( empty( $option_page ) ) {
  33      $option_page = 'options';
  34  }
  35  
  36  /**
  37   * Filters the capability required when using the Settings API.
  38   *
  39   * By default, the options groups for all registered settings require the manage_options capability.
  40   * This filter is required to change the capability required for a certain options page.
  41   *
  42   * @since 3.2.0
  43   * @since 7.0.0 Applied when `wp-admin/options.php` is accessed directly.
  44   *
  45   * @param string $capability The capability used for the page, which is manage_options by default.
  46   */
  47  $capability = apply_filters( "option_page_capability_{$option_page}", $capability );
  48  
  49  if ( ! current_user_can( $capability ) ) {
  50      wp_die(
  51          '<h1>' . __( 'You need a higher level of permission.' ) . '</h1>' .
  52          '<p>' . __( 'Sorry, you are not allowed to manage options for this site.' ) . '</p>',
  53          403
  54      );
  55  }
  56  
  57  // Handle admin email change requests.
  58  if ( ! empty( $_GET['adminhash'] ) ) {
  59      $new_admin_details = get_option( 'adminhash' );
  60      $redirect          = add_query_arg( array( 'updated' => 'false' ), 'options-general.php' );
  61  
  62      if ( is_array( $new_admin_details )
  63          && hash_equals( $new_admin_details['hash'], $_GET['adminhash'] )
  64          && ! empty( $new_admin_details['newemail'] )
  65      ) {
  66          update_option( 'admin_email', $new_admin_details['newemail'] );
  67          delete_option( 'adminhash' );
  68          delete_option( 'new_admin_email' );
  69          $redirect = add_query_arg(
  70              array(
  71                  'updated'             => 'true',
  72                  'admin_email_updated' => 'true',
  73              ),
  74              'options-general.php',
  75          );
  76      }
  77  
  78      wp_redirect( admin_url( $redirect ) );
  79      exit;
  80  } elseif ( ! empty( $_GET['dismiss'] ) && 'new_admin_email' === $_GET['dismiss'] ) {
  81      check_admin_referer( 'dismiss-' . get_current_blog_id() . '-new_admin_email' );
  82      delete_option( 'adminhash' );
  83      delete_option( 'new_admin_email' );
  84      wp_redirect( admin_url( 'options-general.php?updated=true' ) );
  85      exit;
  86  }
  87  
  88  if ( is_multisite() && ! current_user_can( 'manage_network_options' ) && 'update' !== $action ) {
  89      wp_die(
  90          '<h1>' . __( 'You need a higher level of permission.' ) . '</h1>' .
  91          '<p>' . __( 'Sorry, you are not allowed to delete these items.' ) . '</p>',
  92          403
  93      );
  94  }
  95  
  96  $allowed_options            = array(
  97      'general'    => array(
  98          'blogname',
  99          'blogdescription',
 100          'site_icon',
 101          'gmt_offset',
 102          'date_format',
 103          'time_format',
 104          'start_of_week',
 105          'timezone_string',
 106          'WPLANG',
 107          'new_admin_email',
 108      ),
 109      'discussion' => array(
 110          'default_pingback_flag',
 111          'default_ping_status',
 112          'default_comment_status',
 113          'comments_notify',
 114          'moderation_notify',
 115          'comment_moderation',
 116          'require_name_email',
 117          'comment_previously_approved',
 118          'comment_max_links',
 119          'moderation_keys',
 120          'disallowed_keys',
 121          'show_avatars',
 122          'avatar_rating',
 123          'avatar_default',
 124          'close_comments_for_old_posts',
 125          'close_comments_days_old',
 126          'thread_comments',
 127          'thread_comments_depth',
 128          'page_comments',
 129          'comments_per_page',
 130          'default_comments_page',
 131          'comment_order',
 132          'comment_registration',
 133          'show_comments_cookies_opt_in',
 134          'wp_notes_notify',
 135      ),
 136      'media'      => array(
 137          'thumbnail_size_w',
 138          'thumbnail_size_h',
 139          'thumbnail_crop',
 140          'medium_size_w',
 141          'medium_size_h',
 142          'large_size_w',
 143          'large_size_h',
 144          'image_default_size',
 145          'image_default_align',
 146          'image_default_link_type',
 147      ),
 148      'reading'    => array(
 149          'posts_per_page',
 150          'posts_per_rss',
 151          'rss_use_excerpt',
 152          'show_on_front',
 153          'page_on_front',
 154          'page_for_posts',
 155          'blog_public',
 156      ),
 157      'writing'    => array(
 158          'default_category',
 159          'default_email_category',
 160          'default_link_category',
 161          'default_post_format',
 162      ),
 163  );
 164  $allowed_options['misc']    = array();
 165  $allowed_options['options'] = array();
 166  $allowed_options['privacy'] = array();
 167  
 168  /**
 169   * Filters whether the post-by-email functionality is enabled.
 170   *
 171   * @since 3.0.0
 172   *
 173   * @param bool $enabled Whether post-by-email configuration is enabled. Default true.
 174   */
 175  if ( apply_filters( 'enable_post_by_email_configuration', true ) ) {
 176      $allowed_options['writing'][] = 'mailserver_url';
 177      $allowed_options['writing'][] = 'mailserver_port';
 178      $allowed_options['writing'][] = 'mailserver_login';
 179      $allowed_options['writing'][] = 'mailserver_pass';
 180  }
 181  
 182  if ( ! is_utf8_charset() ) {
 183      $allowed_options['reading'][] = 'blog_charset';
 184  }
 185  
 186  if ( get_site_option( 'initial_db_version' ) < 32453 ) {
 187      $allowed_options['writing'][] = 'use_smilies';
 188      $allowed_options['writing'][] = 'use_balanceTags';
 189  }
 190  
 191  if ( ! is_multisite() ) {
 192      if ( ! defined( 'WP_SITEURL' ) ) {
 193          $allowed_options['general'][] = 'siteurl';
 194      }
 195      if ( ! defined( 'WP_HOME' ) ) {
 196          $allowed_options['general'][] = 'home';
 197      }
 198  
 199      $allowed_options['general'][] = 'users_can_register';
 200      $allowed_options['general'][] = 'default_role';
 201  
 202      if ( '1' === get_option( 'blog_public' ) ) {
 203          $allowed_options['writing'][] = 'ping_sites';
 204      }
 205  
 206      $allowed_options['media'][] = 'uploads_use_yearmonth_folders';
 207  
 208      /*
 209       * If upload_url_path is not the default (empty),
 210       * or upload_path is not the default ('wp-content/uploads' or empty),
 211       * they can be edited, otherwise they're locked.
 212       */
 213      if ( get_option( 'upload_url_path' )
 214          || get_option( 'upload_path' ) && 'wp-content/uploads' !== get_option( 'upload_path' )
 215      ) {
 216          $allowed_options['media'][] = 'upload_path';
 217          $allowed_options['media'][] = 'upload_url_path';
 218      }
 219  }
 220  
 221  /**
 222   * Filters the allowed options list.
 223   *
 224   * @since 2.7.0
 225   * @deprecated 5.5.0 Use {@see 'allowed_options'} instead.
 226   *
 227   * @param array $allowed_options The allowed options list.
 228   */
 229  $allowed_options = apply_filters_deprecated(
 230      'whitelist_options',
 231      array( $allowed_options ),
 232      '5.5.0',
 233      'allowed_options',
 234      __( 'Please consider writing more inclusive code.' )
 235  );
 236  
 237  /**
 238   * Filters the allowed options list.
 239   *
 240   * @since 5.5.0
 241   *
 242   * @param array $allowed_options The allowed options list.
 243   */
 244  $allowed_options = apply_filters( 'allowed_options', $allowed_options );
 245  
 246  if ( 'update' === $action ) { // We are saving settings sent from a settings page.
 247      if ( 'options' === $option_page && ! isset( $_POST['option_page'] ) ) { // This is for back compat and will eventually be removed.
 248          $unregistered = true;
 249          check_admin_referer( 'update-options' );
 250      } else {
 251          $unregistered = false;
 252          check_admin_referer( $option_page . '-options' );
 253      }
 254  
 255      if ( ! isset( $allowed_options[ $option_page ] ) ) {
 256          wp_die(
 257              sprintf(
 258                  /* translators: %s: The options page name. */
 259                  __( '<strong>Error:</strong> The %s options page is not in the allowed options list.' ),
 260                  '<code>' . esc_html( $option_page ) . '</code>'
 261              )
 262          );
 263      }
 264  
 265      if ( 'options' === $option_page ) {
 266          if ( is_multisite() && ! current_user_can( 'manage_network_options' ) ) {
 267              wp_die( __( 'Sorry, you are not allowed to modify unregistered settings for this site.' ) );
 268          }
 269          $options = isset( $_POST['page_options'] ) ? explode( ',', wp_unslash( $_POST['page_options'] ) ) : null;
 270      } else {
 271          $options = $allowed_options[ $option_page ];
 272      }
 273  
 274      if ( 'general' === $option_page ) {
 275          // Handle custom date/time formats.
 276          if ( ! empty( $_POST['date_format'] ) && isset( $_POST['date_format_custom'] )
 277              && '\c\u\s\t\o\m' === wp_unslash( $_POST['date_format'] )
 278          ) {
 279              $_POST['date_format'] = $_POST['date_format_custom'];
 280          }
 281  
 282          if ( ! empty( $_POST['time_format'] ) && isset( $_POST['time_format_custom'] )
 283              && '\c\u\s\t\o\m' === wp_unslash( $_POST['time_format'] )
 284          ) {
 285              $_POST['time_format'] = $_POST['time_format_custom'];
 286          }
 287  
 288          // Map UTC+- timezones to gmt_offsets and set timezone_string to empty.
 289          if ( ! empty( $_POST['timezone_string'] ) && preg_match( '/^UTC[+-]/', $_POST['timezone_string'] ) ) {
 290              $_POST['gmt_offset']      = $_POST['timezone_string'];
 291              $_POST['gmt_offset']      = preg_replace( '/UTC\+?/', '', $_POST['gmt_offset'] );
 292              $_POST['timezone_string'] = '';
 293          } elseif ( isset( $_POST['timezone_string'] ) && ! in_array( $_POST['timezone_string'], timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ), true ) ) {
 294              // Reset to the current value.
 295              $current_timezone_string = get_option( 'timezone_string' );
 296  
 297              if ( ! empty( $current_timezone_string ) ) {
 298                  $_POST['timezone_string'] = $current_timezone_string;
 299              } else {
 300                  $_POST['gmt_offset']      = get_option( 'gmt_offset' );
 301                  $_POST['timezone_string'] = '';
 302              }
 303  
 304              add_settings_error(
 305                  'general',
 306                  'settings_updated',
 307                  __( 'The timezone you have entered is not valid. Please select a valid timezone.' ),
 308                  'error'
 309              );
 310          }
 311  
 312          // Handle translation installation.
 313          if ( ! empty( $_POST['WPLANG'] ) && current_user_can( 'install_languages' ) ) {
 314              require_once  ABSPATH . 'wp-admin/includes/translation-install.php';
 315  
 316              if ( wp_can_install_language_pack() ) {
 317                  $language = wp_download_language_pack( $_POST['WPLANG'] );
 318                  if ( $language ) {
 319                      $_POST['WPLANG'] = $language;
 320                  }
 321              }
 322          }
 323      }
 324  
 325      if ( $options ) {
 326          $user_language_old = get_user_locale();
 327  
 328          foreach ( $options as $option ) {
 329              if ( $unregistered ) {
 330                  _deprecated_argument(
 331                      'options.php',
 332                      '2.7.0',
 333                      sprintf(
 334                          /* translators: 1: The option/setting, 2: Documentation URL. */
 335                          __( 'The %1$s setting is unregistered. Unregistered settings are deprecated. See <a href="%2$s">documentation on the Settings API</a>.' ),
 336                          '<code>' . esc_html( $option ) . '</code>',
 337                          __( 'https://developer.wordpress.org/plugins/settings/settings-api/' )
 338                      )
 339                  );
 340              }
 341  
 342              $option = trim( $option );
 343              $value  = null;
 344              if ( isset( $_POST[ $option ] ) ) {
 345                  $value = $_POST[ $option ];
 346                  if ( ! is_array( $value ) ) {
 347                      $value = trim( $value );
 348                  }
 349                  $value = wp_unslash( $value );
 350              }
 351              update_option( $option, $value );
 352          }
 353  
 354          /*
 355           * Switch translation in case WPLANG was changed.
 356           * The global $locale is used in get_locale() which is
 357           * used as a fallback in get_user_locale().
 358           */
 359          unset( $GLOBALS['locale'] );
 360          $user_language_new = get_user_locale();
 361          if ( $user_language_old !== $user_language_new ) {
 362              load_default_textdomain( $user_language_new );
 363          }
 364      } else {
 365          add_settings_error( 'general', 'settings_updated', __( 'Settings save failed.' ), 'error' );
 366      }
 367  
 368      /*
 369       * Handle settings errors and return to options page.
 370       */
 371  
 372      // If no settings errors were registered add a general 'updated' message.
 373      if ( ! count( get_settings_errors() ) ) {
 374          add_settings_error( 'general', 'settings_updated', __( 'Settings saved.' ), 'success' );
 375      }
 376  
 377      set_transient( 'settings_errors', get_settings_errors(), 30 ); // 30 seconds.
 378  
 379      // Redirect back to the settings page that was submitted.
 380      $goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() );
 381      wp_redirect( $goback );
 382      exit;
 383  }
 384  
 385  require_once  ABSPATH . 'wp-admin/admin-header.php';
 386  ?>
 387  
 388  <div class="wrap">
 389      <h1><?php esc_html_e( 'All Settings' ); ?></h1>
 390  
 391      <?php
 392      wp_admin_notice(
 393          '<strong>' . __( 'Warning:' ) . '</strong> ' . __( 'This page allows direct access to your site settings. You can break things here. Please be cautious!' ),
 394          array(
 395              'type' => 'warning',
 396          )
 397      );
 398      ?>
 399      <form name="form" action="options.php" method="post" id="all-options">
 400          <?php wp_nonce_field( 'options-options' ); ?>
 401          <input type="hidden" name="action" value="update" />
 402          <input type="hidden" name="option_page" value="options" />
 403          <table class="form-table" role="presentation">
 404  <?php
 405  /**
 406   * @global wpdb $wpdb WordPress database abstraction object.
 407   */
 408  global $wpdb;
 409  
 410  $options = $wpdb->get_results( "SELECT * FROM $wpdb->options ORDER BY option_name" );
 411  
 412  foreach ( (array) $options as $option ) :
 413      $disabled = false;
 414  
 415      if ( '' === $option->option_name ) {
 416          continue;
 417      }
 418  
 419      if ( 'home' === $option->option_name && defined( 'WP_HOME' ) ) {
 420          $disabled = true;
 421      }
 422  
 423      if ( 'siteurl' === $option->option_name && defined( 'WP_SITEURL' ) ) {
 424          $disabled = true;
 425      }
 426  
 427      if ( is_serialized( $option->option_value ) ) {
 428          if ( is_serialized_string( $option->option_value ) ) {
 429              // This is a serialized string, so we should display it.
 430              $value               = maybe_unserialize( $option->option_value );
 431              $options_to_update[] = $option->option_name;
 432          } else {
 433              $value    = 'SERIALIZED DATA';
 434              $disabled = true;
 435          }
 436      } elseif ( str_starts_with( $option->option_name, 'connectors_' )
 437          && str_ends_with( $option->option_name, '_api_key' )
 438      ) {
 439          // Mask connector API keys and prevent updates from this screen.
 440          $value    = _wp_connectors_mask_api_key( $option->option_value );
 441          $disabled = true;
 442      } else {
 443          $value               = $option->option_value;
 444          $options_to_update[] = $option->option_name;
 445      }
 446  
 447      $class = 'all-options';
 448  
 449      if ( $disabled ) {
 450          $class .= ' disabled';
 451      }
 452  
 453      $name = esc_attr( $option->option_name );
 454      ?>
 455  <tr>
 456      <th scope="row"><label for="<?php echo $name; ?>"><?php echo esc_html( $option->option_name ); ?></label></th>
 457  <td>
 458      <?php if ( str_contains( $value, "\n" ) ) : ?>
 459          <textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" cols="30" rows="5"><?php echo esc_textarea( $value ); ?></textarea>
 460      <?php else : ?>
 461          <input class="regular-text <?php echo $class; ?>" type="text" name="<?php echo $name; ?>" id="<?php echo $name; ?>" value="<?php echo esc_attr( $value ); ?>"<?php disabled( $disabled, true ); ?> />
 462      <?php endif; ?></td>
 463  </tr>
 464  <?php endforeach; ?>
 465  </table>
 466  
 467  <input type="hidden" name="page_options" value="<?php echo esc_attr( implode( ',', $options_to_update ) ); ?>" />
 468  
 469  <?php submit_button( __( 'Save Changes' ), 'primary', 'Update' ); ?>
 470  
 471  </form>
 472  </div>
 473  
 474  <?php
 475  require_once  ABSPATH . 'wp-admin/admin-footer.php';


Generated : Sun Oct 11 08:20:32 2026 Cross-referenced by PHPXref