From 247194db7045141f665d010be3d25850ee88595e Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:14:43 +0100 Subject: [PATCH 01/20] Modify `uses_context` for allowed blocks in PHP --- lib/compat/wordpress-6.5/blocks.php | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/compat/wordpress-6.5/blocks.php b/lib/compat/wordpress-6.5/blocks.php index c670e1363a7f8..7520f4134a776 100644 --- a/lib/compat/wordpress-6.5/blocks.php +++ b/lib/compat/wordpress-6.5/blocks.php @@ -219,3 +219,38 @@ function gutenberg_process_block_bindings( $block_content, $parsed_block, $block } add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 ); + +/** + * Add `postId` and `postType` context to blocks that can use block bindings. + * + * @param string $args Array of arguments for registering a block type. + * @param string $block_name The name of the block to process. + * @return array The modified arguments for registering a block type. + */ +function gutenberg_add_context_for_block_bindings( $args, $block_name ) { + $allowed_blocks = array( + 'core/paragraph' => array( 'content' ), + 'core/heading' => array( 'content' ), + 'core/image' => array( 'url', 'title', 'alt' ), + 'core/button' => array( 'url', 'text' ), + ); + + if ( ! isset( $allowed_blocks[ $block_name ] ) ) { + return $args; + } + if ( ! isset( $args['uses_context'] ) ) { + $args['uses_context'] = array( 'postId', 'postType' ); + } else { + // Check if 'postId' exists in 'uses_context' and add it if it doesn't. + if ( ! in_array( 'postId', $args['uses_context'], true ) ) { + $args['uses_context'][] = 'postId'; + } + // Check if 'postType' exists in 'uses_context' and add it if it doesn't. + if ( ! in_array( 'postType', $args['uses_context'], true ) ) { + $args['uses_context'][] = 'postType'; + } + } + + return $args; +} +add_filter( 'register_block_type_args', 'gutenberg_add_context_for_block_bindings', 10, 2 ); From 98e7757cc45aaf825e0a92803dc2d24e4753a6a7 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:14:43 +0100 Subject: [PATCH 02/20] Update post meta source to use block context --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 5 ++--- 1 file changed, 2 insertions(+), 3 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 655abd982663b..78192aba13ff0 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -12,7 +12,7 @@ * Example: array( "key" => "foo" ). * @return mixed The value computed for the source. */ -function gutenberg_block_bindings_post_meta_callback( $source_attrs ) { +function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_instance ) { if ( ! isset( $source_attrs['key'] ) ) { return null; } @@ -21,8 +21,7 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs ) { if ( isset( $source_attrs['postId'] ) ) { $post_id = $source_attrs['postId']; } else { - // I tried using $block_instance->context['postId'] but it wasn't available in the image block. - $post_id = get_the_ID(); + $post_id = isset( $block_instance->context['postId'] ) ? $block_instance->context['postId'] : get_the_ID(); } // If a post isn't public, we need to prevent unauthorized users from accessing the post meta. From 38b539d0264c1764e306602616884c9d07943b67 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:14:43 +0100 Subject: [PATCH 03/20] Remove old hook used for the editor --- .../src/hooks/use-bindings-attributes.js | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/packages/block-editor/src/hooks/use-bindings-attributes.js b/packages/block-editor/src/hooks/use-bindings-attributes.js index a1873143c294a..33020bc5a40d2 100644 --- a/packages/block-editor/src/hooks/use-bindings-attributes.js +++ b/packages/block-editor/src/hooks/use-bindings-attributes.js @@ -112,24 +112,3 @@ addFilter( 'core/editor/custom-sources-backwards-compatibility/shim-attribute-source', shimAttributeSource ); - -// Add the context to all blocks. -addFilter( - 'blocks.registerBlockType', - 'core/block-bindings-ui', - ( settings, name ) => { - if ( ! ( name in BLOCK_BINDINGS_ALLOWED_BLOCKS ) ) { - return settings; - } - const contextItems = [ 'postId', 'postType', 'queryId' ]; - const usesContextArray = settings.usesContext; - const oldUsesContextArray = new Set( usesContextArray ); - contextItems.forEach( ( item ) => { - if ( ! oldUsesContextArray.has( item ) ) { - usesContextArray.push( item ); - } - } ); - settings.usesContext = usesContextArray; - return settings; - } -); From 4194fcd8858930f2c870e6a9ae01373bcc58da8d Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:14:44 +0100 Subject: [PATCH 04/20] Remove possibility of passing post id from source --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 8 +------- 1 file changed, 1 insertion(+), 7 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 78192aba13ff0..381162b5f29f4 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -17,13 +17,7 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst return null; } - // Use the postId attribute if available - if ( isset( $source_attrs['postId'] ) ) { - $post_id = $source_attrs['postId']; - } else { - $post_id = isset( $block_instance->context['postId'] ) ? $block_instance->context['postId'] : get_the_ID(); - } - + $post_id = isset( $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 ) ) { From 3a8acd60122be9a58a1ea6f10ca2706c7102e2ce Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:14:44 +0100 Subject: [PATCH 05/20] Set correct post id --- 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 381162b5f29f4..3b4c11fe3b240 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -17,7 +17,7 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst return null; } - $post_id = isset( $block_instance->context['postId'] ); + $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 ) ) { From 0534638a4add3261c821ac38fde95faf4f77d000 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:15:58 +0100 Subject: [PATCH 06/20] Adapt post meta source --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 4 ++++ 1 file changed, 4 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 3b4c11fe3b240..b7c7d8da3d623 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -17,6 +17,9 @@ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_inst return null; } + if ( ! isset( $block_instance->context['postId'] ) ) { + 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 ); @@ -40,6 +43,7 @@ function gutenberg_register_block_bindings_post_meta_source() { array( 'label' => _x( 'Post Meta', 'block bindings source' ), 'get_value_callback' => 'gutenberg_block_bindings_post_meta_callback', + 'uses_context' => array( 'postId', 'postType' ), ) ); } From 31def4b57c1ce5d02467ababeab37f76a8d4ea3f Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:20:36 +0100 Subject: [PATCH 07/20] Adapt pattern overrides source --- lib/compat/wordpress-6.5/block-bindings/pattern-overrides.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/compat/wordpress-6.5/block-bindings/pattern-overrides.php b/lib/compat/wordpress-6.5/block-bindings/pattern-overrides.php index 0e6d3fc94eeaa..76c3d49ca8085 100644 --- a/lib/compat/wordpress-6.5/block-bindings/pattern-overrides.php +++ b/lib/compat/wordpress-6.5/block-bindings/pattern-overrides.php @@ -35,6 +35,7 @@ function gutenberg_register_block_bindings_pattern_overrides_source() { array( 'label' => _x( 'Pattern Overrides', 'block bindings source' ), 'get_value_callback' => 'gutenberg_block_bindings_pattern_overrides_callback', + 'uses_context' => array( 'pattern/overrides' ), ) ); } From 6cb23c5286468a6c338474c2a8f53a631edf8577 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:23:09 +0100 Subject: [PATCH 08/20] Remove old usesContext from block.json --- packages/block-library/src/button/block.json | 1 - packages/block-library/src/heading/block.json | 1 - packages/block-library/src/image/block.json | 7 +------ packages/block-library/src/paragraph/block.json | 2 +- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/button/block.json b/packages/block-library/src/button/block.json index c3d51c61a0999..ec9f042cf5bcf 100644 --- a/packages/block-library/src/button/block.json +++ b/packages/block-library/src/button/block.json @@ -8,7 +8,6 @@ "description": "Prompt visitors to take action with a button-style link.", "keywords": [ "link" ], "textdomain": "default", - "usesContext": [ "pattern/overrides" ], "attributes": { "tagName": { "type": "string", diff --git a/packages/block-library/src/heading/block.json b/packages/block-library/src/heading/block.json index 90ef0d383af2c..9990ef582e2f4 100644 --- a/packages/block-library/src/heading/block.json +++ b/packages/block-library/src/heading/block.json @@ -7,7 +7,6 @@ "description": "Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.", "keywords": [ "title", "subtitle" ], "textdomain": "default", - "usesContext": [ "pattern/overrides" ], "attributes": { "textAlign": { "type": "string" diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 7a46a34db591f..1076aad0f1798 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -4,12 +4,7 @@ "name": "core/image", "title": "Image", "category": "media", - "usesContext": [ - "allowResize", - "imageCrop", - "fixedHeight", - "pattern/overrides" - ], + "usesContext": [ "allowResize", "imageCrop", "fixedHeight" ], "description": "Insert an image to make a visual statement.", "keywords": [ "img", "photo", "picture" ], "textdomain": "default", diff --git a/packages/block-library/src/paragraph/block.json b/packages/block-library/src/paragraph/block.json index 2f23d41cd0372..7cfe785921b66 100644 --- a/packages/block-library/src/paragraph/block.json +++ b/packages/block-library/src/paragraph/block.json @@ -7,7 +7,7 @@ "description": "Start with the basic building block of all narrative.", "keywords": [ "text" ], "textdomain": "default", - "usesContext": [ "postId", "pattern/overrides" ], + "usesContext": [ "postId" ], "attributes": { "align": { "type": "string" From 1dbf2c4f05b23c1b0c7cf63d562d453bc3ba6e4b Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 9 Feb 2024 20:25:17 +0100 Subject: [PATCH 09/20] Remove old filter --- lib/compat/wordpress-6.5/blocks.php | 35 ----------------------------- 1 file changed, 35 deletions(-) diff --git a/lib/compat/wordpress-6.5/blocks.php b/lib/compat/wordpress-6.5/blocks.php index 7520f4134a776..c670e1363a7f8 100644 --- a/lib/compat/wordpress-6.5/blocks.php +++ b/lib/compat/wordpress-6.5/blocks.php @@ -219,38 +219,3 @@ function gutenberg_process_block_bindings( $block_content, $parsed_block, $block } add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 ); - -/** - * Add `postId` and `postType` context to blocks that can use block bindings. - * - * @param string $args Array of arguments for registering a block type. - * @param string $block_name The name of the block to process. - * @return array The modified arguments for registering a block type. - */ -function gutenberg_add_context_for_block_bindings( $args, $block_name ) { - $allowed_blocks = array( - 'core/paragraph' => array( 'content' ), - 'core/heading' => array( 'content' ), - 'core/image' => array( 'url', 'title', 'alt' ), - 'core/button' => array( 'url', 'text' ), - ); - - if ( ! isset( $allowed_blocks[ $block_name ] ) ) { - return $args; - } - if ( ! isset( $args['uses_context'] ) ) { - $args['uses_context'] = array( 'postId', 'postType' ); - } else { - // Check if 'postId' exists in 'uses_context' and add it if it doesn't. - if ( ! in_array( 'postId', $args['uses_context'], true ) ) { - $args['uses_context'][] = 'postId'; - } - // Check if 'postType' exists in 'uses_context' and add it if it doesn't. - if ( ! in_array( 'postType', $args['uses_context'], true ) ) { - $args['uses_context'][] = 'postType'; - } - } - - return $args; -} -add_filter( 'register_block_type_args', 'gutenberg_add_context_for_block_bindings', 10, 2 ); From 3a17b0948a2c2170dfd5cfcba30cfb39f2429406 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Mon, 12 Feb 2024 09:38:58 +0100 Subject: [PATCH 10/20] Add backport to `uses_context` in source registration --- .../class-wp-block-bindings-registry.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index e60b9ac8fbd08..239fcd5c9df60 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -139,6 +139,25 @@ public function register( string $source_name, array $source_properties ) { $this->sources[ $source_name ] = $source; + // Add `uses_context` defined by block bindings sources. + add_filter( + 'register_block_type_args', + function ( $args, $block_name ) use ( $source ) { + $allowed_blocks = $this->allowed_blocks; + + if ( empty( $allowed_blocks[ $block_name ] ) || empty( $source->uses_context ) ) { + return $args; + } + $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); + // Use array_values to reset the array keys. + $args['uses_context'] = array_values( array_unique( array_merge( $original_use_context, $source->uses_context ) ) ); + + return $args; + }, + 10, + 2 + ); + return $source; } From 4cb4dc6c723849f61ccdd78953b56129eba62cc6 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:09:59 +0100 Subject: [PATCH 11/20] Update source class to include `uses_context` --- .../block-bindings/class-wp-block-bindings-source.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php index fa2bc53705fdc..301343867d54e 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php @@ -46,6 +46,14 @@ final class WP_Block_Bindings_Source { */ private $get_value_callback; + /** + * The context added to the blocks needed by the source. + * + * @since 6.5.0 + * @var array|null + */ + public $uses_context = null; + /** * Constructor. * @@ -61,6 +69,9 @@ public function __construct( string $name, array $source_properties ) { $this->name = $name; $this->label = $source_properties['label']; $this->get_value_callback = $source_properties['get_value_callback']; + if ( isset( $source_properties['uses_context'] ) ) { + $this->uses_context = $source_properties['uses_context']; + } } /** From aa39f96c4b760c7c0d6b5dab86c6db811cc24971 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:10:45 +0100 Subject: [PATCH 12/20] Use `get_block_type_uses_context` when available --- .../class-wp-block-bindings-registry.php | 97 +++++++++++++------ 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index 239fcd5c9df60..53285248d32e4 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -32,6 +32,19 @@ final class WP_Block_Bindings_Registry { */ private static $instance = null; + /** + * Supported blocks that can use the block bindings API. + * + * @since 6.5.0 + * @var array + */ + private $supported_blocks = array( + 'core/paragraph', + 'core/heading', + 'core/image', + 'core/button', + ); + /** * Registers a new block bindings source. * @@ -48,18 +61,19 @@ final class WP_Block_Bindings_Registry { * @param array $source_properties { * The array of arguments that are used to register a source. * - * @type string $label The label of the source. - * @type callback $get_value_callback A callback executed when the source is processed during block rendering. - * The callback should have the following signature: - * - * `function ($source_args, $block_instance,$attribute_name): mixed` - * - @param array $source_args Array containing source arguments - * used to look up the override value, - * i.e. {"key": "foo"}. - * - @param WP_Block $block_instance The block instance. - * - @param string $attribute_name The name of the target attribute. - * The callback has a mixed return type; it may return a string to override - * the block's original value, null, false to remove an attribute, etc. + * @type string $label The label of the source. + * @type callback $get_value_callback A callback executed when the source is processed during block rendering. + * The callback should have the following signature: + * + * `function ($source_args, $block_instance,$attribute_name): mixed` + * - @param array $source_args Array containing source arguments + * used to look up the override value, + * i.e. {"key": "foo"}. + * - @param WP_Block $block_instance The block instance. + * - @param string $attribute_name The name of the target attribute. + * The callback has a mixed return type; it may return a string to override + * the block's original value, null, false to remove an attribute, etc. + * @type array $uses_context (optional) Array of values to add to block `uses_context` needed by the source. * } * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure. */ @@ -132,6 +146,16 @@ public function register( string $source_name, array $source_properties ) { return false; } + // Validate that the uses_context parameter is an array. + if ( isset( $source_properties['uses_context'] ) && ! is_array( $source_properties['uses_context'] ) ) { + _doing_it_wrong( + __METHOD__, + __( 'The "uses_context" parameter must be an array.' ), + '6.5.0' + ); + return false; + } + $source = new WP_Block_Bindings_Source( $source_name, $source_properties @@ -140,24 +164,41 @@ public function register( string $source_name, array $source_properties ) { $this->sources[ $source_name ] = $source; // Add `uses_context` defined by block bindings sources. - add_filter( - 'register_block_type_args', - function ( $args, $block_name ) use ( $source ) { - $allowed_blocks = $this->allowed_blocks; + // If `get_uses_context` exists (from WP 6.5), use its filter because it is more reliable. + if ( method_exists( 'WP_Block_Type', 'get_uses_context' ) ) { + add_filter( + 'get_block_type_uses_context', + function ( $uses_context, $block_type ) use ( $source ) { + if ( ! in_array( $block_type->name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { + return $uses_context; + } + // Use array_values to reset the array keys. + $merged_uses_context = array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) ); - if ( empty( $allowed_blocks[ $block_name ] ) || empty( $source->uses_context ) ) { - return $args; - } - $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); - // Use array_values to reset the array keys. - $args['uses_context'] = array_values( array_unique( array_merge( $original_use_context, $source->uses_context ) ) ); - - return $args; - }, - 10, - 2 - ); + return $merged_uses_context; + }, + 10, + 2 + ); + } else { + add_filter( + 'register_block_type_args', + function ( $args, $block_name ) use ( $source ) { + $allowed_blocks = $this->allowed_blocks; + + if ( empty( $allowed_blocks[ $block_name ] ) || empty( $source->uses_context ) ) { + return $args; + } + $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); + // Use array_values to reset the array keys. + $args['uses_context'] = array_values( array_unique( array_merge( $original_use_context, $source->uses_context ) ) ); + return $args; + }, + 10, + 2 + ); + } return $source; } From d8886e828803b31b7587e741085ee3feed7113d3 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:11:01 +0100 Subject: [PATCH 13/20] Use `empty` function in post meta source --- lib/compat/wordpress-6.5/block-bindings/post-meta.php | 4 ++-- 1 file changed, 2 insertions(+), 2 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 b7c7d8da3d623..de7ae732aae3d 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -13,11 +13,11 @@ * @return mixed The value computed for the source. */ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_instance ) { - if ( ! isset( $source_attrs['key'] ) ) { + if ( empty( $source_attrs['key'] ) ) { return null; } - if ( ! isset( $block_instance->context['postId'] ) ) { + if ( empty( $block_instance->context['postId'] ) ) { return null; } $post_id = $block_instance->context['postId']; From 8dae6529d15a452cbd39618eab536883cbb6868e Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:17:23 +0100 Subject: [PATCH 14/20] Update descriptions --- .../block-bindings/block-bindings.php | 23 +++++++++--------- .../class-wp-block-bindings-registry.php | 24 +++++++++---------- .../block-bindings/post-meta.php | 5 ++-- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/block-bindings.php b/lib/compat/wordpress-6.5/block-bindings/block-bindings.php index 7ea0f1bab4683..1bcb23ccd6549 100644 --- a/lib/compat/wordpress-6.5/block-bindings/block-bindings.php +++ b/lib/compat/wordpress-6.5/block-bindings/block-bindings.php @@ -25,18 +25,19 @@ * @param array $source_properties { * The array of arguments that are used to register a source. * - * @type string $label The label of the source. - * @type callback $get_value_callback A callback executed when the source is processed during block rendering. - * The callback should have the following signature: + * @type string $label The label of the source. + * @type callback $get_value_callback A callback executed when the source is processed during block rendering. + * The callback should have the following signature: * - * `function ($source_args, $block_instance,$attribute_name): mixed` - * - @param array $source_args Array containing source arguments - * used to look up the override value, - * i.e. {"key": "foo"}. - * - @param WP_Block $block_instance The block instance. - * - @param string $attribute_name The name of an attribute . - * The callback has a mixed return type; it may return a string to override - * the block's original value, null, false to remove an attribute, etc. + * `function ($source_args, $block_instance,$attribute_name): mixed` + * - @param array $source_args Array containing source arguments + * used to look up the override value, + * i.e. {"key": "foo"}. + * - @param WP_Block $block_instance The block instance. + * - @param string $attribute_name The name of an attribute . + * The callback has a mixed return type; it may return a string to override + * the block's original value, null, false to remove an attribute, etc. + * @type array $uses_context (optional) Array of values to add to block `uses_context` needed by the source. * } * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure. */ diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index 53285248d32e4..cf6815ceeab5b 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -61,19 +61,19 @@ final class WP_Block_Bindings_Registry { * @param array $source_properties { * The array of arguments that are used to register a source. * - * @type string $label The label of the source. - * @type callback $get_value_callback A callback executed when the source is processed during block rendering. - * The callback should have the following signature: + * @type string $label The label of the source. + * @type callback $get_value_callback A callback executed when the source is processed during block rendering. + * The callback should have the following signature: * - * `function ($source_args, $block_instance,$attribute_name): mixed` - * - @param array $source_args Array containing source arguments - * used to look up the override value, - * i.e. {"key": "foo"}. - * - @param WP_Block $block_instance The block instance. - * - @param string $attribute_name The name of the target attribute. - * The callback has a mixed return type; it may return a string to override - * the block's original value, null, false to remove an attribute, etc. - * @type array $uses_context (optional) Array of values to add to block `uses_context` needed by the source. + * `function ($source_args, $block_instance,$attribute_name): mixed` + * - @param array $source_args Array containing source arguments + * used to look up the override value, + * i.e. {"key": "foo"}. + * - @param WP_Block $block_instance The block instance. + * - @param string $attribute_name The name of the target attribute. + * The callback has a mixed return type; it may return a string to override + * the block's original value, null, false to remove an attribute, etc. + * @type array $uses_context (optional) Array of values to add to block `uses_context` needed by the source. * } * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure. */ 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 de7ae732aae3d..5ce8eb7ac56ee 100644 --- a/lib/compat/wordpress-6.5/block-bindings/post-meta.php +++ b/lib/compat/wordpress-6.5/block-bindings/post-meta.php @@ -8,8 +8,9 @@ /** * Gets value for Post Meta source. * - * @param array $source_args Array containing source arguments used to look up the override value. - * Example: array( "key" => "foo" ). + * @param array $source_args Array containing source arguments used to look up the override value. + * Example: array( "key" => "foo" ). + * @param WP_Block $block_instance The block instance. * @return mixed The value computed for the source. */ function gutenberg_block_bindings_post_meta_callback( $source_attrs, $block_instance ) { From 9252a376bf40301439d2a79b2f1ebe034e839abb Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:22:13 +0100 Subject: [PATCH 15/20] Update $supported_blocks variable name --- .../block-bindings/class-wp-block-bindings-registry.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index cf6815ceeab5b..4dbff2b23a056 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -184,9 +184,9 @@ function ( $uses_context, $block_type ) use ( $source ) { add_filter( 'register_block_type_args', function ( $args, $block_name ) use ( $source ) { - $allowed_blocks = $this->allowed_blocks; + $supported_blocks = $this->supported_blocks; - if ( empty( $allowed_blocks[ $block_name ] ) || empty( $source->uses_context ) ) { + if ( empty( $supported_blocks[ $block_name ] ) || empty( $source->uses_context ) ) { return $args; } $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); From 058fa6e189c75757b590e75b450ffd1c0030f9b6 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:32:07 +0100 Subject: [PATCH 16/20] Use `in_array` properly --- .../block-bindings/class-wp-block-bindings-registry.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index 4dbff2b23a056..a86a22b6f878d 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -184,9 +184,7 @@ function ( $uses_context, $block_type ) use ( $source ) { add_filter( 'register_block_type_args', function ( $args, $block_name ) use ( $source ) { - $supported_blocks = $this->supported_blocks; - - if ( empty( $supported_blocks[ $block_name ] ) || empty( $source->uses_context ) ) { + if ( ! in_array( $block_name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { return $args; } $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); From a77a9ce66043ee2d7406bb74b2c8788fb8f71946 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:49:09 +0100 Subject: [PATCH 17/20] Update bindings registry comments --- .../class-wp-block-bindings-registry.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index a86a22b6f878d..28a5147e63013 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -109,14 +109,14 @@ public function register( string $source_name, array $source_properties ) { if ( $this->is_registered( $source_name ) ) { _doing_it_wrong( __METHOD__, - /* translators: %s: Block bindings source name. */ + // translators: %s: Block bindings source name. sprintf( __( 'Block bindings source "%s" already registered.' ), $source_name ), '6.5.0' ); return false; } - /* Validate that the source properties contain the label */ + // Validate that the source properties contain the label. if ( ! isset( $source_properties['label'] ) ) { _doing_it_wrong( __METHOD__, @@ -126,7 +126,7 @@ public function register( string $source_name, array $source_properties ) { return false; } - /* Validate that the source properties contain the get_value_callback */ + // Validate that the source properties contain the get_value_callback. if ( ! isset( $source_properties['get_value_callback'] ) ) { _doing_it_wrong( __METHOD__, @@ -136,7 +136,7 @@ public function register( string $source_name, array $source_properties ) { return false; } - /* Validate that the get_value_callback is a valid callback */ + // Validate that the get_value_callback is a valid callback. if ( ! is_callable( $source_properties['get_value_callback'] ) ) { _doing_it_wrong( __METHOD__, @@ -212,7 +212,7 @@ public function unregister( string $source_name ) { if ( ! $this->is_registered( $source_name ) ) { _doing_it_wrong( __METHOD__, - /* translators: %s: Block bindings source name. */ + // translators: %s: Block bindings source name. sprintf( __( 'Block binding "%s" not found.' ), $source_name ), '6.5.0' ); From 63b790e5d1504cae7d345912cd6e84eb8f53f323 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Tue, 13 Feb 2024 14:52:30 +0100 Subject: [PATCH 18/20] Update allowed_blocks variable name --- lib/compat/wordpress-6.5/blocks.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/compat/wordpress-6.5/blocks.php b/lib/compat/wordpress-6.5/blocks.php index c670e1363a7f8..d8c24b3772125 100644 --- a/lib/compat/wordpress-6.5/blocks.php +++ b/lib/compat/wordpress-6.5/blocks.php @@ -157,18 +157,16 @@ function gutenberg_block_bindings_replace_html( $block_content, $block_name, str * @param WP_Block $block_instance The block instance. */ function gutenberg_process_block_bindings( $block_content, $parsed_block, $block_instance ) { - // Allowed blocks that support block bindings. - // TODO: Look for a mechanism to opt-in for this. Maybe adding a property to block attributes? - $allowed_blocks = array( + $supported_block_attrs = array( 'core/paragraph' => array( 'content' ), 'core/heading' => array( 'content' ), 'core/image' => array( 'url', 'title', 'alt' ), 'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ), ); - // If the block doesn't have the bindings property or isn't one of the allowed block types, return. + // If the block doesn't have the bindings property or isn't one of the supported block types, return. if ( - ! isset( $allowed_blocks[ $block_instance->name ] ) || + ! isset( $supported_block_attrs[ $block_instance->name ] ) || empty( $parsed_block['attrs']['metadata']['bindings'] ) || ! is_array( $parsed_block['attrs']['metadata']['bindings'] ) ) { @@ -192,8 +190,8 @@ function gutenberg_process_block_bindings( $block_content, $parsed_block, $block $modified_block_content = $block_content; foreach ( $parsed_block['attrs']['metadata']['bindings'] as $attribute_name => $block_binding ) { - // If the attribute is not in the allowed list, process next attribute. - if ( ! in_array( $attribute_name, $allowed_blocks[ $block_instance->name ], true ) ) { + // If the attribute is not in the supported list, process next attribute. + if ( ! in_array( $attribute_name, $supported_block_attrs[ $block_instance->name ], true ) ) { continue; } // If no source is provided, or that source is not registered, process next attribute. From e557ab3aba548ea70dac607d0b179301aabcc217 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 16 Feb 2024 11:26:48 +0100 Subject: [PATCH 19/20] Check allowed properties in the registry --- .../class-wp-block-bindings-registry.php | 30 +++++++++++++++---- .../class-wp-block-bindings-source.php | 8 ++--- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index 28a5147e63013..739ef2434845f 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -32,6 +32,18 @@ final class WP_Block_Bindings_Registry { */ private static $instance = null; + /** + * Supported source properties that can be passed to the registered source. + * + * @since 6.5.0 + * @var array + */ + private $allowed_source_properties = array( + 'label', + 'get_value_callback', + 'uses_context', + ); + /** * Supported blocks that can use the block bindings API. * @@ -109,7 +121,7 @@ public function register( string $source_name, array $source_properties ) { if ( $this->is_registered( $source_name ) ) { _doing_it_wrong( __METHOD__, - // translators: %s: Block bindings source name. + /* translators: %s: Block bindings source name. */ sprintf( __( 'Block bindings source "%s" already registered.' ), $source_name ), '6.5.0' ); @@ -156,6 +168,16 @@ public function register( string $source_name, array $source_properties ) { return false; } + // Validate that the source properties contain only allowed properties. + if ( ! empty( array_diff( array_keys( $source_properties ), $this->allowed_source_properties ) ) ) { + _doing_it_wrong( + __METHOD__, + __( 'The $source_properties array contains invalid properties.' ), + '6.5.0' + ); + return false; + } + $source = new WP_Block_Bindings_Source( $source_name, $source_properties @@ -173,9 +195,7 @@ function ( $uses_context, $block_type ) use ( $source ) { return $uses_context; } // Use array_values to reset the array keys. - $merged_uses_context = array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) ); - - return $merged_uses_context; + return array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) ); }, 10, 2 @@ -212,7 +232,7 @@ public function unregister( string $source_name ) { if ( ! $this->is_registered( $source_name ) ) { _doing_it_wrong( __METHOD__, - // translators: %s: Block bindings source name. + /* translators: %s: Block bindings source name. */ sprintf( __( 'Block binding "%s" not found.' ), $source_name ), '6.5.0' ); diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php index 301343867d54e..1862f2af8bb11 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-source.php @@ -66,11 +66,9 @@ final class WP_Block_Bindings_Source { * @param array $source_properties The properties of the source. */ public function __construct( string $name, array $source_properties ) { - $this->name = $name; - $this->label = $source_properties['label']; - $this->get_value_callback = $source_properties['get_value_callback']; - if ( isset( $source_properties['uses_context'] ) ) { - $this->uses_context = $source_properties['uses_context']; + $this->name = $name; + foreach ( $source_properties as $property_name => $property_value ) { + $this->$property_name = $property_value; } } From d0c3e9e6804e075919b175feb6ee57657be8e307 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 16 Feb 2024 13:56:37 +0100 Subject: [PATCH 20/20] Use only compatibility filter --- .../class-wp-block-bindings-registry.php | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php index 739ef2434845f..7f04820050a91 100644 --- a/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php +++ b/lib/compat/wordpress-6.5/block-bindings/class-wp-block-bindings-registry.php @@ -186,37 +186,21 @@ public function register( string $source_name, array $source_properties ) { $this->sources[ $source_name ] = $source; // Add `uses_context` defined by block bindings sources. - // If `get_uses_context` exists (from WP 6.5), use its filter because it is more reliable. - if ( method_exists( 'WP_Block_Type', 'get_uses_context' ) ) { - add_filter( - 'get_block_type_uses_context', - function ( $uses_context, $block_type ) use ( $source ) { - if ( ! in_array( $block_type->name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { - return $uses_context; - } - // Use array_values to reset the array keys. - return array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) ); - }, - 10, - 2 - ); - } else { - add_filter( - 'register_block_type_args', - function ( $args, $block_name ) use ( $source ) { - if ( ! in_array( $block_name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { - return $args; - } - $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); - // Use array_values to reset the array keys. - $args['uses_context'] = array_values( array_unique( array_merge( $original_use_context, $source->uses_context ) ) ); - + add_filter( + 'register_block_type_args', + function ( $args, $block_name ) use ( $source ) { + if ( ! in_array( $block_name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { return $args; - }, - 10, - 2 - ); - } + } + $original_use_context = isset( $args['uses_context'] ) ? $args['uses_context'] : array(); + // Use array_values to reset the array keys. + $args['uses_context'] = array_values( array_unique( array_merge( $original_use_context, $source->uses_context ) ) ); + + return $args; + }, + 10, + 2 + ); return $source; }