| 1 | <?php |
| 2 | /** |
| 3 | * WordPress Options implementation for General Settings. |
| 4 | * |
| 5 | * @package WordPress |
| 6 | * @subpackage Administration |
| 7 | * @since 4.8.0 |
| 8 | */ |
| 9 | |
| 10 | /** |
| 11 | * Adds default settings fields for the General Settings page. |
| 12 | * |
| 13 | * @since 4.8.0 |
| 14 | */ |
| 15 | function add_settings_fields_options_general() { |
| 16 | add_settings_field( 'blogname', __( 'Site Title' ), 'text', 'general', 'default', array( |
| 17 | 'input_class' => 'regular-text', |
| 18 | ) ); |
| 19 | |
| 20 | add_settings_field( 'blogdescription', __( 'Tagline' ), 'text', 'general', 'default', array( |
| 21 | 'input_class' => 'regular-text', |
| 22 | 'description_id' => 'tagline-description', |
| 23 | 'description' => __( 'In a few words, explain what this site is about.' ), |
| 24 | ) ); |
| 25 | |
| 26 | if ( ! is_multisite() ) { |
| 27 | add_settings_field( 'siteurl', __( 'WordPress Address (URL)' ), 'url', 'general', 'default', array( |
| 28 | 'input_class' => 'regular-text code' . ( defined( 'WP_SITEURL' ) ? ' disabled' : '' ), |
| 29 | 'disabled' => defined( 'WP_SITEURL' ) ? true : false, |
| 30 | ) ); |
| 31 | |
| 32 | add_settings_field( 'home', __( 'Site Address (URL)' ), 'url', 'general', 'default', array( |
| 33 | 'input_class' => 'regular-text code' . ( defined( 'WP_HOME' ) ? ' disabled' : '' ), |
| 34 | 'disabled' => defined( 'WP_HOME' ) ? true : false, |
| 35 | 'description' => __( 'Enter the address here if you <a href="https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">want your site home page to be different from your WordPress installation directory.</a>' ), |
| 36 | ) ); |
| 37 | |
| 38 | add_settings_field( 'admin_email', __( 'Email Address' ), 'email', 'general', 'default', array( |
| 39 | 'input_id' => 'admin-email', |
| 40 | 'input_class' => 'regular-text ltr', |
| 41 | 'description' => __( 'This address is used for admin purposes, like new user notification.' ), |
| 42 | ) ); |
| 43 | |
| 44 | add_settings_field( 'users_can_register', __( 'Anyone can register' ), 'checkbox', 'general', 'default' ); |
| 45 | |
| 46 | add_settings_field( 'default_role', __( 'New User Default Role' ), 'render_settings_field_roles_dropdown', 'general', 'default' ); |
| 47 | } else { |
| 48 | add_settings_field( 'admin_email', __( 'Email Address' ), 'email', 'general', 'default', array( |
| 49 | 'input_id' => 'new_admin_email', |
| 50 | 'input_name' => 'new_admin_email', |
| 51 | 'input_class' => 'regular-text ltr', |
| 52 | 'description_id' => 'new-admin-email-description', |
| 53 | 'description' => __( 'This address is used for admin purposes. If you change this we will send you an email at your new address to confirm it. <strong>The new address will not become active until confirmed.</strong>' ), |
| 54 | 'value_callback' => 'settings_field_admin_email_get_option', |
| 55 | 'after' => 'settings_field_admin_email_after', |
| 56 | ) ); |
| 57 | } |
| 58 | |
| 59 | $languages = get_available_languages(); |
| 60 | $translations = wp_get_available_translations(); |
| 61 | if ( ! is_multisite() && defined( 'WPLANG' ) && '' !== WPLANG && 'en_US' !== WPLANG && ! in_array( WPLANG, $languages ) ) { |
| 62 | $languages[] = WPLANG; |
| 63 | } |
| 64 | if ( ! empty( $languages ) || ! empty( $translations ) ) { |
| 65 | add_settings_field( 'WPLANG', __( 'Site Language' ), 'render_settings_field_languages_dropdown', 'general', 'default', array( |
| 66 | 'languages' => $languages, |
| 67 | 'translations' => $translations, |
| 68 | 'after' => 'settings_field_wplang_after', |
| 69 | ) ); |
| 70 | } |
| 71 | |
| 72 | add_settings_field( 'timezone_string', __( 'Timezone' ), 'render_settings_field_timezones_dropdown', 'general', 'default', array( |
| 73 | 'description_id' => 'timezone-description', |
| 74 | 'description' => __( 'Choose either a city in the same timezone as you or a UTC timezone offset.' ), |
| 75 | ) ); |
| 76 | |
| 77 | add_settings_field( 'date_format', __( 'Date Format' ), 'render_settings_field_datetime_format_radio', 'general', 'default', array( |
| 78 | 'mode' => 'date_format', |
| 79 | 'fieldset' => true, |
| 80 | ) ); |
| 81 | |
| 82 | add_settings_field( 'time_format', __( 'Time Format' ), 'render_settings_field_datetime_format_radio', 'general', 'default', array( |
| 83 | 'mode' => 'time_format', |
| 84 | 'fieldset' => true, |
| 85 | 'after' => 'settings_field_time_format_after', |
| 86 | ) ); |
| 87 | |
| 88 | /** |
| 89 | * @global WP_Locale $wp_locale |
| 90 | */ |
| 91 | global $wp_locale; |
| 92 | |
| 93 | $start_of_week_choices = array(); |
| 94 | for ( $day_index = 0; $day_index <= 6; $day_index++ ) { |
| 95 | $start_of_week_choices[ $day_index ] = $wp_locale->get_weekday( $day_index ); |
| 96 | } |
| 97 | |
| 98 | add_settings_field( 'start_of_week', __( 'Week Starts On' ), 'select', 'general', 'default', array( |
| 99 | 'choices' => $start_of_week_choices, |
| 100 | ) ); |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * Settings field callback to print a roles dropdown control. |
| 105 | * |
| 106 | * @since 4.8.0 |
| 107 | * |
| 108 | * @see add_settings_field() |
| 109 | * |
| 110 | * @param array $field_args Array of field arguments. |
| 111 | */ |
| 112 | function render_settings_field_roles_dropdown( $field_args ) { |
| 113 | $input_attrs = array( |
| 114 | 'id' => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '', |
| 115 | 'name' => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '', |
| 116 | 'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '', |
| 117 | ); |
| 118 | |
| 119 | $description_attrs = array(); |
| 120 | |
| 121 | if ( ! empty( $field_args['description'] ) ) { |
| 122 | if ( ! empty( $field_args['description_id'] ) ) { |
| 123 | $description_attrs['id'] = $field_args['description_id']; |
| 124 | $input_attrs['aria-describedby'] = $field_args['description_id']; |
| 125 | } |
| 126 | $description_attrs['class'] = 'description'; |
| 127 | } |
| 128 | |
| 129 | $current = ! empty( $field_args['value'] ) ? $field_args['value'] : ''; |
| 130 | ?> |
| 131 | <select<?php attrs( $input_attrs ); ?>><?php wp_dropdown_roles( $current ); ?></select> |
| 132 | <?php |
| 133 | |
| 134 | if ( ! empty( $field_args['description'] ) ) { |
| 135 | echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>'; |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Settings field callback to print a languages dropdown control. |
| 141 | * |
| 142 | * @since 4.8.0 |
| 143 | * |
| 144 | * @see add_settings_field() |
| 145 | * |
| 146 | * @param array $field_args Array of field arguments. |
| 147 | */ |
| 148 | function render_settings_field_languages_dropdown( $field_args ) { |
| 149 | $languages = isset( $field_args['languages'] ) ? $field_args['languages'] : get_available_languages(); |
| 150 | $translations = isset( $field_args['translations'] ) ? $field_args['translations'] : wp_get_available_translations(); |
| 151 | |
| 152 | $locale = get_locale(); |
| 153 | if ( ! in_array( $locale, $languages ) ) { |
| 154 | $locale = ''; |
| 155 | } |
| 156 | |
| 157 | wp_dropdown_languages( array( |
| 158 | 'name' => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '', |
| 159 | 'id' => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '', |
| 160 | 'selected' => $locale, |
| 161 | 'languages' => $languages, |
| 162 | 'translations' => $translations, |
| 163 | 'show_available_translations' => ( ! is_multisite() || is_super_admin() ) && wp_can_install_language_pack(), |
| 164 | ) ); |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * Settings field callback to print a timezones dropdown control. |
| 169 | * |
| 170 | * @since 4.8.0 |
| 171 | * |
| 172 | * @see add_settings_field() |
| 173 | * |
| 174 | * @param array $field_args Array of field arguments. |
| 175 | */ |
| 176 | function render_settings_field_timezones_dropdown( $field_args ) { |
| 177 | $current_offset = get_option('gmt_offset'); |
| 178 | $tzstring = ! empty( $field_args['value'] ) ? $field_args['value'] : ''; |
| 179 | |
| 180 | $check_zone_info = true; |
| 181 | |
| 182 | // Remove old Etc mappings. Fallback to gmt_offset. |
| 183 | if ( false !== strpos($tzstring,'Etc/GMT') ) |
| 184 | $tzstring = ''; |
| 185 | |
| 186 | if ( empty($tzstring) ) { // Create a UTC+- zone if no timezone string exists |
| 187 | $check_zone_info = false; |
| 188 | if ( 0 == $current_offset ) |
| 189 | $tzstring = 'UTC+0'; |
| 190 | elseif ($current_offset < 0) |
| 191 | $tzstring = 'UTC' . $current_offset; |
| 192 | else |
| 193 | $tzstring = 'UTC+' . $current_offset; |
| 194 | } |
| 195 | |
| 196 | $input_attrs = array( |
| 197 | 'id' => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '', |
| 198 | 'name' => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '', |
| 199 | 'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '', |
| 200 | ); |
| 201 | |
| 202 | $description_attrs = array(); |
| 203 | |
| 204 | if ( ! empty( $field_args['description'] ) ) { |
| 205 | if ( ! empty( $field_args['description_id'] ) ) { |
| 206 | $description_attrs['id'] = $field_args['description_id']; |
| 207 | $input_attrs['aria-describedby'] = $field_args['description_id']; |
| 208 | } |
| 209 | $description_attrs['class'] = 'description'; |
| 210 | } |
| 211 | |
| 212 | ?> |
| 213 | <select<?php attrs( $input_attrs ); ?>><?php echo wp_timezone_choice( $tzstring, get_user_locale() ); ?></select> |
| 214 | <?php |
| 215 | |
| 216 | if ( ! empty( $field_args['description'] ) ) { |
| 217 | echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>'; |
| 218 | } |
| 219 | |
| 220 | $timezone_format = _x( 'Y-m-d H:i:s', 'timezone date format' ); |
| 221 | |
| 222 | ?> |
| 223 | <p class="timezone-info"> |
| 224 | <span id="utc-time"><?php |
| 225 | /* translators: 1: UTC abbreviation, 2: UTC time */ |
| 226 | printf( __( 'Universal time (%1$s) is %2$s.' ), |
| 227 | '<abbr>' . __( 'UTC' ) . '</abbr>', |
| 228 | '<code>' . date_i18n( $timezone_format, false, true ) . '</code>' |
| 229 | ); |
| 230 | ?></span> |
| 231 | <?php if ( get_option( 'timezone_string' ) || ! empty( $current_offset ) ) : ?> |
| 232 | <span id="local-time"><?php |
| 233 | /* translators: %s: local time */ |
| 234 | printf( __( 'Local time is %s.' ), |
| 235 | '<code>' . date_i18n( $timezone_format ) . '</code>' |
| 236 | ); |
| 237 | ?></span> |
| 238 | <?php endif; ?> |
| 239 | </p> |
| 240 | |
| 241 | <?php if ( $check_zone_info && $tzstring ) : ?> |
| 242 | <p class="timezone-info"> |
| 243 | <span> |
| 244 | <?php |
| 245 | // Set TZ so localtime works. |
| 246 | date_default_timezone_set($tzstring); |
| 247 | $now = localtime(time(), true); |
| 248 | if ( $now['tm_isdst'] ) |
| 249 | _e('This timezone is currently in daylight saving time.'); |
| 250 | else |
| 251 | _e('This timezone is currently in standard time.'); |
| 252 | ?> |
| 253 | <br /> |
| 254 | <?php |
| 255 | $allowed_zones = timezone_identifiers_list(); |
| 256 | |
| 257 | if ( in_array( $tzstring, $allowed_zones) ) { |
| 258 | $found = false; |
| 259 | $date_time_zone_selected = new DateTimeZone($tzstring); |
| 260 | $tz_offset = timezone_offset_get($date_time_zone_selected, date_create()); |
| 261 | $right_now = time(); |
| 262 | foreach ( timezone_transitions_get($date_time_zone_selected) as $tr) { |
| 263 | if ( $tr['ts'] > $right_now ) { |
| 264 | $found = true; |
| 265 | break; |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | if ( $found ) { |
| 270 | echo ' '; |
| 271 | $message = $tr['isdst'] ? |
| 272 | /* translators: %s: date and time */ |
| 273 | __( 'Daylight saving time begins on: %s.') : |
| 274 | /* translators: %s: date and time */ |
| 275 | __( 'Standard time begins on: %s.' ); |
| 276 | // Add the difference between the current offset and the new offset to ts to get the correct transition time from date_i18n(). |
| 277 | printf( $message, |
| 278 | '<code>' . date_i18n( |
| 279 | __( 'F j, Y' ) . ' ' . __( 'g:i a' ), |
| 280 | $tr['ts'] + ( $tz_offset - $tr['offset'] ) |
| 281 | ) . '</code>' |
| 282 | ); |
| 283 | } else { |
| 284 | _e( 'This timezone does not observe daylight saving time.' ); |
| 285 | } |
| 286 | } |
| 287 | // Set back to UTC. |
| 288 | date_default_timezone_set('UTC'); |
| 289 | ?> |
| 290 | </span> |
| 291 | </p> |
| 292 | <?php endif; |
| 293 | } |
| 294 | |
| 295 | /** |
| 296 | * Settings field callback to print a date or time radio group. |
| 297 | * |
| 298 | * @since 4.8.0 |
| 299 | * |
| 300 | * @see add_settings_field() |
| 301 | * |
| 302 | * @param array $field_args Array of field arguments. |
| 303 | */ |
| 304 | function render_settings_field_datetime_format_radio( $field_args ) { |
| 305 | $input_attrs = array( |
| 306 | 'type' => 'radio', |
| 307 | 'id' => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '', |
| 308 | 'name' => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '', |
| 309 | 'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '', |
| 310 | ); |
| 311 | |
| 312 | $choices = array(); |
| 313 | $custom_radio_label = ''; |
| 314 | $custom_label = ''; |
| 315 | |
| 316 | if ( ! empty( $field_args['mode'] ) && 'time_format' === $field_args['mode'] ) { |
| 317 | /** |
| 318 | * Filters the default time formats. |
| 319 | * |
| 320 | * @since 2.7.0 |
| 321 | * |
| 322 | * @param array $default_time_formats Array of default time formats. |
| 323 | */ |
| 324 | $choices = array_unique( apply_filters( 'time_formats', array( __( 'g:i a' ), 'g:i A', 'H:i' ) ) ); |
| 325 | |
| 326 | $custom_radio_label = __( 'Custom: enter a custom time format in the field below' ); |
| 327 | $custom_label = __( 'Custom time format:' ); |
| 328 | } else { |
| 329 | /** |
| 330 | * Filters the default date formats. |
| 331 | * |
| 332 | * @since 2.7.0 |
| 333 | * @since 4.0.0 Added ISO date standard YYYY-MM-DD format. |
| 334 | * |
| 335 | * @param array $default_date_formats Array of default date formats. |
| 336 | */ |
| 337 | $choices = array_unique( apply_filters( 'date_formats', array( __( 'F j, Y' ), 'Y-m-d', 'm/d/Y', 'd/m/Y' ) ) ); |
| 338 | |
| 339 | $custom_radio_label = __( 'Custom: enter a custom date format in the field below' ); |
| 340 | $custom_label = __( 'Custom date format:' ); |
| 341 | } |
| 342 | |
| 343 | $current = ! empty( $field_args['value'] ) ? $field_args['value'] : $choices[0]; |
| 344 | |
| 345 | $custom = false; |
| 346 | if ( ! in_array( $current, $choices ) ) { |
| 347 | $custom = true; |
| 348 | } |
| 349 | |
| 350 | $id_suffix = 0; |
| 351 | foreach ( $choices as $value ) { |
| 352 | $id_suffix++; |
| 353 | |
| 354 | $radio_attrs = $input_attrs; |
| 355 | $radio_attrs['id'] .= '-' . zeroise( $id_suffix, 2 ); |
| 356 | $radio_attrs['value'] = $value; |
| 357 | |
| 358 | echo '<span class="radio-item">'; |
| 359 | echo '<input' . attrs( $radio_attrs, false ) . checked( $current, $value, false ) . ' />'; |
| 360 | echo ' <label for="' . $radio_attrs['id'] . '"><span class="date-time-text format-i18n">' . date_i18n( $value ) . '</span><code>' . esc_html( $value ) . '</code></label>'; |
| 361 | echo '</span><br />'; |
| 362 | } |
| 363 | |
| 364 | $radio_attrs = $input_attrs; |
| 365 | $radio_attrs['id'] = $radio_attrs['name'] . '_custom_radio'; |
| 366 | $radio_attrs['value'] = '\c\u\s\t\o\m'; |
| 367 | |
| 368 | echo '<span class="radio-item">'; |
| 369 | echo '<input' . attrs( $radio_attrs, false ) . checked( $custom, true, false ) . ' />'; |
| 370 | echo ' <label for="' . $radio_attrs['id'] . '">' . $custom_radio_label . '</label>'; |
| 371 | echo '</span><br />'; |
| 372 | |
| 373 | $description_id = $radio_attrs['id'] . '-custom-description'; |
| 374 | $text_attrs = array( |
| 375 | 'type' => 'text', |
| 376 | 'id' => $radio_attrs['name'] . '_custom', |
| 377 | 'name' => $radio_attrs['name'] . '_custom', |
| 378 | 'class' => 'small-text', |
| 379 | 'value' => $current, |
| 380 | 'aria-describedby' => $description_id, |
| 381 | ); |
| 382 | |
| 383 | echo '<span class="radio-item">'; |
| 384 | echo '<label for="' . esc_attr( $text_attrs['id'] ) . '">' . $custom_label . '</label>'; |
| 385 | echo ' <input' . attrs( $text_attrs, false ) . ' />'; |
| 386 | echo ' <span class="description" id="' . $description_id . '">' . __( 'Example:' ) . ' <span class="example">' . date_i18n( $current ) . '</span><span class="spinner"></span></span>'; |
| 387 | echo '</span>'; |
| 388 | } |
| 389 | |
| 390 | /** |
| 391 | * Settings field callback to retrieve the admin email. |
| 392 | * |
| 393 | * @since 4.8 |
| 394 | * |
| 395 | * @return string Admin email address. |
| 396 | */ |
| 397 | function settings_field_admin_email_get_option() { |
| 398 | return get_option( 'admin_email' ); |
| 399 | } |
| 400 | |
| 401 | /** |
| 402 | * Settings field callback to print additional content for the 'admin_email' control. |
| 403 | * |
| 404 | * @since 4.8 |
| 405 | */ |
| 406 | function settings_field_admin_email_after() { |
| 407 | $new_admin_email = get_option( 'new_admin_email' ); |
| 408 | if ( $new_admin_email && $new_admin_email != get_option('admin_email') ) : ?> |
| 409 | <div class="updated inline"> |
| 410 | <p><?php |
| 411 | printf( |
| 412 | /* translators: %s: new admin email */ |
| 413 | __( 'There is a pending change of the admin email to %s.' ), |
| 414 | '<code>' . esc_html( $new_admin_email ) . '</code>' |
| 415 | ); |
| 416 | printf( |
| 417 | ' <a href="%1$s">%2$s</a>', |
| 418 | esc_url( wp_nonce_url( admin_url( 'options.php?dismiss=new_admin_email' ), 'dismiss-' . get_current_blog_id() . '-new_admin_email' ) ), |
| 419 | __( 'Cancel' ) |
| 420 | ); |
| 421 | ?></p> |
| 422 | </div> |
| 423 | <?php endif; |
| 424 | } |
| 425 | |
| 426 | /** |
| 427 | * Settings field callback to print additional content for the 'WPLANG' control. |
| 428 | * |
| 429 | * @since 4.8 |
| 430 | */ |
| 431 | function settings_field_wplang_after() { |
| 432 | // Add note about deprecated WPLANG constant. |
| 433 | if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && get_locale() !== WPLANG ) { |
| 434 | if ( is_multisite() && current_user_can( 'manage_network_options' ) |
| 435 | || ! is_multisite() && current_user_can( 'manage_options' ) ) { |
| 436 | ?> |
| 437 | <p class="description"> |
| 438 | <strong><?php _e( 'Note:' ); ?></strong> <?php printf( __( 'The %s constant in your %s file is no longer needed.' ), '<code>WPLANG</code>', '<code>wp-config.php</code>' ); ?> |
| 439 | </p> |
| 440 | <?php |
| 441 | } |
| 442 | _deprecated_argument( 'define()', '4.0.0', sprintf( __( 'The %s constant in your %s file is no longer needed.' ), 'WPLANG', 'wp-config.php' ) ); |
| 443 | } |
| 444 | } |
| 445 | |
| 446 | /** |
| 447 | * Settings field callback to print additional content for the 'time_format' control. |
| 448 | * |
| 449 | * @since 4.8 |
| 450 | */ |
| 451 | function settings_field_time_format_after() { |
| 452 | ?> |
| 453 | <p class="date-time-doc"><a href="https://codex.wordpress.org/Formatting_Date_and_Time"><?php _e( 'Documentation on date and time formatting' ); ?></a>.</p> |
| 454 | <?php |
| 455 | } |