Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 53 additions & 13 deletions src/wp-admin/options.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,17 +414,14 @@
}

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 );
$options_to_update[] = $option->option_name;
} else {
$value = 'SERIALIZED DATA';
$disabled = true;
}
$value = maybe_unserialize( $option->option_value );
$disabled = true;
$options_to_update[] = $option->option_name;
$is_serialized = true;
} else {
$value = $option->option_value;
$options_to_update[] = $option->option_name;
$is_serialized = false;
}

$class = 'all-options';
Expand All @@ -438,11 +435,35 @@
<tr>
<th scope="row"><label for="<?php echo $name; ?>"><?php echo esc_html( $option->option_name ); ?></label></th>
<td>
<?php if ( str_contains( $value, "\n" ) ) : ?>
<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" cols="30" rows="5"><?php echo esc_textarea( $value ); ?></textarea>
<?php else : ?>
<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 ); ?> />
<?php endif; ?></td>
<?php if ( $is_serialized && ( is_array( $value ) || is_object( $value ) ) ) : ?>
<button
type="button"
class="toggle-serialized button button-secondary"
data-target="opt-<?php echo esc_attr( $name ); ?>">
Show (SERIALIZED DATA)
</button>

<pre
id="opt-<?php echo esc_attr( $name ); ?>"
style="display:none; margin-top:8px; max-height:300px; overflow:auto; background:#f6f7f7; padding:10px;">
<?php echo esc_html( print_r( $value, true ) ); ?>

Check failure on line 449 in src/wp-admin/options.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Line indented incorrectly; expected at least 2 tabs, found 0
</pre>

<?php elseif ( str_contains( (string) $value, "\n" ) ) : ?>
<textarea
class="<?php echo $class; ?>"
disabled="disabled"
cols="30"
rows="5"><?php echo esc_textarea( $value ); ?></textarea>

<?php else : ?>
<input
class="regular-text <?php echo $class; ?>"
type="text"
value="<?php echo esc_attr( $value ); ?>"
disabled="disabled" />
<?php endif; ?>

</tr>
<?php endforeach; ?>
Comment on lines 416 to 468

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$value = $option->option_value;
$options_to_update[] = $option->option_name;
$is_serialized = false;
if ( is_serialized( $option->option_value ) ) {
$disabled = true;
$is_serialized = true;
}
$class = 'all-options';
if ( $disabled ) {
$class .= ' disabled';
}
$name = esc_attr( $option->option_name );
?>
<tr>
<th scope="row"><label
for="<?php echo $name; ?>"><?php echo esc_html( $option->option_name ); ?></label></th>
<td>
<?php if ( $is_serialized ) : ?>
<details name="<?php echo $name; ?>" class="<?php echo $class; ?>">
<summary>SERIALIZED DATA</summary>
<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>"
id="<?php echo $name; ?>" cols="30" rows="5"
disabled="disabled"><?php echo esc_textarea( $value ); ?></textarea>
</details>
<?php elseif ( str_contains( $value, "\n" ) ) : ?>
<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>"
id="<?php echo $name; ?>" cols="30"
rows="5"><?php echo esc_textarea( $value ); ?></textarea>
<?php else : ?>
<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 ); ?> />
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>

</table>
Expand All @@ -454,5 +475,24 @@
</form>
</div>

<script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we place this JavaScript in an external file and load it via wp_enqueue_script() for better maintainability?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should first wait for a dev feedback on the feasibility of this overall concept. Then we can talk about the specific details.

Copy link

@anatolinicolae anatolinicolae Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about a native approach instead? Like relying on the <details> tag that basically does the same thing as this JS. I'll give it a try locally later anyway 👍

Copy link

@anatolinicolae anatolinicolae Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch looks good, but I'm unsure if we want to unserialize the fields. I would stick to raw values thrown into a textarea but maybe_unserialize makes sense if we disable saving.

<details> version is decent enough for debugging purpose, but we can stick to the cooler "Show serialized value" button for a more native look and feel.

image
	...

	$value               = $option->option_value;
	$options_to_update[] = $option->option_name;
	$is_serialized       = false;
	$class               = 'all-options';

	if ( is_serialized( $option->option_value ) ) {
		$disabled      = true;
		$is_serialized = true;
		$class        .= ' disabled';
	}

	$name = esc_attr($option->option_name);
?>
	<tr>
		<th scope="row"><label for="<?php echo $name; ?>"><?php echo esc_html($option->option_name); ?></label></th>
		<td>
			<?php if ($is_serialized) : ?>
				<details name="<?php echo $name; ?>" class="<?php echo $class; ?>">
					<summary>SERIALIZED DATA</summary>
					<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" cols="30" rows="5" disabled="disabled"><?php echo esc_textarea( $value ); ?></textarea>
				</details>
			<?php elseif ( str_contains( $value, "\n" ) ) : ?>
				<textarea class="<?php echo $class; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" cols="30" rows="5"><?php echo esc_textarea( $value ); ?></textarea>
			<?php else : ?>
				<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 ); ?> />
			<?php endif; ?>
		</td>
	</tr>
<?php endforeach; ?>

Similarly for network's site-settings.php:

image
$value         = $option->option_value;
$is_serialized = false;
$disabled      = false;
$class         = 'all-options';

if ( is_serialized( $option->option_value ) ) {
	$is_serialized = true;
	$disabled      = true;
	$class        .= ' disabled';
}

if ( $is_serialized ) {
	?>
	<tr class="form-field">
		<th scope="row"><label for="<?php echo esc_attr( $option->option_name ); ?>" class="code"><?php echo esc_html( $option->option_name ); ?></label></th>
		<td>
			<details name="<?php echo esc_attr( $option->option_name ); ?>" class="<?php echo $class; ?>">
				<summary>SERIALIZED DATA</summary>
				<textarea class="<?php echo $class; ?>" name="option[<?php echo esc_attr( $option->option_name ); ?>]" id="<?php echo esc_attr( $option->option_name ); ?>" cols="30" rows="5" disabled="disabled"><?php echo esc_textarea( $value ); ?></textarea>
			</details>
		</td>
	</tr>
	<?php
} elseif ( str_contains( $value, "\n" ) ) {
	?>
	<tr class="form-field">
		<th scope="row"><label for="<?php echo esc_attr( $option->option_name ); ?>" class="code"><?php echo esc_html( $option->option_name ); ?></label></th>
		<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( $value ); ?></textarea></td>
	</tr>
	<?php
} else {
	?>
	<tr class="form-field">
		<th scope="row"><label for="<?php echo esc_attr( $option->option_name ); ?>" class="code"><?php echo esc_html( $option->option_name ); ?></label></th>
		<?php if ( $is_main_site && in_array( $option->option_name, array( 'siteurl', 'home' ), true ) ) { ?>
		<td><code><?php echo esc_html( $value ); ?></code></td>
		<?php } else { ?>
		<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( $value ); ?>" size="40" <?php disabled( $disabled ); ?> /></td>
		<?php } ?>
	</tr>
	<?php
}

document.addEventListener('click', function (e) {
if (!e.target.classList.contains('toggle-serialized')) {
return;
}

const targetId = e.target.getAttribute('data-target');
const el = document.getElementById(targetId);

if (!el) {
return;
}

const open = el.style.display === 'block';
el.style.display = open ? 'none' : 'block';
e.target.textContent = open ? 'Show' : 'Hide';
});
</script>

<?php
require_once ABSPATH . 'wp-admin/admin-footer.php';
Loading