diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php index 7fe1b42d2d..5b895c00c2 100644 --- a/src/wp-admin/includes/post.php +++ b/src/wp-admin/includes/post.php @@ -1874,3 +1874,146 @@ function redirect_post($post_id = '') { wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) ); exit; } + +/** + * Return whether the post can be edited in the block editor. + * + * @since 5.0.0 + * + * @param int|WP_Post $post Post ID or WP_Post object. + * @return bool Whether the post can be edited in the block editor. + */ +function use_block_editor_for_post( $post ) { + $post = get_post( $post ); + + if ( ! $post ) { + return false; + } + + $use_block_editor = use_block_editor_for_post_type( $post->post_type ); + + /** + * Filter whether a post is able to be edited in the block editor. + * + * @since 5.0.0 + * + * @param bool $use_block_editor Whether the post can be edited or not. + * @param WP_Post $post The post being checked. + */ + return apply_filters( 'use_block_editor_for_post', $use_block_editor, $post ); +} + +/** + * Return whether a post type is compatible with the block editor. + * + * The block editor depends on the REST API, and if the post type is not shown in the + * REST API, then it won't work with the block editor. + * + * @since 5.0.0 + * + * @param string $post_type The post type. + * @return bool Whether the post type can be edited with the block editor. + */ +function use_block_editor_for_post_type( $post_type ) { + if ( ! post_type_exists( $post_type ) ) { + return false; + } + + if ( ! post_type_supports( $post_type, 'editor' ) ) { + return false; + } + + $post_type_object = get_post_type_object( $post_type ); + if ( $post_type_object && ! $post_type_object->show_in_rest ) { + return false; + } + + /** + * Filter whether a post is able to be edited in the block editor. + * + * @since 5.0.0 + * + * @param bool $use_block_editor Whether the post type can be edited or not. Default true. + * @param string $post_type The post type being checked. + */ + return apply_filters( 'use_block_editor_for_post_type', true, $post_type ); +} + +/** + * Returns all the block categories that will be shown in the block editor. + * + * @since 5.0.0 + * + * @param WP_Post $post Post object. + * @return array Array of block categories. + */ +function get_block_categories( $post ) { + $default_categories = array( + array( + 'slug' => 'common', + 'title' => __( 'Common Blocks', 'gutenberg' ), + ), + array( + 'slug' => 'formatting', + 'title' => __( 'Formatting', 'gutenberg' ), + ), + array( + 'slug' => 'layout', + 'title' => __( 'Layout Elements', 'gutenberg' ), + ), + array( + 'slug' => 'widgets', + 'title' => __( 'Widgets', 'gutenberg' ), + ), + array( + 'slug' => 'embed', + 'title' => __( 'Embeds', 'gutenberg' ), + ), + array( + 'slug' => 'reusable', + 'title' => __( 'Reusable Blocks', 'gutenberg' ), + ), + ); + + /** + * Filter 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. + * + * Returns an associative array of registered block data keyed by block name. Data includes properties + * of a block relevant for client registration. + * + * @since 5.0.0 + * + * @return array An associative array of registered block data. + */ +function get_block_editor_server_block_settings() { + $block_registry = WP_Block_Type_Registry::get_instance(); + $blocks = array(); + $keys_to_pick = array( 'title', 'description', 'icon', 'category', 'keywords', 'supports', 'attributes' ); + + foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) { + foreach ( $keys_to_pick as $key ) { + if ( ! isset( $block_type->{ $key } ) ) { + continue; + } + + if ( ! isset( $blocks[ $block_name ] ) ) { + $blocks[ $block_name ] = array(); + } + + $blocks[ $block_name ][ $key ] = $block_type->{ $key }; + } + } + + return $blocks; +} diff --git a/tests/phpunit/tests/admin/includesPost.php b/tests/phpunit/tests/admin/includesPost.php index f2df065e49..f57b27f203 100644 --- a/tests/phpunit/tests/admin/includesPost.php +++ b/tests/phpunit/tests/admin/includesPost.php @@ -658,4 +658,53 @@ class Tests_Admin_Includes_Post extends WP_UnitTestCase { $this->assertSame( $p, post_exists( $title, $content, $date ) ); } + function test_use_block_editor_for_post() { + $this->assertFalse( use_block_editor_for_post( -1 ) ); + $bogus_post_id = $this->factory()->post->create( + array( + 'post_type' => 'bogus', + ) + ); + $this->assertFalse( use_block_editor_for_post( $bogus_post_id ) ); + + register_post_type( + 'restless', + array( + 'show_in_rest' => false, + ) + ); + $restless_post_id = $this->factory()->post->create( + array( + 'post_type' => 'restless', + ) + ); + $this->assertFalse( use_block_editor_for_post( $restless_post_id ) ); + + $generic_post_id = $this->factory()->post->create(); + + add_filter( 'use_block_editor_for_post', '__return_false' ); + $this->assertFalse( use_block_editor_for_post( $generic_post_id ) ); + remove_filter( 'use_block_editor_for_post', '__return_false' ); + + add_filter( 'use_block_editor_for_post', '__return_true' ); + $this->assertTrue( use_block_editor_for_post( $restless_post_id ) ); + remove_filter( 'use_block_editor_for_post', '__return_true' ); + } + + function test_get_block_editor_server_block_settings() { + $name = 'core/test'; + $settings = array( + 'icon' => 'text', + 'render_callback' => 'foo', + ); + + register_block_type( $name, $settings ); + + $blocks = get_block_editor_server_block_settings(); + + unregister_block_type( $name ); + + $this->assertArrayHasKey( $name, $blocks ); + $this->assertSame( array( 'icon' => 'text' ), $blocks[ $name ] ); + } }