PluginProbe
Gutenberg / 10.1.1
Gutenberg v10.1.1
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / widgets.php

widgets.php in Gutenberg 10.1.1, at lib/widgets.php

287 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Functions used in making widgets interopable with block editors.
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Checks if a screen containing the block editor is being loaded.
10 *
11 * @return boolean True if a screen containing the block editor is being loaded.
12 */
13 function gutenberg_is_block_editor() {
14 // If get_current_screen does not exist, we are neither in the standard block editor for posts, or the widget block editor.
15 // We can safely return false.
16 if ( ! function_exists( 'get_current_screen' ) ) {
17 return false;
18 }
19 $screen = get_current_screen();
20 return ! empty( $screen ) &&
21 (
22 $screen->is_block_editor() ||
23 'appearance_page_gutenberg-widgets' === $screen->id ||
24 ( function_exists( 'gutenberg_is_edit_site_page' ) && gutenberg_is_edit_site_page( $screen->id ) )
25 );
26 }
27
28 /**
29 * Whether or not to use the block editor to manage widgets. Defaults to true
30 * unless a theme has removed support for widgets-block-editor or a plugin has
31 * filtered the return value of this function.
32 *
33 * @return boolean Whether or not to use the block editor to manage widgets.
34 */
35 function gutenberg_use_widgets_block_editor() {
36 /**
37 * Filters whether or not to use the block editor to manage widgets.
38 *
39 * @param boolean $use_widgets_block_editor Whether or not to use the block editor to manage widgets.
40 */
41 return apply_filters(
42 'gutenberg_use_widgets_block_editor',
43 get_theme_support( 'widgets-block-editor' )
44 );
45 }
46
47 /**
48 * Emulates the Widgets screen `admin_print_styles` when at the block editor
49 * screen.
50 */
51 function gutenberg_block_editor_admin_print_styles() {
52 if ( gutenberg_is_block_editor() ) {
53 /** This action is documented in wp-admin/admin-footer.php */
54 // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
55 do_action( 'admin_print_styles-widgets.php' );
56 }
57 }
58 add_action( 'admin_print_styles', 'gutenberg_block_editor_admin_print_styles' );
59
60 /**
61 * Emulates the Widgets screen `admin_print_scripts` when at the block editor
62 * screen.
63 */
64 function gutenberg_block_editor_admin_print_scripts() {
65 if ( gutenberg_is_block_editor() ) {
66 /** This action is documented in wp-admin/includes/ajax-actions.php */
67 do_action( 'load-widgets.php' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
68 /** This action is documented in wp-admin/includes/ajax-actions.php */
69 do_action( 'widgets.php' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
70 /** This action is documented in wp-admin/widgets.php */
71 do_action( 'sidebar_admin_setup' );
72 // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
73 do_action( 'admin_print_scripts-widgets.php' );
74 }
75 }
76 add_action( 'admin_print_scripts', 'gutenberg_block_editor_admin_print_scripts' );
77
78 /**
79 * Emulates the Widgets screen `admin_print_footer_scripts` when at the block
80 * editor screen.
81 */
82 function gutenberg_block_editor_admin_print_footer_scripts() {
83 if ( gutenberg_is_block_editor() ) {
84 /** This action is documented in wp-admin/admin-footer.php */
85 // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
86 do_action( 'admin_print_footer_scripts-widgets.php' );
87 }
88 }
89 add_action( 'admin_print_footer_scripts', 'gutenberg_block_editor_admin_print_footer_scripts' );
90
91 /**
92 * Emulates the Widgets screen `admin_footer` when at the block editor screen.
93 */
94 function gutenberg_block_editor_admin_footer() {
95 if ( gutenberg_is_block_editor() ) {
96 /** This action is documented in wp-admin/admin-footer.php */
97 // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
98 do_action( 'admin_footer-widgets.php' );
99 }
100 }
101 add_action( 'admin_footer', 'gutenberg_block_editor_admin_footer' );
102
103 /**
104 * Adds a save widgets nonce required by the legacy widgets block.
105 */
106 function gutenberg_print_save_widgets_nonce() {
107 // The function wpWidgets.save needs this nonce to work as expected.
108 echo implode(
109 "\n",
110 array(
111 '<form method="post">',
112 wp_nonce_field( 'save-sidebar-widgets', '_wpnonce_widgets', false ),
113 '</form>',
114 )
115 );
116 }
117 add_action( 'admin_footer-widgets.php', 'gutenberg_print_save_widgets_nonce' );
118
119
120 /**
121 * Returns the settings required by legacy widgets blocks.
122 *
123 * @return array Legacy widget settings.
124 */
125 function gutenberg_get_legacy_widget_settings() {
126 $settings = array();
127
128 /**
129 * Filters the list of widget classes that should **not** be offered by the legacy widget block.
130 *
131 * Returning an empty array will make all the widgets available.
132 *
133 * @param array $widgets An array of excluded widgets classnames.
134 *
135 * @since 5.6.0
136 */
137 $widgets_to_exclude_from_legacy_widget_block = apply_filters(
138 'widgets_to_exclude_from_legacy_widget_block',
139 array(
140 'WP_Widget_Block',
141 'WP_Widget_Pages',
142 'WP_Widget_Calendar',
143 'WP_Widget_Archives',
144 'WP_Widget_Media_Audio',
145 'WP_Widget_Media_Image',
146 'WP_Widget_Media_Gallery',
147 'WP_Widget_Media_Video',
148 'WP_Widget_Meta',
149 'WP_Widget_Search',
150 'WP_Widget_Text',
151 'WP_Widget_Categories',
152 'WP_Widget_Recent_Posts',
153 'WP_Widget_Recent_Comments',
154 'WP_Widget_RSS',
155 'WP_Widget_Tag_Cloud',
156 'WP_Nav_Menu_Widget',
157 'WP_Widget_Custom_HTML',
158 )
159 );
160
161 $available_legacy_widgets = array();
162 global $wp_widget_factory;
163 if ( ! empty( $wp_widget_factory ) ) {
164 foreach ( $wp_widget_factory->widgets as $class => $widget_obj ) {
165 $available_legacy_widgets[ $class ] = array(
166 'name' => html_entity_decode( $widget_obj->name ),
167 'id_base' => $widget_obj->id_base,
168 // wp_widget_description is not being used because its input parameter is a Widget Id.
169 // Widgets id's reference to a specific widget instance.
170 // Here we are iterating on all the available widget classes even if no widget instance exists for them.
171 'description' => isset( $widget_obj->widget_options['description'] ) ?
172 html_entity_decode( $widget_obj->widget_options['description'] ) :
173 null,
174 'isReferenceWidget' => false,
175 'isHidden' => in_array( $class, $widgets_to_exclude_from_legacy_widget_block, true ),
176 );
177 }
178 }
179 global $wp_registered_widgets;
180 if ( ! empty( $wp_registered_widgets ) ) {
181 foreach ( $wp_registered_widgets as $widget_id => $widget_obj ) {
182
183 $block_widget_start = 'blocks-widget-';
184 if (
185 ( is_array( $widget_obj['callback'] ) &&
186 isset( $widget_obj['callback'][0] ) &&
187 ( $widget_obj['callback'][0] instanceof WP_Widget ) ) ||
188 // $widget_id starts with $block_widget_start.
189 strncmp( $widget_id, $block_widget_start, strlen( $block_widget_start ) ) === 0
190 ) {
191 continue;
192 }
193 $available_legacy_widgets[ $widget_id ] = array(
194 'name' => html_entity_decode( $widget_obj['name'] ),
195 'description' => html_entity_decode( wp_widget_description( $widget_id ) ),
196 'isReferenceWidget' => true,
197 );
198 }
199 }
200
201 $settings['availableLegacyWidgets'] = $available_legacy_widgets;
202
203 return $settings;
204 }
205
206 /**
207 * Extends default editor settings with values supporting legacy widgets.
208 *
209 * @param array $settings Default editor settings.
210 *
211 * @return array Filtered editor settings.
212 */
213 function gutenberg_legacy_widget_settings( $settings ) {
214 return array_merge( $settings, gutenberg_get_legacy_widget_settings() );
215 }
216 add_filter( 'block_editor_settings', 'gutenberg_legacy_widget_settings' );
217
218 /**
219 * Function to enqueue admin-widgets as part of the block editor assets.
220 */
221 function gutenberg_enqueue_widget_scripts() {
222 wp_enqueue_script( 'admin-widgets' );
223 }
224
225 add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_widget_scripts' );
226
227 /**
228 * Overrides dynamic_sidebar_params to make sure Blocks are not wrapped in <form> tag.
229 *
230 * @param array $arg Dynamic sidebar params.
231 * @return array Updated dynamic sidebar params.
232 */
233 function gutenberg_override_sidebar_params_for_block_widget( $arg ) {
234 if ( 'Block' === $arg[0]['widget_name'] ) {
235 $arg[0]['before_form'] = '';
236 $arg[0]['before_widget_content'] = '<div class="widget-content">';
237 $arg[0]['after_widget_content'] = '</div><form class="block-widget-form">';
238 $arg[0]['after_form'] = '</form>';
239 }
240
241 return $arg;
242 }
243
244 /**
245 * Registers the WP_Widget_Block widget
246 */
247 function gutenberg_register_widgets() {
248 if ( ! gutenberg_use_widgets_block_editor() ) {
249 return;
250 }
251
252 register_widget( 'WP_Widget_Block' );
253 // By default every widget on widgets.php is wrapped with a <form>.
254 // This means that you can sometimes end up with invalid HTML, e.g. when
255 // one of the widgets is a Search block.
256 //
257 // To fix the problem, let's add a filter that moves the form below the actual
258 // widget content.
259 global $pagenow;
260 if ( 'widgets.php' === $pagenow ) {
261 add_filter(
262 'dynamic_sidebar_params',
263 'gutenberg_override_sidebar_params_for_block_widget'
264 );
265 }
266 }
267
268 add_action( 'widgets_init', 'gutenberg_register_widgets' );
269
270 /**
271 * Hook into before the widgets editor screen is loaded and, if widget-preview
272 * is set, render the requested preview of a legacy widget instead. This powers
273 * the Preview option in the Legacy Widget block.
274 */
275 function gutenberg_load_widget_preview_if_requested() {
276 if (
277 isset( $_GET['widget-preview'] ) &&
278 current_user_can( 'edit_theme_options' )
279 ) {
280 define( 'IFRAME_REQUEST', true );
281 require_once __DIR__ . '/widget-preview-template.php';
282 exit;
283 }
284 }
285 add_filter( 'load-appearance_page_gutenberg-widgets', 'gutenberg_load_widget_preview_if_requested' );
286
287