From 99e9156eade5f4c2374b5d34225373447c41d311 Mon Sep 17 00:00:00 2001 From: Anatoli Nicolae Date: Sun, 26 Apr 2026 11:31:58 +0200 Subject: [PATCH] Administration: Display serialized option values read-only instead of a placeholder. Replaces the hard-coded "SERIALIZED DATA" placeholder in wp-admin/options.php and wp-admin/network/site-settings.php with the raw serialized value rendered read-only inside a collapsible
/ element. The value remains non-editable and is excluded from form submission so it cannot be accidentally corrupted on save. Also tightens the surrounding template: * options.php: hoists $value initialization out of per-branch assignments, collapses the disabled-class logic into a ternary, merges the home/siteurl WP_HOME/WP_SITEURL checks. * site-settings.php: hoists the $ltr_fields list out of the per-row loop, consolidates four duplicated blocks into a single row with inline branches, and removes a double-escape on serialized-string values (esc_html() was applied at assignment and again at output via esc_textarea/esc_attr). Fixes #64581. --- src/wp-admin/network/site-settings.php | 94 +++++++++++++------------- src/wp-admin/options.php | 51 +++++++------- 2 files changed, 74 insertions(+), 71 deletions(-) diff --git a/src/wp-admin/network/site-settings.php b/src/wp-admin/network/site-settings.php index 8b1248f6b13b2..46800b4e4859e 100644 --- a/src/wp-admin/network/site-settings.php +++ b/src/wp-admin/network/site-settings.php @@ -132,62 +132,64 @@ ) ); + $ltr_fields = array( + 'siteurl', + 'home', + 'admin_email', + 'new_admin_email', + 'mailserver_url', + 'mailserver_login', + 'mailserver_pass', + 'ping_sites', + 'permalink_structure', + 'category_base', + 'tag_base', + 'upload_path', + 'upload_url_path', + ); + foreach ( $options as $option ) { if ( 'default_role' === $option->option_name ) { $editblog_default_role = $option->option_value; } - $disabled = false; - $class = 'all-options'; + $value = $option->option_value; + $disabled = false; + $is_serialized = false; - if ( is_serialized( $option->option_value ) ) { - if ( is_serialized_string( $option->option_value ) ) { - $option->option_value = esc_html( maybe_unserialize( $option->option_value ) ); + if ( is_serialized( $value ) ) { + if ( is_serialized_string( $value ) ) { + $value = maybe_unserialize( $value ); } else { - $option->option_value = 'SERIALIZED DATA'; - $disabled = true; - $class = 'all-options disabled'; + // Other serialized values (arrays, objects) are shown raw, read-only, inside a collapsible
. + $disabled = true; + $is_serialized = true; } } - $ltr_fields = array( - 'siteurl', - 'home', - 'admin_email', - 'new_admin_email', - 'mailserver_url', - 'mailserver_login', - 'mailserver_pass', - 'ping_sites', - 'permalink_structure', - 'category_base', - 'tag_base', - 'upload_path', - 'upload_url_path', - ); - if ( in_array( $option->option_name, $ltr_fields, true ) ) { - $class .= ' ltr'; - } - - if ( str_contains( $option->option_value, "\n" ) ) { - ?> - - - - - - - - option_name, array( 'siteurl', 'home' ), true ) ) { ?> - option_value ); ?> - - /> - - - option_name, $ltr_fields, true ) ? ' ltr' : ''; + $name = esc_attr( $option->option_name ); + $label = esc_html( $option->option_name ); + ?> + + + + +
+ + +
+ + + + option_name, array( 'siteurl', 'home' ), true ) ) : ?> + + + /> + + + get_results( "SELECT * FROM $wpdb->options ORDER BY option_name" ); foreach ( (array) $options as $option ) : - $disabled = false; - if ( '' === $option->option_name ) { continue; } - if ( 'home' === $option->option_name && defined( 'WP_HOME' ) ) { - $disabled = true; - } + $value = $option->option_value; + $disabled = false; + $is_serialized = false; - if ( 'siteurl' === $option->option_name && defined( 'WP_SITEURL' ) ) { + if ( ( 'home' === $option->option_name && defined( 'WP_HOME' ) ) + || ( 'siteurl' === $option->option_name && defined( 'WP_SITEURL' ) ) + ) { $disabled = true; } - if ( is_serialized( $option->option_value ) ) { - if ( is_serialized_string( $option->option_value ) ) { - // This is a serialized string, so we should display it. - $value = maybe_unserialize( $option->option_value ); + if ( is_serialized( $value ) ) { + if ( is_serialized_string( $value ) ) { + // Serialized strings can be safely displayed and edited as their unserialized form. + $value = maybe_unserialize( $value ); $options_to_update[] = $option->option_name; } else { - $value = 'SERIALIZED DATA'; - $disabled = true; + // Other serialized values (arrays, objects) are shown raw, read-only, inside a collapsible
. + $disabled = true; + $is_serialized = true; } } elseif ( str_starts_with( $option->option_name, 'connectors_' ) && str_ends_with( $option->option_name, '_api_key' ) ) { // Mask connector API keys and prevent updates from this screen. - $value = _wp_connectors_mask_api_key( $option->option_value ); + $value = _wp_connectors_mask_api_key( $value ); $disabled = true; } else { - $value = $option->option_value; $options_to_update[] = $option->option_name; } - $class = 'all-options'; - - if ( $disabled ) { - $class .= ' disabled'; - } - - $name = esc_attr( $option->option_name ); + $class = 'all-options' . ( $disabled ? ' disabled' : '' ); + $name = esc_attr( $option->option_name ); ?> - - - + + +
+ + +
+ + /> - + +