PluginProbe
Gutenberg / 22.3.0
Gutenberg v22.3.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 / experimental / class-wp-rest-block-editor-settings-controller.php

class-wp-rest-block-editor-settings-controller.php in Gutenberg 22.3.0, at lib/experimental/class-wp-rest-block-editor-settings-controller.php

661 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API: WP_REST_Block_Editor_Settings_Controller class
4 *
5 * @package WordPress
6 * @subpackage REST_API
7 */
8
9 if ( ! class_exists( 'WP_REST_Block_Editor_Settings_Controller' ) ) {
10
11 /**
12 * Core class used to retrieve the block editor settings via the REST API.
13 *
14 * @see WP_REST_Controller
15 */
16 class WP_REST_Block_Editor_Settings_Controller extends WP_REST_Controller {
17 /**
18 * Constructs the controller.
19 */
20 public function __construct() {
21 $this->namespace = 'wp-block-editor/v1';
22 $this->rest_base = 'settings';
23 }
24
25 /**
26 * Registers the necessary REST API routes.
27 */
28 public function register_routes() {
29 register_rest_route(
30 $this->namespace,
31 '/' . $this->rest_base,
32 array(
33 array(
34 'methods' => WP_REST_Server::READABLE,
35 'callback' => array( $this, 'get_items' ),
36 'permission_callback' => array( $this, 'get_items_permissions_check' ),
37 ),
38 'schema' => array( $this, 'get_public_item_schema' ),
39 )
40 );
41
42 register_rest_route(
43 $this->namespace,
44 '/assets',
45 array(
46 array(
47 'methods' => WP_REST_Server::READABLE,
48 'callback' => array( $this, 'get_assets' ),
49 'permission_callback' => array( $this, 'get_items_permissions_check' ),
50 ),
51 'schema' => array( $this, 'get_assets_schema' ),
52 )
53 );
54 }
55
56 /**
57 * Checks whether a given request has permission to read block editor settings
58 *
59 * @since 5.8.0
60 *
61 * @param WP_REST_Request $request Full details about the request.
62 *
63 * @return WP_Error|bool True if the request has permission, WP_Error object otherwise.
64 */
65 public function get_items_permissions_check( $request ) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
66 if ( current_user_can( 'edit_posts' ) ) {
67 return true;
68 }
69
70 foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
71 if ( current_user_can( $post_type->cap->edit_posts ) ) {
72 return true;
73 }
74 }
75
76 return new WP_Error(
77 'rest_cannot_read_block_editor_settings',
78 __( 'Sorry, you are not allowed to read the block editor settings.', 'gutenberg' ),
79 array( 'status' => rest_authorization_required_code() )
80 );
81 }
82
83 /**
84 * Returns the block editor's settings
85 *
86 * @since 5.8.0
87 *
88 * @param WP_REST_Request $request Full details about the request.
89 *
90 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
91 */
92 public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis
93 // Simplified context handling: mobile vs default.
94 // Only 'mobile' context is special; everything else uses the default editor context.
95 $context_param = $request->get_param( 'context' );
96 $editor_context_name = 'mobile' === $context_param ? 'core/mobile' : 'core/edit-post';
97
98 // Apply mobile-specific settings filter only for mobile context.
99 if ( 'mobile' === $context_param ) {
100 add_filter( 'block_editor_settings_all', 'gutenberg_get_block_editor_settings_mobile', PHP_INT_MAX );
101 }
102
103 $editor_context = new WP_Block_Editor_Context( array( 'name' => $editor_context_name ) );
104 $settings = get_block_editor_settings( array(), $editor_context );
105
106 if ( 'mobile' === $context_param ) {
107 remove_filter( 'block_editor_settings_all', 'gutenberg_get_block_editor_settings_mobile', PHP_INT_MAX );
108 }
109
110 return rest_ensure_response( $settings );
111 }
112
113 /**
114 * Retrieves the block editor's settings schema, conforming to JSON Schema.
115 *
116 * @since 5.8.0
117 *
118 * @return array Item schema data.
119 */
120 public function get_item_schema() {
121 if ( $this->schema ) {
122 return $this->add_additional_fields_schema( $this->schema );
123 }
124
125 $schema = array(
126 '$schema' => 'http://json-schema.org/draft-04/schema#',
127 'title' => 'block-editor-settings-item',
128 'type' => 'object',
129 'properties' => array(
130 '__unstableEnableFullSiteEditingBlocks' => array(
131 'description' => __( 'Enables experimental Site Editor blocks', 'gutenberg' ),
132 'type' => 'boolean',
133 'context' => array( 'default' ),
134 ),
135
136 'styles' => array(
137 'description' => __( 'Editor styles', 'gutenberg' ),
138 'type' => 'array',
139 'context' => array( 'default' ),
140 ),
141
142 'supportsTemplateMode' => array(
143 'description' => __( 'Indicates whether the current theme supports block-based templates.', 'gutenberg' ),
144 'type' => 'boolean',
145 'context' => array( 'default' ),
146 ),
147
148 'supportsLayout' => array(
149 'description' => __( 'Enable/disable layouts support in container blocks.', 'gutenberg' ),
150 'type' => 'boolean',
151 'context' => array( 'default' ),
152 ),
153
154 'widgetTypesToHideFromLegacyWidgetBlock' => array(
155 'description' => __( 'Widget types to hide from Legacy Widget block.', 'gutenberg' ),
156 'type' => 'array',
157 'context' => array( 'default' ),
158 ),
159
160 '__experimentalFeatures' => array(
161 'description' => __( 'Settings consolidated from core, theme, and user origins.', 'gutenberg' ),
162 'type' => 'object',
163 'context' => array( 'default', 'mobile' ),
164 ),
165
166 '__experimentalStyles' => array(
167 'description' => __( 'Styles consolidated from core, theme, and user origins.', 'gutenberg' ),
168 'type' => 'object',
169 'context' => array( 'mobile' ),
170 ),
171
172 '__experimentalEnableQuoteBlockV2' => array(
173 'description' => __( 'Whether the V2 of the quote block that uses inner blocks should be enabled.', 'gutenberg' ),
174 'type' => 'boolean',
175 'context' => array( 'mobile' ),
176 ),
177
178 '__experimentalEnableListBlockV2' => array(
179 'description' => __( 'Whether the V2 of the list block that uses inner blocks should be enabled.', 'gutenberg' ),
180 'type' => 'boolean',
181 'context' => array( 'mobile' ),
182 ),
183
184 'alignWide' => array(
185 'description' => __( 'Enable/Disable Wide/Full Alignments.', 'gutenberg' ),
186 'type' => 'boolean',
187 'context' => array( 'default' ),
188 ),
189
190 'allowedBlockTypes' => array(
191 'description' => __( 'List of allowed block types.', 'gutenberg' ),
192 'type' => 'boolean',
193 'context' => array( 'default' ),
194 ),
195
196 'allowedMimeTypes' => array(
197 'description' => __( 'List of allowed mime types and file extensions.', 'gutenberg' ),
198 'type' => 'object',
199 'context' => array( 'default' ),
200 ),
201
202 'blockCategories' => array(
203 'description' => __( 'Returns all the categories for block types that will be shown in the block editor.', 'gutenberg' ),
204 'type' => 'array',
205 'context' => array( 'default' ),
206 ),
207
208 'blockInspectorTabs' => array(
209 'description' => __( 'Block inspector tab display overrides.', 'gutenberg' ),
210 'type' => 'object',
211 'context' => array( 'default' ),
212 ),
213
214 'disableCustomColors' => array(
215 'description' => __( 'Disables custom colors.', 'gutenberg' ),
216 'type' => 'boolean',
217 'context' => array( 'default' ),
218 ),
219
220 'disableCustomFontSizes' => array(
221 'description' => __( 'Disables custom font size.', 'gutenberg' ),
222 'type' => 'boolean',
223 'context' => array( 'default' ),
224 ),
225
226 'disableCustomGradients' => array(
227 'description' => __( 'Disables custom font size.', 'gutenberg' ),
228 'type' => 'boolean',
229 'context' => array( 'default' ),
230 ),
231
232 'disableLayoutStyles' => array(
233 'description' => __( 'Disables output of layout styles.', 'gutenberg' ),
234 'type' => 'boolean',
235 'context' => array( 'default' ),
236 ),
237
238 'enableCustomLineHeight' => array(
239 'description' => __( 'Enables custom line height.', 'gutenberg' ),
240 'type' => 'boolean',
241 'context' => array( 'default' ),
242 ),
243
244 'enableCustomSpacing' => array(
245 'description' => __( 'Enables custom spacing.', 'gutenberg' ),
246 'type' => 'boolean',
247 'context' => array( 'default' ),
248 ),
249
250 'enableCustomUnits' => array(
251 'description' => __( 'Enables custom units.', 'gutenberg' ),
252 'type' => 'boolean',
253 'context' => array( 'default' ),
254 ),
255
256 'isRTL' => array(
257 'description' => __( 'Determines whether the current locale is right-to-left (RTL).', 'gutenberg' ),
258 'type' => 'boolean',
259 'context' => array( 'default' ),
260 ),
261
262 'imageDefaultSize' => array(
263 'description' => __( 'Default size for images.', 'gutenberg' ),
264 'type' => 'string',
265 'context' => array( 'default' ),
266 ),
267
268 'imageDimensions' => array(
269 'description' => __( 'Available image dimensions.', 'gutenberg' ),
270 'type' => 'object',
271 'context' => array( 'default' ),
272 ),
273
274 'imageEditing' => array(
275 'description' => __( 'Determines whether the image editing feature is enabled.', 'gutenberg' ),
276 'type' => 'boolean',
277 'context' => array( 'default' ),
278 ),
279
280 'imageSizes' => array(
281 'description' => __( 'Available image sizes.', 'gutenberg' ),
282 'type' => 'array',
283 'context' => array( 'default' ),
284 ),
285
286 'maxUploadFileSize' => array(
287 'description' => __( 'Maximum upload size in bytes allowed for the site.', 'gutenberg' ),
288 'type' => 'number',
289 'context' => array( 'default' ),
290 ),
291
292 'colors' => array(
293 'description' => __( 'Active theme color palette.', 'gutenberg' ),
294 'type' => 'array',
295 'context' => array( 'default' ),
296 ),
297
298 'fontSizes' => array(
299 'description' => __( 'Active theme font sizes.', 'gutenberg' ),
300 'type' => 'array',
301 'context' => array( 'default' ),
302 ),
303
304 'gradients' => array(
305 'description' => __( 'Active theme gradients.', 'gutenberg' ),
306 'type' => 'array',
307 'context' => array( 'default' ),
308 ),
309 'spacingSizes' => array(
310 'description' => __( 'Active theme spacing sizes.', 'gutenberg' ),
311 'type' => 'array',
312 'context' => array( 'default' ),
313 ),
314 'spacingScale' => array(
315 'description' => __( 'Active theme spacing scale.', 'gutenberg' ),
316 'type' => 'array',
317 'context' => array( 'default' ),
318 ),
319 'disableCustomSpacingSizes' => array(
320 'description' => __( 'Disables custom spacing sizes.', 'gutenberg' ),
321 'type' => 'boolean',
322 'context' => array( 'default' ),
323 ),
324 ),
325 );
326
327 $this->schema = $schema;
328
329 return $this->add_additional_fields_schema( $this->schema );
330 }
331
332 /**
333 * Retrieves editor assets (scripts, styles, and inline content).
334 *
335 * @since Gutenberg 5.8.0
336 *
337 * @param WP_REST_Request $request Full details about the request.
338 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
339 */
340 public function get_assets( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
341 // Load WordPress admin environment.
342 $this->load_admin_environment();
343
344 // Set up the block editor context.
345 set_current_screen();
346 $current_screen = get_current_screen();
347 if ( $current_screen ) {
348 $current_screen->is_block_editor( true );
349 }
350
351 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
352 $hook_suffix = 'block-editor-assets';
353
354 // Remove unwanted scripts/styles.
355 remove_action( 'admin_enqueue_scripts', 'gutenberg_enqueue_command_palette_assets', 9 );
356 remove_action( 'admin_enqueue_scripts', 'gutenberg_enqueue_command_palette_assets' );
357 remove_action( 'admin_enqueue_scripts', 'wp_auth_check_load' );
358 remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
359 remove_action( 'admin_print_styles', 'print_emoji_styles' );
360
361 // Preload blocks - this creates inline scripts.
362 $server_block_settings = get_block_editor_server_block_settings();
363 wp_add_inline_script(
364 'wp-block-library',
365 'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( $server_block_settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) . ');',
366 'before'
367 );
368
369 // Preload server-registered block bindings sources.
370 $registered_sources = get_all_registered_block_bindings_sources();
371 if ( ! empty( $registered_sources ) ) {
372 $filtered_sources = array();
373 foreach ( $registered_sources as $source ) {
374 $filtered_sources[] = array(
375 'name' => $source->name,
376 'label' => $source->label,
377 'usesContext' => $source->uses_context,
378 );
379 }
380 $script = sprintf( 'for ( const source of %s ) { wp.blocks.registerBlockBindingsSource( source ); }', wp_json_encode( $filtered_sources, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) );
381 wp_add_inline_script(
382 'wp-block-library',
383 $script,
384 'before'
385 );
386 }
387
388 $load_blocks_scripts = 'wp.blockLibrary.registerCoreBlocks( wp.blockLibrary.__experimentalGetCoreBlocks().filter( ( block ) => block.name !== "core/freeform" ) );';
389 wp_add_inline_script(
390 'wp-block-library',
391 $load_blocks_scripts,
392 'after'
393 );
394
395 // Enqueue editor assets.
396 wp_enqueue_script( 'wp-format-library' );
397 wp_enqueue_script( 'wp-block-library' );
398 wp_enqueue_style( 'wp-editor' );
399 wp_enqueue_style( 'wp-block-library' );
400 wp_enqueue_style( 'wp-format-library' );
401 wp_enqueue_media();
402
403 do_action( 'enqueue_block_editor_assets' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
404
405 // Never allow old admin styles as a dependency.
406 wp_deregister_style( 'common' );
407 wp_deregister_style( 'forms' );
408
409 // Trigger rendering hooks to capture all assets.
410 ob_start();
411 do_action( 'admin_enqueue_scripts', $hook_suffix ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
412 do_action( "admin_print_styles-{$hook_suffix}" ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
413 do_action( 'admin_print_styles' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
414 do_action( "admin_print_scripts-{$hook_suffix}" ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
415 do_action( 'admin_print_scripts' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
416 do_action( "admin_head-{$hook_suffix}" ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
417 do_action( 'admin_head' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
418 do_action( 'admin_footer', '' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
419 do_action( 'wp_print_footer_scripts' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
420 do_action( "admin_print_footer_scripts-{$hook_suffix}" ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
421 do_action( 'admin_print_footer_scripts' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
422 do_action( "admin_footer-{$hook_suffix}" ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores, WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
423 $html_output = ob_get_clean();
424 // Extract all script tags with type="text/html" (WordPress media templates use text/html, not text/template).
425 // Templates are already in html_output from the admin_footer hook.
426 $html_templates = array();
427 if ( preg_match_all( '/<script[^>]*type\s*=\s*["\']text\/html["\'][^>]*>.*?<\/script>/is', $html_output, $matches ) ) {
428 $html_templates = $matches[0];
429 }
430
431 // Process the captured assets.
432 return rest_ensure_response( $this->process_assets( $html_templates ) );
433 }
434
435 /**
436 * Process WordPress assets and return structured data.
437 *
438 * @since Gutenberg 5.8.0
439 *
440 * @param array $html_templates Optional. Array of HTML template strings.
441 * @return array Structured asset data.
442 */
443 private function process_assets( $html_templates = array() ) {
444 global $wp_scripts, $wp_styles;
445
446 $styles_data = array();
447 $scripts_data = array();
448 $inline_styles = array(
449 'before' => array(),
450 'after' => array(),
451 );
452 $inline_scripts = array(
453 'before' => array(),
454 'after' => array(),
455 );
456
457 // Get boot module asset file for dependencies.
458 $boot_asset_file = include __DIR__ . '/../../build/modules/boot/index.min.asset.php';
459 $boot_dependencies = isset( $boot_asset_file['dependencies'] ) ? $boot_asset_file['dependencies'] : array();
460
461 // Get all dependencies that should be excluded (boot dependencies + their deep dependencies).
462 $excluded_scripts = $this->get_all_dependencies( $boot_dependencies, $wp_scripts );
463 $excluded_styles = $this->get_all_dependencies( array( 'wp-components', 'wp-commands', 'dashicons' ), $wp_styles );
464
465 // Process styles - include all dependencies of queued styles.
466 $all_needed_styles = array();
467 foreach ( $wp_styles->queue as $handle ) {
468 $all_needed_styles = array_merge( $all_needed_styles, $this->get_all_dependencies( array( $handle ), $wp_styles ) );
469 }
470 $all_needed_styles = array_unique( $all_needed_styles );
471
472 foreach ( $all_needed_styles as $handle ) {
473 // Skip styles that are already loaded by the boot module.
474 if ( in_array( $handle, $excluded_styles, true ) ) {
475 continue;
476 }
477
478 if ( isset( $wp_styles->registered[ $handle ] ) ) {
479 $style = $wp_styles->registered[ $handle ];
480 $styles_data[ $handle ] = array(
481 'src' => $style->src,
482 'deps' => $style->deps,
483 'version' => $style->ver,
484 'media' => $style->args,
485 );
486
487 $inline_style = $wp_styles->get_data( $handle, 'after' );
488 if ( ! empty( $inline_style ) ) {
489 $inline_styles['after'][ $handle ] = $inline_style;
490 }
491 $inline_style = $wp_styles->get_data( $handle, 'before' );
492 if ( ! empty( $inline_style ) ) {
493 $inline_styles['before'][ $handle ] = $inline_style;
494 }
495 }
496 }
497
498 // Process scripts - include all dependencies of queued scripts.
499 $all_needed_scripts = array();
500 foreach ( $wp_scripts->queue as $handle ) {
501 $all_needed_scripts = array_merge( $all_needed_scripts, $this->get_all_dependencies( array( $handle ), $wp_scripts ) );
502 }
503 $all_needed_scripts = array_unique( $all_needed_scripts );
504
505 foreach ( $all_needed_scripts as $handle ) {
506 // Skip scripts that are already loaded by the boot module.
507 if ( in_array( $handle, $excluded_scripts, true ) ) {
508 continue;
509 }
510
511 if ( isset( $wp_scripts->registered[ $handle ] ) ) {
512 $script = $wp_scripts->registered[ $handle ];
513 $scripts_data[ $handle ] = array(
514 'src' => $script->src,
515 'deps' => $script->deps,
516 'version' => $script->ver,
517 'in_footer' => isset( $script->extra['group'] ) && 1 === $script->extra['group'],
518 );
519
520 // Get inline scripts using proper WordPress methods.
521 $before_script = $wp_scripts->get_inline_script_data( $handle, 'before' );
522 $after_script = $wp_scripts->get_inline_script_data( $handle, 'after' );
523
524 // Get extra script data (localized data).
525 $extra_script = $wp_scripts->print_extra_script( $handle, false );
526
527 // Store before scripts (includes extra/localized data).
528 $before_content = '';
529 if ( ! empty( $before_script ) ) {
530 $before_content .= $before_script . "\n";
531 }
532 if ( ! empty( $extra_script ) ) {
533 $before_content .= $extra_script . "\n";
534 }
535
536 if ( ! empty( $before_content ) ) {
537 $inline_scripts['before'][ $handle ] = trim( $before_content );
538 }
539
540 // Store after scripts separately.
541 if ( ! empty( $after_script ) ) {
542 $inline_scripts['after'][ $handle ] = trim( $after_script );
543 }
544 }
545 }
546
547 // Build an import map from registered script modules.
548 // the import map need to be dynamically extended in the frontend.
549 $script_modules = wp_script_modules();
550 $registered = array();
551 $reflection = new ReflectionClass( $script_modules );
552 $property = $reflection->getProperty( 'registered' );
553 $property->setAccessible( true );
554 $registered = $property->getValue( $script_modules );
555 $import_map = array();
556 foreach ( $registered as $id => $module ) {
557 // Handle both array and object formats.
558 if ( is_array( $module ) && isset( $module['src'] ) ) {
559 $import_map[ $id ] = $module['src'];
560 } elseif ( is_object( $module ) && isset( $module->src ) ) {
561 $import_map[ $id ] = $module->src;
562 }
563 }
564
565 return array(
566 'scripts' => $scripts_data,
567 'styles' => $styles_data,
568 'inline_scripts' => $inline_scripts,
569 'inline_styles' => $inline_styles,
570 'html_templates' => $html_templates,
571 'script_modules' => $import_map,
572 );
573 }
574
575 /**
576 * Get all dependencies recursively (works for both scripts and styles).
577 *
578 * @since Gutenberg 5.8.0
579 *
580 * @param array|string $handles The handles to get dependencies for.
581 * @param WP_Dependencies $wp_assets The WordPress dependencies object.
582 * @return array Array of all dependencies.
583 */
584 private function get_all_dependencies( $handles, $wp_assets ) {
585 $all_deps = array();
586 $handles = (array) $handles;
587
588 foreach ( $handles as $handle ) {
589 if ( isset( $wp_assets->registered[ $handle ] ) ) {
590 $asset = $wp_assets->registered[ $handle ];
591 $all_deps[] = $handle;
592
593 if ( ! empty( $asset->deps ) ) {
594 $child_deps = $this->get_all_dependencies( $asset->deps, $wp_assets );
595 $all_deps = array_merge( $all_deps, $child_deps );
596 }
597 }
598 }
599
600 return array_unique( $all_deps );
601 }
602
603 /**
604 * Load WordPress admin environment and required functions.
605 *
606 * This mirrors the initialization that happens in wp-admin context
607 * to ensure all necessary functions and hooks are available.
608 *
609 * @since Gutenberg 5.8.0
610 */
611 private function load_admin_environment() {
612 // Load core admin files that provide essential functions.
613 require_once ABSPATH . 'wp-admin/includes/admin.php';
614 }
615
616 /**
617 * Retrieves the editor assets schema, conforming to JSON Schema.
618 *
619 * @since Gutenberg 5.8.0
620 *
621 * @return array Item schema data.
622 */
623 public function get_assets_schema() {
624 $schema = array(
625 '$schema' => 'http://json-schema.org/draft-04/schema#',
626 'title' => 'block-editor-assets',
627 'type' => 'object',
628 'properties' => array(
629 'scripts' => array(
630 'description' => __( 'Editor scripts data.', 'gutenberg' ),
631 'type' => 'object',
632 'readonly' => true,
633 ),
634 'styles' => array(
635 'description' => __( 'Editor styles data.', 'gutenberg' ),
636 'type' => 'object',
637 'readonly' => true,
638 ),
639 'inline_scripts' => array(
640 'description' => __( 'Inline scripts for editor assets.', 'gutenberg' ),
641 'type' => 'object',
642 'readonly' => true,
643 ),
644 'inline_styles' => array(
645 'description' => __( 'Inline styles for editor assets.', 'gutenberg' ),
646 'type' => 'object',
647 'readonly' => true,
648 ),
649 'script_modules' => array(
650 'description' => __( 'Script modules to load into the import map.', 'gutenberg' ),
651 'type' => 'object',
652 'readonly' => true,
653 ),
654 ),
655 );
656
657 return $this->add_additional_fields_schema( $schema );
658 }
659 }
660 }
661