From b1e87cfcfa62e0f65f3d76d8e235b76bbd438fc5 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 23 Feb 2024 19:30:28 +0100 Subject: [PATCH 1/9] Check if the meta field is protected --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index 5ce8eb7ac56ee..15387f9a94f07 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -28,6 +28,11 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst return null; } + // Check if the meta field is protected. + if ( is_protected_meta( $source_attrs['key'], 'post' ) ) { + return null; + } + return get_post_meta( $post_id, $source_attrs['key'], true ); } From 7734683ff638a62635cedd31be79dd7c2ed97d3d Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 23 Feb 2024 19:34:19 +0100 Subject: [PATCH 2/9] Check if the meta field is available in the REST API --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index 15387f9a94f07..4324ffc353aac 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -33,6 +33,14 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst return null; } + // Check if the meta field is registered to be shown in REST. + // It follows the format: $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ]. + global $wp_meta_keys; + $object_subtype = 'post' === $block_instance->context['postType'] ? '' : $block_instance->context['postType']; + if ( empty( $wp_meta_keys['post'][ $object_subtype ][ $source_attrs['key'] ]['show_in_rest'] ) || false === $wp_meta_keys['post'][ $object_subtype ][ $source_attrs['key'] ]['show_in_rest'] ) { + return null; + } + return get_post_meta( $post_id, $source_attrs['key'], true ); } From f8eab3924595c6ee5be787dcfc5e0fc9b8f77730 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 23 Feb 2024 20:36:49 +0100 Subject: [PATCH 3/9] Use `get_registered_meta_keys` function --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index 4324ffc353aac..5eccde37622c2 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -34,10 +34,10 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst } // Check if the meta field is registered to be shown in REST. - // It follows the format: $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ]. - global $wp_meta_keys; - $object_subtype = 'post' === $block_instance->context['postType'] ? '' : $block_instance->context['postType']; - if ( empty( $wp_meta_keys['post'][ $object_subtype ][ $source_attrs['key'] ]['show_in_rest'] ) || false === $wp_meta_keys['post'][ $object_subtype ][ $source_attrs['key'] ]['show_in_rest'] ) { + $meta_keys = get_registered_meta_keys( 'post', $block_instance->context['postType'] ); + // Add fields registered for all subtypes. + $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( 'post', '' ) ); + if ( empty( $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) || false === $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) { return null; } From 1117928c898819555641bc829782098fc6226a87 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 23 Feb 2024 20:37:25 +0100 Subject: [PATCH 4/9] Return empty string instead of null --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index 5eccde37622c2..a7a1d5c1ad888 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -15,22 +15,22 @@ */ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_instance ) { if ( empty( $source_attrs['key'] ) ) { - return null; + return ''; } if ( empty( $block_instance->context['postId'] ) ) { - return null; + return ''; } $post_id = $block_instance->context['postId']; // If a post isn't public, we need to prevent unauthorized users from accessing the post meta. $post = get_post( $post_id ); if ( ( ! is_post_publicly_viewable( $post ) && ! current_user_can( 'read_post', $post_id ) ) || post_password_required( $post ) ) { - return null; + return ''; } // Check if the meta field is protected. if ( is_protected_meta( $source_attrs['key'], 'post' ) ) { - return null; + return ''; } // Check if the meta field is registered to be shown in REST. @@ -38,7 +38,7 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst // Add fields registered for all subtypes. $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( 'post', '' ) ); if ( empty( $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) || false === $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) { - return null; + return ''; } return get_post_meta( $post_id, $source_attrs['key'], true ); From 8da1667141763da928c85ad09e5a1a83e3bd085d Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Mon, 26 Feb 2024 11:27:19 +0100 Subject: [PATCH 5/9] Return null if the bindings config is not correct --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index a7a1d5c1ad888..f0f9346d547a8 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -15,7 +15,7 @@ */ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_instance ) { if ( empty( $source_attrs['key'] ) ) { - return ''; + return null; } if ( empty( $block_instance->context['postId'] ) ) { From b667e5c75965bb13102c1c39eae18e5a08c73fb7 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 27 Feb 2024 18:03:35 +0100 Subject: [PATCH 6/9] Return `null` when the field is unavailable or protected --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index f0f9346d547a8..5eccde37622c2 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -19,18 +19,18 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst } if ( empty( $block_instance->context['postId'] ) ) { - return ''; + return null; } $post_id = $block_instance->context['postId']; // If a post isn't public, we need to prevent unauthorized users from accessing the post meta. $post = get_post( $post_id ); if ( ( ! is_post_publicly_viewable( $post ) && ! current_user_can( 'read_post', $post_id ) ) || post_password_required( $post ) ) { - return ''; + return null; } // Check if the meta field is protected. if ( is_protected_meta( $source_attrs['key'], 'post' ) ) { - return ''; + return null; } // Check if the meta field is registered to be shown in REST. @@ -38,7 +38,7 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst // Add fields registered for all subtypes. $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( 'post', '' ) ); if ( empty( $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) || false === $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) { - return ''; + return null; } return get_post_meta( $post_id, $source_attrs['key'], true ); From 8697058dc33165b455168fbd828c9f1267933758 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 27 Feb 2024 18:07:19 +0100 Subject: [PATCH 7/9] Add tests for protected fields --- packages/e2e-tests/plugins/block-bindings.php | 20 +++++- .../editor/various/block-bindings.spec.js | 72 +++++++++++++++++-- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/packages/e2e-tests/plugins/block-bindings.php b/packages/e2e-tests/plugins/block-bindings.php index c686b40006a06..74aec2adb500f 100644 --- a/packages/e2e-tests/plugins/block-bindings.php +++ b/packages/e2e-tests/plugins/block-bindings.php @@ -21,7 +21,6 @@ function gutenberg_test_block_bindings_register_custom_fields() { 'default' => 'Value of the text_custom_field', ) ); - // TODO: Change url. register_meta( 'post', 'url_custom_field', @@ -32,5 +31,24 @@ function gutenberg_test_block_bindings_register_custom_fields() { 'default' => '#url-custom-field', ) ); + register_meta( + 'post', + '_protected_field', + array( + 'type' => 'string', + 'single' => true, + 'default' => 'protected field value', + ) + ); + register_meta( + 'post', + 'show_in_rest_false_field', + array( + 'show_in_rest' => false, + 'type' => 'string', + 'single' => true, + 'default' => 'show_in_rest false field value', + ) + ); } add_action( 'init', 'gutenberg_test_block_bindings_register_custom_fields' ); diff --git a/test/e2e/specs/editor/various/block-bindings.spec.js b/test/e2e/specs/editor/various/block-bindings.spec.js index fc315e522b81a..ca19c06beff01 100644 --- a/test/e2e/specs/editor/various/block-bindings.spec.js +++ b/test/e2e/specs/editor/various/block-bindings.spec.js @@ -1218,7 +1218,7 @@ test.describe( 'Block bindings', () => { name: 'core/paragraph', attributes: { anchor: 'paragraph-binding', - content: 'p', + content: 'fallback value', metadata: { bindings: { content: { @@ -1244,9 +1244,73 @@ test.describe( 'Block bindings', () => { // Check the frontend doesn't show the content. const postId = await editor.publishPost(); await page.goto( `/?p=${ postId }` ); - await expect( - page.locator( '#paragraph-binding' ) - ).toBeHidden(); + await expect( page.locator( '#paragraph-binding' ) ).toHaveText( + 'fallback value' + ); + } ); + + test( 'should not show the value of a protected meta field', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + anchor: 'paragraph-binding', + content: 'fallback value', + metadata: { + bindings: { + content: { + source: 'core/post-meta', + args: { key: '_protected_field' }, + }, + }, + }, + }, + } ); + const paragraphBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Paragraph', + } ); + await expect( paragraphBlock ).toHaveText( '_protected_field' ); + // Check the frontend doesn't show the content. + const postId = await editor.publishPost(); + await page.goto( `/?p=${ postId }` ); + await expect( page.locator( '#paragraph-binding' ) ).toHaveText( + 'fallback value' + ); + } ); + + test( 'should not show the value of a meta field with `show_in_rest` false', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + anchor: 'paragraph-binding', + content: 'fallback value', + metadata: { + bindings: { + content: { + source: 'core/post-meta', + args: { key: 'show_in_rest_false_field' }, + }, + }, + }, + }, + } ); + const paragraphBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Paragraph', + } ); + await expect( paragraphBlock ).toHaveText( + 'show_in_rest_false_field' + ); + // Check the frontend doesn't show the content. + const postId = await editor.publishPost(); + await page.goto( `/?p=${ postId }` ); + await expect( page.locator( '#paragraph-binding' ) ).toHaveText( + 'fallback value' + ); } ); } ); From 5eda97077be60888d540dd6155bf51c3d85a815e Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Wed, 28 Feb 2024 11:08:14 +0100 Subject: [PATCH 8/9] Update tests to match current behavior --- test/e2e/specs/editor/various/block-bindings.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/specs/editor/various/block-bindings.spec.js b/test/e2e/specs/editor/various/block-bindings.spec.js index ca19c06beff01..419a70faeaf9b 100644 --- a/test/e2e/specs/editor/various/block-bindings.spec.js +++ b/test/e2e/specs/editor/various/block-bindings.spec.js @@ -1245,7 +1245,7 @@ test.describe( 'Block bindings', () => { const postId = await editor.publishPost(); await page.goto( `/?p=${ postId }` ); await expect( page.locator( '#paragraph-binding' ) ).toHaveText( - 'fallback value' + 'non_existing_custom_field' ); } ); @@ -1276,7 +1276,7 @@ test.describe( 'Block bindings', () => { const postId = await editor.publishPost(); await page.goto( `/?p=${ postId }` ); await expect( page.locator( '#paragraph-binding' ) ).toHaveText( - 'fallback value' + '_protected_field' ); } ); @@ -1309,7 +1309,7 @@ test.describe( 'Block bindings', () => { const postId = await editor.publishPost(); await page.goto( `/?p=${ postId }` ); await expect( page.locator( '#paragraph-binding' ) ).toHaveText( - 'fallback value' + 'show_in_rest_false_field' ); } ); } ); From 471745df93299c16abd4eecb9f88f545d6e6c30c Mon Sep 17 00:00:00 2001 From: Mario Santos <34552881+SantosGuillamot@users.noreply.github.com> Date: Wed, 28 Feb 2024 12:57:44 +0100 Subject: [PATCH 9/9] Remove unnecessary `show_in_rest` conditional Co-authored-by: Pascal Birchler --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/post-meta.php b/lib/compat/wordpress-6.5/block-bindings/post-meta.php index 5eccde37622c2..56298a7c4d4c5 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -37,7 +37,7 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst $meta_keys = get_registered_meta_keys( 'post', $block_instance->context['postType'] ); // Add fields registered for all subtypes. $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( 'post', '' ) ); - if ( empty( $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) || false === $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) { + if ( empty( $meta_keys[ $source_attrs['key'] ]['show_in_rest'] ) ) { return null; }