From 2f4d6d79e02363de66aa9a74d3bdcb3d05260855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Mon, 19 Jul 2021 18:17:35 +0200 Subject: [PATCH 01/19] First stab at the legacy widget rendering endpoint --- src/wp-includes/blocks/legacy-widget.php | 49 +++++++++++++++++++ .../class-wp-rest-widget-types-controller.php | 35 +++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/wp-includes/blocks/legacy-widget.php b/src/wp-includes/blocks/legacy-widget.php index e827f8f7c5309..1fe33b49c7009 100644 --- a/src/wp-includes/blocks/legacy-widget.php +++ b/src/wp-includes/blocks/legacy-widget.php @@ -132,3 +132,52 @@ function handle_legacy_widget_preview_iframe() { // This isn't strictly required, but enables better compatibility with existing plugins. // See: https://github.com/WordPress/gutenberg/issues/32624. add_action( 'admin_init', 'handle_legacy_widget_preview_iframe', 20 ); + + +/** + * Intercepts any request with legacy-widget-preview in the query param and, if + * set, renders a page containing a preview of the requested Legacy Widget + * block. + */ +function render_legacy_widget_preview_iframe( $id_base, $instance ) { + if ( ! current_user_can( 'edit_theme_options' ) ) { + return ""; + } + + define( 'IFRAME_REQUEST', true ); + + ob_start(); + ?> + + > + + + + + + + + > +
+
+ get_registered( 'core/legacy-widget' ); + echo $block->render( [ 'id_base' => $id_base, 'instance' => $instance ] ); + ?> +
+
+ + + + namespace, + '/' . $this->rest_base . '/(?P[a-zA-Z0-9_-]+)/render', + array( + array( + 'methods' => WP_REST_Server::CREATABLE, + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'callback' => array( $this, 'render' ), + 'args' => array( + 'id_base' => array( + 'description' => __( 'The widget type id.' ), + 'type' => 'string', + 'required' => true, + ), + 'instance' => array( + 'description' => __( 'Current instance settings of the widget.' ), + 'type' => 'object', + ), + ), + ), + ) + ); } /** @@ -249,6 +272,9 @@ protected function get_widgets() { * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { + // Some third-party widgets rely on wp-admin functions so let's load them before rendering the preview. + require_once ABSPATH . 'wp-admin/includes/admin.php'; + $widget_id = $request['id']; $widget_type = $this->get_widget( $widget_id ); if ( is_wp_error( $widget_type ) ) { @@ -397,6 +423,15 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } + public function render( $request ) { + return [ + "preview" => render_legacy_widget_preview_iframe( + $request['id_base'], + $request['instance'] + ), + ]; + } + /** * An RPC-style endpoint which can be used by clients to turn user input in * a widget admin form into an encoded instance object. From 9015a895f1fe91867a89c4bfbad160ac6d0ab0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Tue, 27 Jul 2021 16:22:50 +0200 Subject: [PATCH 02/19] Render the previewed block --- src/wp-includes/blocks/legacy-widget.php | 6 +++--- tests/phpunit/tests/rest-api/rest-schema-setup.php | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/blocks/legacy-widget.php b/src/wp-includes/blocks/legacy-widget.php index 1fe33b49c7009..5c9b8e8669534 100644 --- a/src/wp-includes/blocks/legacy-widget.php +++ b/src/wp-includes/blocks/legacy-widget.php @@ -154,7 +154,7 @@ function render_legacy_widget_preview_iframe( $id_base, $instance ) { - + - - > -
-
- get_registered( 'core/legacy-widget' ); - echo $block->render( array( 'idBase' => $id_base, 'instance' => $instance ) ); - ?> -
-
- - - - render_legacy_widget_preview_iframe( + 'preview' => $this->render_legacy_widget_preview_iframe( $request['id_base'], $request['instance'] ), ); } + /** + * Renders a page containing a preview of the requested Legacy Widget block. + * + * @param string $id_base The id base of the requested widget. + * @param array $instance The widget instance attributes. + * + * @return string Rendered Legacy Widget block preview. + */ + private function render_legacy_widget_preview_iframe( $id_base, $instance ) { + if ( ! current_user_can( 'edit_theme_options' ) ) { + return ""; + } + + define( 'IFRAME_REQUEST', true ); + + ob_start(); + ?> + + > + + + + + + + + > +
+
+ get_registered( 'core/legacy-widget' ); + echo $block->render( array( 'idBase' => $id_base, 'instance' => $instance ) ); + ?> +
+
+ + + + Date: Tue, 17 Aug 2021 15:22:16 +0200 Subject: [PATCH 11/19] Lint --- .../class-wp-rest-widget-types-controller.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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 6bead972d111d..9a506a523a2b5 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 @@ -108,13 +108,13 @@ public function register_routes() { 'methods' => WP_REST_Server::CREATABLE, 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'callback' => array( $this, 'render' ), - 'args' => array( - 'id_base' => array( + 'args' => array( + 'id_base' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', 'required' => true, ), - 'instance' => array( + 'instance' => array( 'description' => __( 'Current instance settings of the widget.' ), 'type' => 'object', ), @@ -442,7 +442,7 @@ public function render( $request ) { */ private function render_legacy_widget_preview_iframe( $id_base, $instance ) { if ( ! current_user_can( 'edit_theme_options' ) ) { - return ""; + return ''; } define( 'IFRAME_REQUEST', true ); @@ -470,7 +470,12 @@ private function render_legacy_widget_preview_iframe( $id_base, $instance ) { get_registered( 'core/legacy-widget' ); - echo $block->render( array( 'idBase' => $id_base, 'instance' => $instance ) ); + echo $block->render( + array( + 'idBase' => $id_base, + 'instance' => $instance, + ) + ); ?> From b0b6cb921792254fd9ba4d93a2263c17638d0670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Tue, 17 Aug 2021 15:58:25 +0200 Subject: [PATCH 12/19] Do not require `admin.php` in get_item endpoint --- .../endpoints/class-wp-rest-widget-types-controller.php | 3 --- 1 file changed, 3 deletions(-) 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 9a506a523a2b5..68807a1d2e5a3 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 @@ -272,9 +272,6 @@ protected function get_widgets() { * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { - // Some third-party widgets rely on wp-admin functions so let's load them before rendering the preview. - require_once ABSPATH . 'wp-admin/includes/admin.php'; - $widget_id = $request['id']; $widget_type = $this->get_widget( $widget_id ); if ( is_wp_error( $widget_type ) ) { From b68680383c3c371f58517411565fc764ad786647 Mon Sep 17 00:00:00 2001 From: Adam Zielinski Date: Wed, 18 Aug 2021 12:31:59 +0200 Subject: [PATCH 13/19] Update src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php Co-authored-by: Anton Vlasenko <43744263+anton-vlasenko@users.noreply.github.com> --- .../endpoints/class-wp-rest-widget-types-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 68807a1d2e5a3..47ed73e96b2db 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 @@ -424,7 +424,7 @@ public function render( $request ) { return array( 'preview' => $this->render_legacy_widget_preview_iframe( $request['id_base'], - $request['instance'] + isset($request['instance']) ? $request['instance'] : null ), ); } From 0f8aafa25a714837a250b4796591d2b719189ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Wed, 18 Aug 2021 12:42:43 +0200 Subject: [PATCH 14/19] lint --- .../endpoints/class-wp-rest-widget-types-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 47ed73e96b2db..584250623875e 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 @@ -424,7 +424,7 @@ public function render( $request ) { return array( 'preview' => $this->render_legacy_widget_preview_iframe( $request['id_base'], - isset($request['instance']) ? $request['instance'] : null + isset( $request['instance'] ) ? $request['instance'] : null ), ); } From cf391c79d6fc7ff6b78753e2256faf2dda345580 Mon Sep 17 00:00:00 2001 From: Adam Zielinski Date: Fri, 20 Aug 2021 11:26:30 +0200 Subject: [PATCH 15/19] Update src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php Co-authored-by: Timothy Jacobs --- .../endpoints/class-wp-rest-widget-types-controller.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 584250623875e..15373fb33fdcd 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 @@ -480,9 +480,7 @@ private function render_legacy_widget_preview_iframe( $id_base, $instance ) { Date: Fri, 20 Aug 2021 11:56:02 +0200 Subject: [PATCH 16/19] Add a defined() check for IFRAME_REQUEST constant --- .../endpoints/class-wp-rest-widget-types-controller.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 15373fb33fdcd..d236e425dffbf 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 @@ -442,7 +442,9 @@ private function render_legacy_widget_preview_iframe( $id_base, $instance ) { return ''; } - define( 'IFRAME_REQUEST', true ); + if ( ! defined( 'IFRAME_REQUEST' ) ) { + define( 'IFRAME_REQUEST', true ); + } ob_start(); ?> From a200fea0321a3cbe262c55167ae3dbc00619f2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 20 Aug 2021 11:57:19 +0200 Subject: [PATCH 17/19] Add @since to render_legacy_widget_preview_iframe --- .../rest-api/endpoints/class-wp-rest-widget-types-controller.php | 1 + 1 file changed, 1 insertion(+) 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 d236e425dffbf..018bed9c60d2c 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 @@ -434,6 +434,7 @@ public function render( $request ) { * * @param string $id_base The id base of the requested widget. * @param array $instance The widget instance attributes. + * @since 5.8.1 * * @return string Rendered Legacy Widget block preview. */ From 9a542a3ca2a5f19bdc39565199313b59a500fb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 20 Aug 2021 12:10:18 +0200 Subject: [PATCH 18/19] Add docstring to render() --- .../endpoints/class-wp-rest-widget-types-controller.php | 8 ++++++++ 1 file changed, 8 insertions(+) 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 018bed9c60d2c..e35292a8b88f2 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 @@ -420,6 +420,14 @@ public function get_item_schema() { return $this->add_additional_fields_schema( $this->schema ); } + /** + * Renders a single Legacy Widget and wraps it in a JSON-encodable array. + * + * @param WP_REST_Request $request Full details about the request. + * @since 5.8.1 + * + * @return array An array with rendered Legacy Widget HTML. + */ public function render( $request ) { return array( 'preview' => $this->render_legacy_widget_preview_iframe( From 9bb40881b14e3d7443678723c73b15c561f5f98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 20 Aug 2021 12:11:41 +0200 Subject: [PATCH 19/19] Remove explicit permission check and rely on the configured get_item_permission_callback value --- .../endpoints/class-wp-rest-widget-types-controller.php | 4 ---- 1 file changed, 4 deletions(-) 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 e35292a8b88f2..92a175417fa9f 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 @@ -447,10 +447,6 @@ public function render( $request ) { * @return string Rendered Legacy Widget block preview. */ private function render_legacy_widget_preview_iframe( $id_base, $instance ) { - if ( ! current_user_can( 'edit_theme_options' ) ) { - return ''; - } - if ( ! defined( 'IFRAME_REQUEST' ) ) { define( 'IFRAME_REQUEST', true ); }