From 7bc4c8684f511275d966916f078ab10d2c913b91 Mon Sep 17 00:00:00 2001
From: Robert Anderson <noisysocks@git.wordpress.org>
Date: Wed, 23 Jun 2021 01:33:20 +0000
Subject: [PATCH] Widgets: Fix widget preview not working if widget registered
 via a instance

The register_widget function can be called with a class name or a class
instance. Once called with a class instance, the class instance is converted to
hash as used key in array.

Props spacedmonkey, zieladam.


git-svn-id: https://develop.svn.wordpress.org/trunk@51216 602fd350-edb4-49c9-b593-d223f7449a82
---
 src/wp-includes/class-wp-widget-factory.php   | 23 ++++++++++++++++---
 .../class-wp-rest-widget-types-controller.php |  9 ++++----
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/wp-includes/class-wp-widget-factory.php b/src/wp-includes/class-wp-widget-factory.php
index 82eda94e3a..a7554846a2 100644
--- a/src/wp-includes/class-wp-widget-factory.php
+++ b/src/wp-includes/class-wp-widget-factory.php
@@ -112,12 +112,29 @@ class WP_Widget_Factory {
 	 * @return WP_Widget|null
 	 */
 	public function get_widget_object( $id_base ) {
-		foreach ( $this->widgets as $widget_object ) {
+		$key = $this->get_widget_key( $id_base );
+		if ( '' === $key ) {
+			return null;
+		}
+
+		return $this->widgets[ $key ];
+	}
+
+	/**
+	 * Returns the registered key for the given widget type.
+	 *
+	 * @since 5.8.0
+	 *
+	 * @param string $id_base Widget type ID.
+	 * @return string
+	 */
+	public function get_widget_key( $id_base ) {
+		foreach ( $this->widgets as $key => $widget_object ) {
 			if ( $widget_object->id_base === $id_base ) {
-				return $widget_object;
+				return $key;
 			}
 		}
 
-		return null;
+		return '';
 	}
 }
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php
index 9c0837644b..b4ae1da184 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php
@@ -471,6 +471,7 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
 		}
 
 		$serialized_instance = serialize( $instance );
+		$widget_key = $wp_widget_factory->get_widget_key( $id );
 
 		$response = array(
 			'form'     => trim(
@@ -481,7 +482,7 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
 			),
 			'preview'  => trim(
 				$this->get_widget_preview(
-					$widget_object,
+					$widget_key,
 					$instance
 				)
 			),
@@ -503,13 +504,13 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
 	 * Returns the output of WP_Widget::widget() when called with the provided
 	 * instance. Used by encode_form_data() to preview a widget.
 
-	 * @param WP_Widget $widget_object Widget object to call widget() on.
+	 * @param string    $widget   The widget's PHP class name (see class-wp-widget.php).
 	 * @param array     $instance Widget instance settings.
 	 * @return string
 	 */
-	private function get_widget_preview( $widget_object, $instance ) {
+	private function get_widget_preview( $widget, $instance ) {
 		ob_start();
-		the_widget( get_class( $widget_object ), $instance );
+		the_widget( $widget, $instance );
 		return ob_get_clean();
 	}