From 9e40ea99bf8e77ac00218f90faf7e09a572701d1 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 5 Jul 2023 12:21:16 +1200 Subject: [PATCH] Patterns: rename sync_status and move to top level field on rest return instead of a meta field (#52146) --- lib/blocks.php | 28 +++++++++++ lib/compat/wordpress-6.3/blocks.php | 29 +++--------- ...class-gutenberg-rest-blocks-controller.php | 47 +++++++++++++++++++ lib/load.php | 1 + packages/block-editor/src/store/selectors.js | 15 +++--- .../components/create-pattern-modal/index.js | 2 +- .../components/page-patterns/use-patterns.js | 2 +- .../use-pattern-details.js | 2 +- .../src/components/post-sync-status/index.js | 6 +-- packages/reusable-blocks/src/store/actions.js | 2 +- 10 files changed, 98 insertions(+), 36 deletions(-) create mode 100644 lib/compat/wordpress-6.3/class-gutenberg-rest-blocks-controller.php diff --git a/lib/blocks.php b/lib/blocks.php index 8185567db1b80..e98f711b5c85a 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -372,3 +372,31 @@ function gutenberg_register_legacy_social_link_blocks() { } add_action( 'init', 'gutenberg_register_legacy_social_link_blocks' ); + +/** + * Migrate the legacy `sync_status` meta key (added 16.1) to the new `wp_pattern_sync_status` meta key (16.1.1). + * + * This filter is INTENTIONALLY left out of core as the meta key was fist introduced to core in 6.3 as `wp_pattern_sync_status`. + * see https://github.com/WordPress/gutenberg/pull/52232 + * + * @param mixed $value The value to return, either a single metadata value or an array of values depending on the value of $single. + * @param int $object_id ID of the object metadata is for. + * @param string $meta_key Metadata key. + * @param bool $single Whether to return only the first value of the specified $meta_key. + */ +function gutenberg_legacy_wp_block_post_meta( $value, $object_id, $meta_key, $single ) { + if ( 'wp_pattern_sync_status' !== $meta_key ) { + return $value; + } + + $sync_status = get_post_meta( $object_id, 'sync_status', $single ); + + if ( $single && 'unsynced' === $sync_status ) { + return $sync_status; + } elseif ( isset( $sync_status[0] ) && 'unsynced' === $sync_status[0] ) { + return $sync_status; + } + + return $value; +} +add_filter( 'default_post_metadata', 'gutenberg_legacy_wp_block_post_meta', 10, 4 ); diff --git a/lib/compat/wordpress-6.3/blocks.php b/lib/compat/wordpress-6.3/blocks.php index b338d0a246709..ccc68786dc6ad 100644 --- a/lib/compat/wordpress-6.3/blocks.php +++ b/lib/compat/wordpress-6.3/blocks.php @@ -60,6 +60,7 @@ function gutenberg_rename_reusable_block_cpt_to_pattern( $args, $post_type ) { $args['labels']['item_reverted_to_draft'] = __( 'Pattern reverted to draft.' ); $args['labels']['item_scheduled'] = __( 'Pattern scheduled.' ); $args['labels']['item_updated'] = __( 'Pattern updated.' ); + $args['rest_controller_class'] = 'Gutenberg_REST_Blocks_Controller'; } return $args; @@ -89,7 +90,7 @@ function gutenberg_add_custom_fields_to_wp_block( $args, $post_type ) { add_filter( 'register_post_type_args', 'gutenberg_add_custom_fields_to_wp_block', 10, 2 ); /** - * Adds sync_status meta fields to the wp_block post type so an unsynced option can be added. + * Adds wp_pattern_sync_status meta fields to the wp_block post type so an unsynced option can be added. * * Note: This should be removed when the minimum required WP version is >= 6.3. * @@ -101,39 +102,21 @@ function gutenberg_wp_block_register_post_meta() { $post_type = 'wp_block'; register_post_meta( $post_type, - 'sync_status', + 'wp_pattern_sync_status', array( 'auth_callback' => function() { return current_user_can( 'edit_posts' ); }, - 'sanitize_callback' => 'gutenberg_wp_block_sanitize_post_meta', + 'sanitize_callback' => 'sanitize_text_field', 'single' => true, 'type' => 'string', 'show_in_rest' => array( 'schema' => array( - 'type' => 'string', - 'properties' => array( - 'sync_status' => array( - 'type' => 'string', - ), - ), + 'type' => 'string', + 'enum' => array( 'partial', 'unsynced' ), ), ), ) ); } -/** - * Sanitizes the array of wp_block post meta sync_status string. - * - * Note: This should be removed when the minimum required WP version is >= 6.3. - * - * @see https://github.com/WordPress/gutenberg/pull/51144 - * - * @param array $meta_value String to sanitize. - * - * @return array Sanitized string. - */ -function gutenberg_wp_block_sanitize_post_meta( $meta_value ) { - return sanitize_text_field( $meta_value ); -} add_action( 'init', 'gutenberg_wp_block_register_post_meta' ); diff --git a/lib/compat/wordpress-6.3/class-gutenberg-rest-blocks-controller.php b/lib/compat/wordpress-6.3/class-gutenberg-rest-blocks-controller.php new file mode 100644 index 0000000000000..08108e1638334 --- /dev/null +++ b/lib/compat/wordpress-6.3/class-gutenberg-rest-blocks-controller.php @@ -0,0 +1,47 @@ + - // Filter to either fully synced patterns (sync_status === 'fully'), - // or old school reusable blocks (sync_status === ''). - reusableBlock.meta?.sync_status === 'fully' || - reusableBlock.meta?.sync_status === '' || - ! reusableBlock.meta?.sync_status + // Reusable blocks that are fully synced should have no sync status set + // for backwards compat between patterns and old reusable blocks, but + // some in release 16.1 may have had sync status inadvertantly set to + // 'fully' if created in the site editor. + reusableBlock.wp_pattern_sync_status === 'fully' || + reusableBlock.wp_pattern_sync_status === '' || + ! reusableBlock.wp_pattern_sync_status ) .map( buildReusableBlockInserterItem ) : []; @@ -2313,7 +2315,8 @@ function getUnsyncedPatterns( state ) { return reusableBlocks .filter( - ( reusableBlock ) => reusableBlock.meta?.sync_status === 'unsynced' + ( reusableBlock ) => + reusableBlock.wp_pattern_sync_status === 'unsynced' ) .map( ( reusableBlock ) => { return { diff --git a/packages/edit-site/src/components/create-pattern-modal/index.js b/packages/edit-site/src/components/create-pattern-modal/index.js index 7906cb2352c7b..46d734b86fdd1 100644 --- a/packages/edit-site/src/components/create-pattern-modal/index.js +++ b/packages/edit-site/src/components/create-pattern-modal/index.js @@ -56,7 +56,7 @@ export default function CreatePatternModal( { status: 'publish', meta: syncType === SYNC_TYPES.unsynced - ? { sync_status: syncType } + ? { wp_pattern_sync_status: syncType } : undefined, }, { throwOnError: true } diff --git a/packages/edit-site/src/components/page-patterns/use-patterns.js b/packages/edit-site/src/components/page-patterns/use-patterns.js index a8d76b58cb45d..cef7b4721193f 100644 --- a/packages/edit-site/src/components/page-patterns/use-patterns.js +++ b/packages/edit-site/src/components/page-patterns/use-patterns.js @@ -154,7 +154,7 @@ const reusableBlockToPattern = ( reusableBlock ) => ( { categories: reusableBlock.wp_pattern, id: reusableBlock.id, name: reusableBlock.slug, - syncStatus: reusableBlock.meta?.sync_status || SYNC_TYPES.full, + syncStatus: reusableBlock.wp_pattern_sync_status || SYNC_TYPES.full, title: reusableBlock.title.raw, type: reusableBlock.type, reusableBlock, diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js index 3828c18af7838..ed36bb907301b 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js @@ -95,7 +95,7 @@ export default function usePatternDetails( postType, postId ) { details.push( { label: __( 'Syncing' ), value: - record.meta?.sync_status === 'unsynced' + record.wp_pattern_sync_status === 'unsynced' ? __( 'Not synced' ) : __( 'Fully synced' ), } ); diff --git a/packages/editor/src/components/post-sync-status/index.js b/packages/editor/src/components/post-sync-status/index.js index c384fd234c7a3..22de1396d0679 100644 --- a/packages/editor/src/components/post-sync-status/index.js +++ b/packages/editor/src/components/post-sync-status/index.js @@ -11,17 +11,17 @@ import { PanelRow } from '@wordpress/components'; import { store as editorStore } from '../../store'; export default function PostSyncStatus() { - const { meta, postType } = useSelect( ( select ) => { + const { syncStatus, postType } = useSelect( ( select ) => { const { getEditedPostAttribute } = select( editorStore ); return { - meta: getEditedPostAttribute( 'meta' ), + syncStatus: getEditedPostAttribute( 'wp_pattern_sync_status' ), postType: getEditedPostAttribute( 'type' ), }; }, [] ); if ( postType !== 'wp_block' ) { return null; } - const syncStatus = meta?.sync_status; + const isFullySynced = ! syncStatus; return ( diff --git a/packages/reusable-blocks/src/store/actions.js b/packages/reusable-blocks/src/store/actions.js index aae706adfab36..17a2e83d5e776 100644 --- a/packages/reusable-blocks/src/store/actions.js +++ b/packages/reusable-blocks/src/store/actions.js @@ -52,7 +52,7 @@ export const __experimentalConvertBlocksToReusable = const meta = syncType === 'unsynced' ? { - sync_status: syncType, + wp_pattern_sync_status: syncType, } : undefined;