diff --git a/src/wp-admin/edit-form-blocks.php b/src/wp-admin/edit-form-blocks.php index c7de88b5d3..ae5f0481ff 100644 --- a/src/wp-admin/edit-form-blocks.php +++ b/src/wp-admin/edit-form-blocks.php @@ -23,6 +23,8 @@ if ( ! defined( 'ABSPATH' ) ) { */ global $post_type, $post_type_object, $post, $title, $editor_styles, $wp_meta_boxes; +$editor_name = 'post-editor'; + // Flag that we're loading the block editor. $current_screen = get_current_screen(); $current_screen->is_block_editor( true ); @@ -56,6 +58,7 @@ $preload_paths = array( sprintf( '/wp/v2/%s/%d/autosaves?context=edit', $rest_base, $post->ID ), ); + /** * Preload common data by specifying an array of REST API paths that will be preloaded. * @@ -135,31 +138,6 @@ wp_add_inline_script( 'before' ); - -/* - * Initialize the editor. - */ - -$align_wide = get_theme_support( 'align-wide' ); -$color_palette = current( (array) get_theme_support( 'editor-color-palette' ) ); -$font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) ); -$gradient_presets = current( (array) get_theme_support( 'editor-gradient-presets' ) ); -$custom_line_height = get_theme_support( 'custom-line-height' ); -$custom_units = get_theme_support( 'custom-units' ); -$custom_spacing = get_theme_support( 'custom-spacing' ); - -/** - * Filters the allowed block types for the editor, defaulting to true (all - * block types supported). - * - * @since 5.0.0 - * - * @param bool|array $allowed_block_types Array of block type slugs, or - * boolean to enable/disable all. - * @param WP_Post $post The post resource data. - */ -$allowed_block_types = apply_filters( 'allowed_block_types', true, $post ); - /* * Get all available templates for the post/page attributes meta-box. * The "Default template" array element should only be added if the array is @@ -175,12 +153,6 @@ $available_templates = ! empty( $available_templates ) ? array_merge( $available_templates ) : $available_templates; -// Media settings. -$max_upload_size = wp_max_upload_size(); -if ( ! $max_upload_size ) { - $max_upload_size = 0; -} - // Editor Styles. $styles = array( array( @@ -208,39 +180,6 @@ if ( $editor_styles && current_theme_supports( 'editor-styles' ) ) { } } -// Image sizes. - -/** This filter is documented in wp-admin/includes/media.php */ -$image_size_names = apply_filters( - 'image_size_names_choose', - array( - 'thumbnail' => __( 'Thumbnail' ), - 'medium' => __( 'Medium' ), - 'large' => __( 'Large' ), - 'full' => __( 'Full Size' ), - ) -); - -$available_image_sizes = array(); -foreach ( $image_size_names as $image_size_slug => $image_size_name ) { - $available_image_sizes[] = array( - 'slug' => $image_size_slug, - 'name' => $image_size_name, - ); -} - -$default_size = get_option( 'image_default_size', 'large' ); -$image_default_size = in_array( $default_size, array_keys( $image_size_names ), true ) ? $image_default_size : 'large'; - -$image_dimensions = array(); -$all_sizes = wp_get_registered_image_subsizes(); -foreach ( $available_image_sizes as $size ) { - $key = $size['slug']; - if ( isset( $all_sizes[ $key ] ) ) { - $image_dimensions[ $key ] = $all_sizes[ $key ]; - } -} - // Lock settings. $user_id = wp_check_post_lock( $post->ID ); if ( $user_id ) { @@ -289,24 +228,13 @@ if ( $user_id ) { $body_placeholder = apply_filters( 'write_your_story', __( 'Type / to choose a block' ), $post ); $editor_settings = array( - 'alignWide' => $align_wide, 'availableTemplates' => $available_templates, - 'allowedBlockTypes' => $allowed_block_types, - 'disableCustomColors' => get_theme_support( 'disable-custom-colors' ), - 'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ), - 'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ), 'disablePostFormats' => ! current_theme_supports( 'post-formats' ), /** This filter is documented in wp-admin/edit-form-advanced.php */ 'titlePlaceholder' => apply_filters( 'enter_title_here', __( 'Add title' ), $post ), 'bodyPlaceholder' => $body_placeholder, - 'isRTL' => is_rtl(), 'autosaveInterval' => AUTOSAVE_INTERVAL, - 'maxUploadFileSize' => $max_upload_size, - 'allowedMimeTypes' => get_allowed_mime_types(), 'styles' => $styles, - 'imageSizes' => $available_image_sizes, - 'imageDefaultSize' => $image_default_size, - 'imageDimensions' => $image_dimensions, 'richEditingEnabled' => user_can_richedit(), 'postLock' => $lock_details, 'postLockUtils' => array( @@ -320,9 +248,6 @@ $editor_settings = array( // Whether or not to load the 'postcustom' meta box is stored as a user meta // field so that we're not always loading its assets. 'enableCustomFields' => (bool) get_user_meta( get_current_user_id(), 'enable_custom_fields', true ), - 'enableCustomLineHeight' => $custom_line_height, - 'enableCustomUnits' => $custom_units, - 'enableCustomSpacing' => $custom_spacing, ); $autosave = wp_get_post_autosave( $post->ID ); @@ -336,18 +261,6 @@ if ( $autosave ) { } } -if ( false !== $color_palette ) { - $editor_settings['colors'] = $color_palette; -} - -if ( false !== $font_sizes ) { - $editor_settings['fontSizes'] = $font_sizes; -} - -if ( false !== $gradient_presets ) { - $editor_settings['gradients'] = $gradient_presets; -} - if ( ! empty( $post_type_object->template ) ) { $editor_settings['template'] = $post_type_object->template; $editor_settings['templateLock'] = ! empty( $post_type_object->template_lock ) ? $post_type_object->template_lock : false; @@ -372,7 +285,6 @@ wp_enqueue_media( wp_tinymce_inline_scripts(); wp_enqueue_editor(); - /** * Styles */ @@ -400,15 +312,7 @@ if ( ! isset( $core_meta_boxes['postcustom'] ) || ! $core_meta_boxes['postcustom unset( $editor_settings['enableCustomFields'] ); } -/** - * Filters the settings to pass to the block editor. - * - * @since 5.0.0 - * - * @param array $editor_settings Default editor settings. - * @param WP_Post $post Post being edited. - */ -$editor_settings = apply_filters( 'block_editor_settings', $editor_settings, $post ); +$editor_settings = get_block_editor_settings( $editor_name, $editor_settings ); $init_script = << 'text', - 'title' => _x( 'Text', 'block category' ), - 'icon' => null, - ), - array( - 'slug' => 'media', - 'title' => _x( 'Media', 'block category' ), - 'icon' => null, - ), - array( - 'slug' => 'design', - 'title' => _x( 'Design', 'block category' ), - 'icon' => null, - ), - array( - 'slug' => 'widgets', - 'title' => _x( 'Widgets', 'block category' ), - 'icon' => null, - ), - array( - 'slug' => 'theme', - 'title' => _x( 'Theme', 'block category' ), - 'icon' => null, - ), - array( - 'slug' => 'embed', - 'title' => _x( 'Embeds', 'block category' ), - 'icon' => null, - ), - array( - 'slug' => 'reusable', - 'title' => _x( 'Reusable Blocks', 'block category' ), - 'icon' => null, - ), - ); - - /** - * Filters the default array of block categories. - * - * @since 5.0.0 - * - * @param array[] $default_categories Array of block categories. - * @param WP_Post $post Post being loaded. - */ - return apply_filters( 'block_categories', $default_categories, $post ); -} - /** * Prepares server-registered blocks for the block editor. * diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php new file mode 100644 index 0000000000..b5aa648fbb --- /dev/null +++ b/src/wp-includes/block-editor.php @@ -0,0 +1,267 @@ + 'text', + 'title' => _x( 'Text', 'block category' ), + 'icon' => null, + ), + array( + 'slug' => 'media', + 'title' => _x( 'Media', 'block category' ), + 'icon' => null, + ), + array( + 'slug' => 'design', + 'title' => _x( 'Design', 'block category' ), + 'icon' => null, + ), + array( + 'slug' => 'widgets', + 'title' => _x( 'Widgets', 'block category' ), + 'icon' => null, + ), + array( + 'slug' => 'theme', + 'title' => _x( 'Theme', 'block category' ), + 'icon' => null, + ), + array( + 'slug' => 'embed', + 'title' => _x( 'Embeds', 'block category' ), + 'icon' => null, + ), + array( + 'slug' => 'reusable', + 'title' => _x( 'Reusable Blocks', 'block category' ), + 'icon' => null, + ), + ); +} + +/** + * Returns all the categories for block types that will be shown in the block editor. + * + * @since 5.0.0 + * + * @param string|WP_Post $editor_name_or_post The name of the editor (e.g. 'post-editor') + * or the post object. + * + * @return array[] Array of categories for block types. + */ +function get_block_categories( $editor_name_or_post ) { + // Assume the post editor when the WP_Post object passed. + $editor_name = is_object( $editor_name_or_post ) ? 'post-editor' : $editor_name_or_post; + $default_categories = get_default_block_categories(); + + /** + * Filters the default array of categories for block types. + * + * @since 5.8.0 + * + * @param array[] $default_categories Array of categories for block types. + */ + $block_categories = apply_filters( "block_categories_{$editor_name}", $default_categories ); + if ( 'post-editor' === $editor_name ) { + $post = is_object( $editor_name_or_post ) ? $editor_name_or_post : get_post(); + + /** + * Filters the default array of categories for block types. + * + * @since 5.0.0 + * @deprecated 5.8.0 The hook transitioned to support also screens that don't contain the $post instance. + * + * @param array[] $block_categories Array of categories for block types. + * @param WP_Post $post Post being loaded. + */ + $block_categories = apply_filters_deprecated( 'block_categories', array( $block_categories, $post ), '5.8.0', "block_categories_{$editor_name}" ); + } + + return $block_categories; +} + +/** + * Gets the list of allowed block types to use in the block editor. + * + * @since 5.8.0 + * + * @param string $editor_name The name of the editor (e.g. 'post-editor'). + * + * @return bool|array Array of block type slugs, or boolean to enable/disable all. + */ +function get_allowed_block_types( $editor_name ) { + $allowed_block_types = true; + + /** + * Filters the allowed block types for the given editor, defaulting to true (all + * registered block types supported). + * + * @since 5.8.0 + * + * @param bool|array $allowed_block_types Array of block type slugs, or + * boolean to enable/disable all. + */ + $allowed_block_types = apply_filters( "allowed_block_types_{$editor_name}", $allowed_block_types ); + if ( 'post-editor' === $editor_name ) { + $post = get_post(); + + /** + * Filters the allowed block types for the editor, defaulting to true (all + * block types supported). + * + * @since 5.0.0 + * @deprecated 5.8.0 The hook transitioned to support also screens that don't contain $post instance. + * + * @param bool|array $allowed_block_types Array of block type slugs, or + * boolean to enable/disable all. + * @param WP_Post $post The post resource data. + */ + $allowed_block_types = apply_filters_deprecated( 'allowed_block_types', array( $allowed_block_types, $post ), '5.8.0', "allowed_block_types_{$editor_name}" ); + } + + return $allowed_block_types; +} + +/** + * Returns the default block editor settings. + * + * @since 5.8.0 + * + * @return array The default block editor settings. + */ +function get_default_block_editor_settings() { + // Media settings. + $max_upload_size = wp_max_upload_size(); + if ( ! $max_upload_size ) { + $max_upload_size = 0; + } + + /** This filter is documented in wp-admin/includes/media.php */ + $image_size_names = apply_filters( + 'image_size_names_choose', + array( + 'thumbnail' => __( 'Thumbnail' ), + 'medium' => __( 'Medium' ), + 'large' => __( 'Large' ), + 'full' => __( 'Full Size' ), + ) + ); + + $available_image_sizes = array(); + foreach ( $image_size_names as $image_size_slug => $image_size_name ) { + $available_image_sizes[] = array( + 'slug' => $image_size_slug, + 'name' => $image_size_name, + ); + } + + $default_size = get_option( 'image_default_size', 'large' ); + $image_default_size = in_array( $default_size, array_keys( $image_size_names ), true ) ? $image_default_size : 'large'; + + $image_dimensions = array(); + $all_sizes = wp_get_registered_image_subsizes(); + foreach ( $available_image_sizes as $size ) { + $key = $size['slug']; + if ( isset( $all_sizes[ $key ] ) ) { + $image_dimensions[ $key ] = $all_sizes[ $key ]; + } + } + + $editor_settings = array( + 'alignWide' => get_theme_support( 'align-wide' ), + 'allowedBlockTypes' => true, + 'allowedMimeTypes' => get_allowed_mime_types(), + 'blockCategories' => get_default_block_categories(), + 'disableCustomColors' => get_theme_support( 'disable-custom-colors' ), + 'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ), + 'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ), + 'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ), + 'enableCustomSpacing' => get_theme_support( 'custom-spacing' ), + 'enableCustomUnits' => get_theme_support( 'custom-units' ), + 'isRTL' => is_rtl(), + 'imageDefaultSize' => $image_default_size, + 'imageDimensions' => $image_dimensions, + 'imageEditing' => true, + 'imageSizes' => $available_image_sizes, + 'maxUploadFileSize' => $max_upload_size, + ); + + // Theme settings. + $color_palette = current( (array) get_theme_support( 'editor-color-palette' ) ); + if ( false !== $color_palette ) { + $editor_settings['colors'] = $color_palette; + } + + $font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) ); + if ( false !== $font_sizes ) { + $editor_settings['fontSizes'] = $font_sizes; + } + + $gradient_presets = current( (array) get_theme_support( 'editor-gradient-presets' ) ); + if ( false !== $gradient_presets ) { + $editor_settings['gradients'] = $gradient_presets; + } + + return $editor_settings; +} + +/** + * Returns the contextualized block editor settings settings for a selected editor type. + * + * @since 5.8.0 + * + * @param string $editor_name The name of the editor (e.g. 'post-editor'). + * @param array $custom_settings Optional custom settings to use with the editor type. + * + * @return array The contextualized block editor settings. + */ +function get_block_editor_settings( $editor_name, $custom_settings = array() ) { + $editor_settings = array_merge( + get_default_block_editor_settings( $editor_name ), + array( + 'allowedBlockTypes' => get_allowed_block_types( $editor_name ), + 'blockCategories' => get_block_categories( $editor_name ), + ), + $custom_settings + ); + + /** + * Filters the settings to pass to the block editor for a given editor type. + * + * @since 5.8.0 + * + * @param array $editor_settings Default editor settings. + */ + $editor_settings = apply_filters( "block_editor_settings_{$editor_name}", $editor_settings ); + if ( 'post-editor' === $editor_name ) { + $post = get_post(); + + /** + * Filters the settings to pass to the block editor. + * + * @since 5.0.0 + * @deprecated 5.8.0 The hook transitioned to support also screens that don't contain $post instance. + * + * @param array $editor_settings Default editor settings. + * @param WP_Post $post Post being edited. + */ + $editor_settings = apply_filters_deprecated( 'block_editor_settings', array( $editor_settings, $post ), '5.8.0', "block_editor_settings_{$editor_name}" ); + } + + return $editor_settings; +} diff --git a/src/wp-settings.php b/src/wp-settings.php index c62e1c1db2..69057406a2 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -294,6 +294,7 @@ require ABSPATH . WPINC . '/class-wp-block-list.php'; require ABSPATH . WPINC . '/class-wp-block-parser.php'; require ABSPATH . WPINC . '/blocks.php'; require ABSPATH . WPINC . '/blocks/index.php'; +require ABSPATH . WPINC . '/block-editor.php'; require ABSPATH . WPINC . '/block-patterns.php'; require ABSPATH . WPINC . '/class-wp-block-supports.php'; require ABSPATH . WPINC . '/block-supports/align.php'; diff --git a/tests/phpunit/tests/blocks/block-editor.php b/tests/phpunit/tests/blocks/block-editor.php new file mode 100644 index 0000000000..d638298f05 --- /dev/null +++ b/tests/phpunit/tests/blocks/block-editor.php @@ -0,0 +1,312 @@ + 'Example', + ); + + $post = $this->factory()->post->create_and_get( $args ); + } + + function filter_set_block_categories_post( $block_categories, $post ) { + if ( empty( $post ) ) { + return $block_categories; + } + + return array( + array( + 'slug' => 'filtered-category', + 'title' => 'Filtered Category', + 'icon' => null, + ), + ); + } + + function filter_set_allowed_block_types_post( $allowed_block_types, $post ) { + if ( empty( $post ) ) { + return $allowed_block_types; + } + + return array( 'test/filtered-block' ); + } + + function filter_set_block_editor_settings_post( $editor_settings, $post ) { + if ( empty( $post ) ) { + return $allowed_block_types; + } + + return array( + 'filter' => 'deprecated', + ); + } + + /** + * @ticket 52920 + * @expectedDeprecated block_categories + */ + function test_get_block_categories_deprecated_filter_post_object() { + add_filter( 'block_categories', array( $this, 'filter_set_block_categories_post' ), 10, 2 ); + + $block_categories = get_block_categories( get_post() ); + + remove_filter( 'block_categories', array( $this, 'filter_set_block_categories_post' ) ); + + $this->assertSameSets( + array( + array( + 'slug' => 'filtered-category', + 'title' => 'Filtered Category', + 'icon' => null, + ), + ), + $block_categories + ); + } + + /** + * @ticket 52920 + * @expectedDeprecated block_categories + */ + function test_get_block_categories_deprecated_filter_post_editor() { + add_filter( 'block_categories', array( $this, 'filter_set_block_categories_post' ), 10, 2 ); + + $block_categories = get_block_categories( 'post-editor' ); + + remove_filter( 'block_categories', array( $this, 'filter_set_block_categories_post' ) ); + + $this->assertSameSets( + array( + array( + 'slug' => 'filtered-category', + 'title' => 'Filtered Category', + 'icon' => null, + ), + ), + $block_categories + ); + } + + /** + * @ticket 52920 + */ + function test_get_allowed_block_types_default() { + $allowed_block_types = get_allowed_block_types( 'post-editor' ); + + $this->assertTrue( $allowed_block_types ); + } + + /** + * @ticket 52920 + * @expectedDeprecated allowed_block_types + */ + function test_get_allowed_block_types_deprecated_filter_post_editor() { + add_filter( 'allowed_block_types', array( $this, 'filter_set_allowed_block_types_post' ), 10, 2 ); + + $allowed_block_types = get_allowed_block_types( 'post-editor' ); + + remove_filter( 'allowed_block_types', array( $this, 'filter_set_allowed_block_types_post' ) ); + + $this->assertSameSets( array( 'test/filtered-block' ), $allowed_block_types ); + } + + /** + * @ticket 52920 + */ + function test_get_default_block_editor_settings() { + $settings = get_default_block_editor_settings(); + + $this->assertCount( 16, $settings ); + $this->assertFalse( $settings['alignWide'] ); + $this->assertInternalType( 'array', $settings['allowedMimeTypes'] ); + $this->assertTrue( $settings['allowedBlockTypes'] ); + $this->assertSameSets( + array( + array( + 'slug' => 'text', + 'title' => 'Text', + 'icon' => null, + ), + array( + 'slug' => 'media', + 'title' => 'Media', + 'icon' => null, + ), + array( + 'slug' => 'design', + 'title' => 'Design', + 'icon' => null, + ), + array( + 'slug' => 'widgets', + 'title' => 'Widgets', + 'icon' => null, + ), + array( + 'slug' => 'theme', + 'title' => 'Theme', + 'icon' => null, + ), + array( + 'slug' => 'embed', + 'title' => 'Embeds', + 'icon' => null, + ), + array( + 'slug' => 'reusable', + 'title' => 'Reusable Blocks', + 'icon' => null, + ), + ), + $settings['blockCategories'] + ); + $this->assertFalse( $settings['disableCustomColors'] ); + $this->assertFalse( $settings['disableCustomFontSizes'] ); + $this->assertFalse( $settings['disableCustomGradients'] ); + $this->assertFalse( $settings['enableCustomLineHeight'] ); + $this->assertFalse( $settings['enableCustomSpacing'] ); + $this->assertFalse( $settings['enableCustomUnits'] ); + $this->assertFalse( $settings['isRTL'] ); + $this->assertSame( 'large', $settings['imageDefaultSize'] ); + $this->assertSameSets( + array( + array( + 'width' => 150, + 'height' => 150, + 'crop' => true, + ), + array( + 'width' => 300, + 'height' => 300, + 'crop' => false, + ), + array( + 'width' => 1024, + 'height' => 1024, + 'crop' => false, + ), + ), + $settings['imageDimensions'] + ); + $this->assertTrue( $settings['imageEditing'] ); + $this->assertSameSets( + array( + array( + 'slug' => 'full', + 'name' => 'Full Size', + ), + array( + 'slug' => 'large', + 'name' => 'Large', + ), + array( + 'slug' => 'medium', + 'name' => 'Medium', + ), + array( + 'slug' => 'thumbnail', + 'name' => 'Thumbnail', + ), + ), + $settings['imageSizes'] + ); + $this->assertInternalType( 'int', $settings['maxUploadFileSize'] ); + } + + /** + * @ticket 52920 + */ + function test_get_block_editor_settings_returns_default_settings() { + $this->assertSameSets( + get_block_editor_settings( 'my-editor' ), + get_default_block_editor_settings() + ); + } + + /** + * @ticket 52920 + */ + function test_get_block_editor_settings_overrides_default_settings_my_editor() { + function filter_allowed_block_types_my_editor() { + return array( 'test/filtered-my-block' ); + } + function filter_block_categories_my_editor() { + return array( + array( + 'slug' => 'filtered-my-category', + 'title' => 'Filtered My Category', + 'icon' => null, + ), + ); + } + function filter_block_editor_settings_my_editor( $editor_settings ) { + $editor_settings['maxUploadFileSize'] = 12345; + + return $editor_settings; + } + + add_filter( 'allowed_block_types_my-editor', 'filter_allowed_block_types_my_editor', 10, 1 ); + add_filter( 'block_categories_my-editor', 'filter_block_categories_my_editor', 10, 1 ); + add_filter( 'block_editor_settings_my-editor', 'filter_block_editor_settings_my_editor', 10, 1 ); + + $settings = get_block_editor_settings( 'my-editor' ); + + remove_filter( 'allowed_block_types_my-editor', 'filter_allowed_block_types_my_editor' ); + remove_filter( 'block_categories_my-editor', 'filter_block_categories_my_editor' ); + remove_filter( 'block_editor_settings_my-editor', 'filter_block_editor_settings_my_editor' ); + + $this->assertSameSets( array( 'test/filtered-my-block' ), $settings['allowedBlockTypes'] ); + $this->assertSameSets( + array( + array( + 'slug' => 'filtered-my-category', + 'title' => 'Filtered My Category', + 'icon' => null, + ), + ), + $settings['blockCategories'] + ); + $this->assertSame( 12345, $settings['maxUploadFileSize'] ); + } + + /** + * @ticket 52920 + * @expectedDeprecated block_editor_settings + */ + function test_get_block_editor_settings_deprecated_filter_post_editor() { + add_filter( 'block_editor_settings', array( $this, 'filter_set_block_editor_settings_post' ), 10, 2 ); + + $settings = get_block_editor_settings( 'post-editor' ); + + remove_filter( 'block_editor_settings', array( $this, 'filter_set_block_editor_settings_post' ) ); + + $this->assertSameSets( + array( + 'filter' => 'deprecated', + ), + $settings + ); + } +}