Skip to content

Legacy Widget add support for widgets with attributes that can't be serialised into JSON #28902

@noisysocks

Description

@noisysocks

Description

The Legacy Widget block will choke when used with a widget that has an instance attribute which can't be serialised into JSON. WordPress supports storing any PHP value in a widget's instance attributes.

Step-by-step reproduction instructions

  1. Add the following code to a plugin file e.g. gutenberg.php:
class Date_Widget extends WP_Widget {
	protected $default_instance = array(
		'date' => null,
	);

	public function __construct() {
		$widget_ops  = array(
			'classname'                   => 'widget_date',
			'description'                 => __( 'A date.', 'gutenberg' ),
			'customize_selective_refresh' => true,
		);
		$control_ops = array(
			'width'  => 200,
			'height' => 350,
		);
		parent::__construct( 'date', __( 'Date', 'gutenberg' ), $widget_ops, $control_ops );
	}

	public function widget( $args, $instance ) {
		echo $args['before_widget'];
		if ( $instance['date'] ) {
			echo $instance['date']->format( 'c' );
		}
		echo $args['after_widget'];
	}

	public function update( $new_instance, $old_instance ) {
		$instance = array_merge( $this->default_instance, $old_instance );
		if ( $new_instance['date'] ) {
			$instance['date'] = DateTime::createFromFormat( 'Y-m-d', $new_instance['date'] );
		} else {
			$instance['date'] = null;
		}
		return $instance;
	}

	public function form( $instance ) {
		$instance = wp_parse_args( (array) $instance, $this->default_instance );
		?>
		<p>
			<label for="<?php echo $this->get_field_id( 'date' ); ?>">Date:</label>
			<input
				id="<?php echo $this->get_field_id( 'date' ); ?>"
				class="widefat"
				name="<?php echo $this->get_field_name( 'date' ); ?>"
				type="date"
				value="<?php echo $instance['date'] ? $instance['date']->format( 'Y-m-d' ) : ''; ?>"
			/>
		</p>
		<?php
	}
}
add_action(
	'widgets_init',
	function() {
		register_widget( 'Date_Widget' );
	}
);
  1. Navigate to Appearance → Widgets.

  2. Use the insert to add a Date legacy widget.

  3. Set a date and press Update.

  4. Refresh the page.

Expected behaviour

The Date legacy widget should be in the editor and display the date that was set.

Actual behaviour

The Date legacy widget is missing from the editor and there are network errors in DevTools.

Screenshots or screen recording (optional)

Kapture 2021-02-10 at 11 18 56

WordPress information

  • WordPress version: trunk
  • Gutenberg version: master
  • Are all plugins except Gutenberg deactivated? Yes
  • Are you using a default theme (e.g. Twenty Twenty-One)? Yes

Metadata

Metadata

Assignees

Labels

REST API InteractionRelated to REST API[Block] Legacy WidgetAffects the Legacy Widget Block - used for displaying Classic Widgets[Feature] Widgets CustomizerAbility to add and edit blocks in Customize → Widgets.[Feature] Widgets ScreenThe block-based screen that replaced widgets.php.[Type] BugAn existing feature does not function as intended

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions