Skip to content

Commit d5620d3

Browse files
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 <details>/<summary> 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 <tr> 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.
1 parent acebfd0 commit d5620d3

2 files changed

Lines changed: 74 additions & 71 deletions

File tree

src/wp-admin/network/site-settings.php

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -132,62 +132,64 @@
132132
)
133133
);
134134

135+
$ltr_fields = array(
136+
'siteurl',
137+
'home',
138+
'admin_email',
139+
'new_admin_email',
140+
'mailserver_url',
141+
'mailserver_login',
142+
'mailserver_pass',
143+
'ping_sites',
144+
'permalink_structure',
145+
'category_base',
146+
'tag_base',
147+
'upload_path',
148+
'upload_url_path',
149+
);
150+
135151
foreach ( $options as $option ) {
136152
if ( 'default_role' === $option->option_name ) {
137153
$editblog_default_role = $option->option_value;
138154
}
139155

140-
$disabled = false;
141-
$class = 'all-options';
156+
$value = $option->option_value;
157+
$disabled = false;
158+
$is_serialized = false;
142159

143-
if ( is_serialized( $option->option_value ) ) {
144-
if ( is_serialized_string( $option->option_value ) ) {
145-
$option->option_value = esc_html( maybe_unserialize( $option->option_value ) );
160+
if ( is_serialized( $value ) ) {
161+
if ( is_serialized_string( $value ) ) {
162+
$value = maybe_unserialize( $value );
146163
} else {
147-
$option->option_value = 'SERIALIZED DATA';
148-
$disabled = true;
149-
$class = 'all-options disabled';
164+
// Other serialized values (arrays, objects) are shown raw, read-only, inside a collapsible <details>.
165+
$disabled = true;
166+
$is_serialized = true;
150167
}
151168
}
152169

153-
$ltr_fields = array(
154-
'siteurl',
155-
'home',
156-
'admin_email',
157-
'new_admin_email',
158-
'mailserver_url',
159-
'mailserver_login',
160-
'mailserver_pass',
161-
'ping_sites',
162-
'permalink_structure',
163-
'category_base',
164-
'tag_base',
165-
'upload_path',
166-
'upload_url_path',
167-
);
168-
if ( in_array( $option->option_name, $ltr_fields, true ) ) {
169-
$class .= ' ltr';
170-
}
171-
172-
if ( str_contains( $option->option_value, "\n" ) ) {
173-
?>
174-
<tr class="form-field">
175-
<th scope="row"><label for="<?php echo esc_attr( $option->option_name ); ?>" class="code"><?php echo esc_html( $option->option_name ); ?></label></th>
176-
<td><textarea class="<?php echo $class; ?>" rows="5" cols="40" name="option[<?php echo esc_attr( $option->option_name ); ?>]" id="<?php echo esc_attr( $option->option_name ); ?>"<?php disabled( $disabled ); ?>><?php echo esc_textarea( $option->option_value ); ?></textarea></td>
177-
</tr>
178-
<?php
179-
} else {
180-
?>
181-
<tr class="form-field">
182-
<th scope="row"><label for="<?php echo esc_attr( $option->option_name ); ?>" class="code"><?php echo esc_html( $option->option_name ); ?></label></th>
183-
<?php if ( $is_main_site && in_array( $option->option_name, array( 'siteurl', 'home' ), true ) ) { ?>
184-
<td><code><?php echo esc_html( $option->option_value ); ?></code></td>
185-
<?php } else { ?>
186-
<td><input class="<?php echo $class; ?>" name="option[<?php echo esc_attr( $option->option_name ); ?>]" type="text" id="<?php echo esc_attr( $option->option_name ); ?>" value="<?php echo esc_attr( $option->option_value ); ?>" size="40" <?php disabled( $disabled ); ?> /></td>
187-
<?php } ?>
188-
</tr>
189-
<?php
190-
}
170+
$class = 'all-options' . ( $disabled ? ' disabled' : '' );
171+
$class .= in_array( $option->option_name, $ltr_fields, true ) ? ' ltr' : '';
172+
$name = esc_attr( $option->option_name );
173+
$label = esc_html( $option->option_name );
174+
?>
175+
<tr class="form-field">
176+
<th scope="row"><label for="<?php echo $name; ?>" class="code"><?php echo $label; ?></label></th>
177+
<?php if ( $is_serialized ) : ?>
178+
<td>
179+
<details class="<?php echo $class; ?>">
180+
<summary><?php esc_html_e( 'Serialized data' ); ?></summary>
181+
<textarea class="<?php echo $class; ?>" rows="5" cols="40" id="<?php echo $name; ?>" readonly="readonly"><?php echo esc_textarea( $value ); ?></textarea>
182+
</details>
183+
</td>
184+
<?php elseif ( str_contains( $value, "\n" ) ) : ?>
185+
<td><textarea class="<?php echo $class; ?>" rows="5" cols="40" name="option[<?php echo $name; ?>]" id="<?php echo $name; ?>"<?php disabled( $disabled ); ?>><?php echo esc_textarea( $value ); ?></textarea></td>
186+
<?php elseif ( $is_main_site && in_array( $option->option_name, array( 'siteurl', 'home' ), true ) ) : ?>
187+
<td><code><?php echo esc_html( $value ); ?></code></td>
188+
<?php else : ?>
189+
<td><input class="<?php echo $class; ?>" name="option[<?php echo $name; ?>]" type="text" id="<?php echo $name; ?>" value="<?php echo esc_attr( $value ); ?>" size="40" <?php disabled( $disabled ); ?> /></td>
190+
<?php endif; ?>
191+
</tr>
192+
<?php
191193
} // End foreach.
192194

193195
/**

src/wp-admin/options.php

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -400,56 +400,57 @@
400400
$options = $wpdb->get_results( "SELECT * FROM $wpdb->options ORDER BY option_name" );
401401

402402
foreach ( (array) $options as $option ) :
403-
$disabled = false;
404-
405403
if ( '' === $option->option_name ) {
406404
continue;
407405
}
408406

409-
if ( 'home' === $option->option_name && defined( 'WP_HOME' ) ) {
410-
$disabled = true;
411-
}
407+
$value = $option->option_value;
408+
$disabled = false;
409+
$is_serialized = false;
412410

413-
if ( 'siteurl' === $option->option_name && defined( 'WP_SITEURL' ) ) {
411+
if ( ( 'home' === $option->option_name && defined( 'WP_HOME' ) )
412+
|| ( 'siteurl' === $option->option_name && defined( 'WP_SITEURL' ) )
413+
) {
414414
$disabled = true;
415415
}
416416

417-
if ( is_serialized( $option->option_value ) ) {
418-
if ( is_serialized_string( $option->option_value ) ) {
419-
// This is a serialized string, so we should display it.
420-
$value = maybe_unserialize( $option->option_value );
417+
if ( is_serialized( $value ) ) {
418+
if ( is_serialized_string( $value ) ) {
419+
// Serialized strings can be safely displayed and edited as their unserialized form.
420+
$value = maybe_unserialize( $value );
421421
$options_to_update[] = $option->option_name;
422422
} else {
423-
$value = 'SERIALIZED DATA';
424-
$disabled = true;
423+
// Other serialized values (arrays, objects) are shown raw, read-only, inside a collapsible <details>.
424+
$disabled = true;
425+
$is_serialized = true;
425426
}
426427
} elseif ( str_starts_with( $option->option_name, 'connectors_' )
427428
&& str_ends_with( $option->option_name, '_api_key' )
428429
) {
429430
// Mask connector API keys and prevent updates from this screen.
430-
$value = _wp_connectors_mask_api_key( $option->option_value );
431+
$value = _wp_connectors_mask_api_key( $value );
431432
$disabled = true;
432433
} else {
433-
$value = $option->option_value;
434434
$options_to_update[] = $option->option_name;
435435
}
436436

437-
$class = 'all-options';
438-
439-
if ( $disabled ) {
440-
$class .= ' disabled';
441-
}
442-
443-
$name = esc_attr( $option->option_name );
437+
$class = 'all-options' . ( $disabled ? ' disabled' : '' );
438+
$name = esc_attr( $option->option_name );
444439
?>
445440
<tr>
446441
<th scope="row"><label for="<?php echo $name; ?>"><?php echo esc_html( $option->option_name ); ?></label></th>
447-
<td>
448-
<?php if ( str_contains( $value, "\n" ) ) : ?>
449-
<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" cols="30" rows="5"><?php echo esc_textarea( $value ); ?></textarea>
442+
<td>
443+
<?php if ( $is_serialized ) : ?>
444+
<details class="<?php echo $class; ?>">
445+
<summary><?php esc_html_e( 'Serialized data' ); ?></summary>
446+
<textarea class="<?php echo $class; ?>" id="<?php echo $name; ?>" cols="30" rows="5" readonly="readonly"><?php echo esc_textarea( $value ); ?></textarea>
447+
</details>
448+
<?php elseif ( str_contains( $value, "\n" ) ) : ?>
449+
<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" cols="30" rows="5"<?php disabled( $disabled, true ); ?>><?php echo esc_textarea( $value ); ?></textarea>
450450
<?php else : ?>
451451
<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 ); ?> />
452-
<?php endif; ?></td>
452+
<?php endif; ?>
453+
</td>
453454
</tr>
454455
<?php endforeach; ?>
455456
</table>

0 commit comments

Comments
 (0)