PluginProbe
Gutenberg / 8.9.3
Gutenberg v8.9.3
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 8.9.3, at lib/widgets.php

326 lines 11.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 * Registers a wp_area post type.
222 */
223 function gutenberg_create_wp_area_post_type() {
224 register_post_type(
225 'wp_area',
226 array(
227 'description' => __( 'Experimental custom post type that will store block areas referenced by themes.', 'gutenberg' ),
228 'labels' => array(
229 'name' => _x( 'Block Area (Experimental)', 'post type general name', 'gutenberg' ),
230 'singular_name' => _x( 'Block Area (Experimental)', 'post type singular name', 'gutenberg' ),
231 'menu_name' => _x( 'Block Areas', 'admin menu', 'gutenberg' ),
232 'name_admin_bar' => _x( 'Block Area', 'add new on admin bar', 'gutenberg' ),
233 'add_new' => _x( 'Add New', 'Block', 'gutenberg' ),
234 'add_new_item' => __( 'Add New Block Area', 'gutenberg' ),
235 'new_item' => __( 'New Block Area', 'gutenberg' ),
236 'edit_item' => __( 'Edit Block Area', 'gutenberg' ),
237 'view_item' => __( 'View Block Area', 'gutenberg' ),
238 'all_items' => __( 'All Block Areas', 'gutenberg' ),
239 'search_items' => __( 'Search Block Areas', 'gutenberg' ),
240 'not_found' => __( 'No block area found.', 'gutenberg' ),
241 'not_found_in_trash' => __( 'No block areas found in Trash.', 'gutenberg' ),
242 'filter_items_list' => __( 'Filter block areas list', 'gutenberg' ),
243 'items_list_navigation' => __( 'Block areas list navigation', 'gutenberg' ),
244 'items_list' => __( 'Block areas list', 'gutenberg' ),
245 'item_published' => __( 'Block area published.', 'gutenberg' ),
246 'item_published_privately' => __( 'Block area published privately.', 'gutenberg' ),
247 'item_reverted_to_draft' => __( 'Block area reverted to draft.', 'gutenberg' ),
248 'item_scheduled' => __( 'Block area scheduled.', 'gutenberg' ),
249 'item_updated' => __( 'Block area updated.', 'gutenberg' ),
250 ),
251 'public' => false,
252 'show_ui' => false,
253 'show_in_menu' => false,
254 'show_in_rest' => true,
255 'rest_base' => '__experimental/block-areas',
256 'capabilities' => array(
257 'read' => 'edit_posts',
258 'create_posts' => 'edit_theme_options',
259 'edit_posts' => 'edit_theme_options',
260 'edit_published_posts' => 'edit_theme_options',
261 'delete_published_posts' => 'edit_theme_options',
262 'edit_others_posts' => 'edit_theme_options',
263 'delete_others_posts' => 'edit_theme_options',
264 ),
265 'map_meta_cap' => true,
266 'supports' => array(
267 'title',
268 'editor',
269 ),
270 )
271 );
272 }
273 add_action( 'init', 'gutenberg_create_wp_area_post_type' );
274
275 /**
276 * Function to enqueue admin-widgets as part of the block editor assets.
277 */
278 function gutenberg_enqueue_widget_scripts() {
279 wp_enqueue_script( 'admin-widgets' );
280 }
281
282 add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_widget_scripts' );
283
284 /**
285 * Overrides dynamic_sidebar_params to make sure Blocks are not wrapped in <form> tag.
286 *
287 * @param array $arg Dynamic sidebar params.
288 * @return array Updated dynamic sidebar params.
289 */
290 function gutenberg_override_sidebar_params_for_block_widget( $arg ) {
291 if ( 'Block' === $arg[0]['widget_name'] ) {
292 $arg[0]['before_form'] = '';
293 $arg[0]['before_widget_content'] = '<div class="widget-content">';
294 $arg[0]['after_widget_content'] = '</div><form class="block-widget-form">';
295 $arg[0]['after_form'] = '</form>';
296 }
297
298 return $arg;
299 }
300
301 /**
302 * Registers the WP_Widget_Block widget
303 */
304 function gutenberg_register_widgets() {
305 if ( ! gutenberg_use_widgets_block_editor() ) {
306 return;
307 }
308
309 register_widget( 'WP_Widget_Block' );
310 // By default every widget on widgets.php is wrapped with a <form>.
311 // This means that you can sometimes end up with invalid HTML, e.g. when
312 // one of the widgets is a Search block.
313 //
314 // To fix the problem, let's add a filter that moves the form below the actual
315 // widget content.
316 global $pagenow;
317 if ( 'widgets.php' === $pagenow ) {
318 add_filter(
319 'dynamic_sidebar_params',
320 'gutenberg_override_sidebar_params_for_block_widget'
321 );
322 }
323 }
324
325 add_action( 'widgets_init', 'gutenberg_register_widgets' );
326