PluginProbe
Gutenberg / 9.1.0
Gutenberg v9.1.0
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 9.1.0, at lib/widgets.php

292 lines 9.5 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 $has_permissions_to_manage_widgets = current_user_can( 'edit_theme_options' );
162 $available_legacy_widgets = array();
163 global $wp_widget_factory;
164 if ( ! empty( $wp_widget_factory ) ) {
165 foreach ( $wp_widget_factory->widgets as $class => $widget_obj ) {
166 $available_legacy_widgets[ $class ] = array(
167 'name' => html_entity_decode( $widget_obj->name ),
168 'id_base' => $widget_obj->id_base,
169 // wp_widget_description is not being used because its input parameter is a Widget Id.
170 // Widgets id's reference to a specific widget instance.
171 // Here we are iterating on all the available widget classes even if no widget instance exists for them.
172 'description' => isset( $widget_obj->widget_options['description'] ) ?
173 html_entity_decode( $widget_obj->widget_options['description'] ) :
174 null,
175 'isReferenceWidget' => false,
176 'isHidden' => in_array( $class, $widgets_to_exclude_from_legacy_widget_block, true ),
177 );
178 }
179 }
180 global $wp_registered_widgets;
181 if ( ! empty( $wp_registered_widgets ) ) {
182 foreach ( $wp_registered_widgets as $widget_id => $widget_obj ) {
183
184 $block_widget_start = 'blocks-widget-';
185 if (
186 ( is_array( $widget_obj['callback'] ) &&
187 isset( $widget_obj['callback'][0] ) &&
188 ( $widget_obj['callback'][0] instanceof WP_Widget ) ) ||
189 // $widget_id starts with $block_widget_start.
190 strncmp( $widget_id, $block_widget_start, strlen( $block_widget_start ) ) === 0
191 ) {
192 continue;
193 }
194 $available_legacy_widgets[ $widget_id ] = array(
195 'name' => html_entity_decode( $widget_obj['name'] ),
196 'description' => html_entity_decode( wp_widget_description( $widget_id ) ),
197 'isReferenceWidget' => true,
198 );
199 }
200 }
201
202 $settings['hasPermissionsToManageWidgets'] = $has_permissions_to_manage_widgets;
203 $settings['availableLegacyWidgets'] = $available_legacy_widgets;
204
205 return gutenberg_experiments_editor_settings( $settings );
206 }
207
208 /**
209 * Extends default editor settings with values supporting legacy widgets.
210 *
211 * @param array $settings Default editor settings.
212 *
213 * @return array Filtered editor settings.
214 */
215 function gutenberg_legacy_widget_settings( $settings ) {
216 return array_merge( $settings, gutenberg_get_legacy_widget_settings() );
217 }
218 add_filter( 'block_editor_settings', 'gutenberg_legacy_widget_settings' );
219
220 /**
221 * Function to enqueue admin-widgets as part of the block editor assets.
222 */
223 function gutenberg_enqueue_widget_scripts() {
224 wp_enqueue_script( 'admin-widgets' );
225 }
226
227 add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_widget_scripts' );
228
229 /**
230 * Overrides dynamic_sidebar_params to make sure Blocks are not wrapped in <form> tag.
231 *
232 * @param array $arg Dynamic sidebar params.
233 * @return array Updated dynamic sidebar params.
234 */
235 function gutenberg_override_sidebar_params_for_block_widget( $arg ) {
236 if ( 'Block' === $arg[0]['widget_name'] ) {
237 $arg[0]['before_form'] = '';
238 $arg[0]['before_widget_content'] = '<div class="widget-content">';
239 $arg[0]['after_widget_content'] = '</div><form class="block-widget-form">';
240 $arg[0]['after_form'] = '</form>';
241 }
242
243 return $arg;
244 }
245
246 /**
247 * Registers the WP_Widget_Block widget
248 */
249 function gutenberg_register_widgets() {
250 if ( ! gutenberg_use_widgets_block_editor() ) {
251 return;
252 }
253
254 register_widget( 'WP_Widget_Block' );
255 // By default every widget on widgets.php is wrapped with a <form>.
256 // This means that you can sometimes end up with invalid HTML, e.g. when
257 // one of the widgets is a Search block.
258 //
259 // To fix the problem, let's add a filter that moves the form below the actual
260 // widget content.
261 global $pagenow;
262 if ( 'widgets.php' === $pagenow ) {
263 add_filter(
264 'dynamic_sidebar_params',
265 'gutenberg_override_sidebar_params_for_block_widget'
266 );
267 }
268 }
269
270 add_action( 'widgets_init', 'gutenberg_register_widgets' );
271
272 /**
273 * Overwrites the template WordPress would use to render the currrent request,
274 * to a widget preview template if widgetPreview parameter was passed in the url.
275 *
276 * @param string $template Original template.
277 *
278 * @return string The original or the path of widget-preview-template.php file.
279 */
280 function change_post_template_to_widget_preview( $template ) {
281 if (
282 isset( $_GET['widgetPreview'] ) &&
283 current_user_can( 'edit_theme_options' )
284 ) {
285 add_filter( 'show_admin_bar', '__return_false' );
286 return dirname( __FILE__ ) . '/widget-preview-template.php';
287 }
288 return $template;
289 }
290 add_filter( 'template_include', 'change_post_template_to_widget_preview' );
291
292