Changeset 57641
- Timestamp:
- 02/16/2024 12:53:16 PM (7 months ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-bindings.php
r57562 r57641 76 76 * The array of arguments that are used to register a source. 77 77 * 78 * @type string $label The label of the source.79 * @type callback $get_value_callback A callback executed when the source is processed during block rendering.80 * The callback should have the following signature:78 * @type string $label The label of the source. 79 * @type callback $get_value_callback A callback executed when the source is processed during block rendering. 80 * The callback should have the following signature: 81 81 * 82 * `function ($source_args, $block_instance,$attribute_name): mixed` 83 * - @param array $source_args Array containing source arguments 84 * used to look up the override value, 85 * i.e. {"key": "foo"}. 86 * - @param WP_Block $block_instance The block instance. 87 * - @param string $attribute_name The name of an attribute . 88 * The callback has a mixed return type; it may return a string to override 89 * the block's original value, null, false to remove an attribute, etc. 82 * `function ($source_args, $block_instance,$attribute_name): mixed` 83 * - @param array $source_args Array containing source arguments 84 * used to look up the override value, 85 * i.e. {"key": "foo"}. 86 * - @param WP_Block $block_instance The block instance. 87 * - @param string $attribute_name The name of an attribute . 88 * The callback has a mixed return type; it may return a string to override 89 * the block's original value, null, false to remove an attribute, etc. 90 * @type array $uses_context (optional) Array of values to add to block `uses_context` needed by the source. 90 91 * } 91 92 * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure. -
trunk/src/wp-includes/block-bindings/pattern-overrides.php
r57585 r57641 40 40 'label' => _x( 'Pattern Overrides', 'block bindings source' ), 41 41 'get_value_callback' => '_block_bindings_pattern_overrides_get_value', 42 'uses_context' => array( 'pattern/overrides' ), 42 43 ) 43 44 ); -
trunk/src/wp-includes/block-bindings/post-meta.php
r57526 r57641 14 14 * @access private 15 15 * 16 * @param array $source_args Array containing source arguments used to look up the override value. 17 * Example: array( "key" => "foo" ). 16 * @param array $source_args Array containing source arguments used to look up the override value. 17 * Example: array( "key" => "foo" ). 18 * @param WP_Block $block_instance The block instance. 18 19 * @return mixed The value computed for the source. 19 20 */ 20 function _block_bindings_post_meta_get_value( array $source_args ) {21 if ( ! isset( $source_args['key'] ) ) {21 function _block_bindings_post_meta_get_value( array $source_args, $block_instance ) { 22 if ( empty( $source_args['key'] ) ) { 22 23 return null; 23 24 } 24 25 25 // Use the postId attribute if available. 26 if ( isset( $source_args['postId'] ) ) { 27 $post_id = $source_args['postId']; 28 } else { 29 // $block_instance->context['postId'] is not available in the Image block. 30 $post_id = get_the_ID(); 26 if ( empty( $block_instance->context['postId'] ) ) { 27 return null; 31 28 } 29 $post_id = $block_instance->context['postId']; 32 30 33 31 // If a post isn't public, we need to prevent unauthorized users from accessing the post meta. … … 52 50 'label' => _x( 'Post Meta', 'block bindings source' ), 53 51 'get_value_callback' => '_block_bindings_post_meta_get_value', 52 'uses_context' => array( 'postId', 'postType' ), 54 53 ) 55 54 ); -
trunk/src/wp-includes/class-wp-block-bindings-registry.php
r57575 r57641 34 34 35 35 /** 36 * Supported source properties that can be passed to the registered source. 37 * 38 * @since 6.5.0 39 * @var array 40 */ 41 private $allowed_source_properties = array( 42 'label', 43 'get_value_callback', 44 'uses_context', 45 ); 46 47 /** 48 * Supported blocks that can use the block bindings API. 49 * 50 * @since 6.5.0 51 * @var array 52 */ 53 private $supported_blocks = array( 54 'core/paragraph', 55 'core/heading', 56 'core/image', 57 'core/button', 58 ); 59 60 /** 36 61 * Registers a new block bindings source. 37 62 * … … 54 79 * The array of arguments that are used to register a source. 55 80 * 56 * @type string $label The label of the source. 57 * @type callback $get_value_callback A callback executed when the source is processed during block rendering. 58 * The callback should have the following signature: 59 * 60 * `function ($source_args, $block_instance,$attribute_name): mixed` 61 * - @param array $source_args Array containing source arguments 62 * used to look up the override value, 63 * i.e. {"key": "foo"}. 64 * - @param WP_Block $block_instance The block instance. 65 * - @param string $attribute_name The name of the target attribute. 66 * The callback has a mixed return type; it may return a string to override 67 * the block's original value, null, false to remove an attribute, etc. 81 * @type string $label The label of the source. 82 * @type callback $get_value_callback A callback executed when the source is processed during block rendering. 83 * The callback should have the following signature: 84 * 85 * `function ($source_args, $block_instance,$attribute_name): mixed` 86 * - @param array $source_args Array containing source arguments 87 * used to look up the override value, 88 * i.e. {"key": "foo"}. 89 * - @param WP_Block $block_instance The block instance. 90 * - @param string $attribute_name The name of the target attribute. 91 * The callback has a mixed return type; it may return a string to override 92 * the block's original value, null, false to remove an attribute, etc. 93 * @type array $uses_context (optional) Array of values to add to block `uses_context` needed by the source. 68 94 * } 69 95 * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure. … … 108 134 } 109 135 110 / * Validate that the source properties contain the label */136 // Validates that the source properties contain the label. 111 137 if ( ! isset( $source_properties['label'] ) ) { 112 138 _doing_it_wrong( … … 118 144 } 119 145 120 / * Validate that the source properties contain the get_value_callback */146 // Validates that the source properties contain the get_value_callback. 121 147 if ( ! isset( $source_properties['get_value_callback'] ) ) { 122 148 _doing_it_wrong( … … 128 154 } 129 155 130 / * Validate that the get_value_callback is a valid callback */156 // Validates that the get_value_callback is a valid callback. 131 157 if ( ! is_callable( $source_properties['get_value_callback'] ) ) { 132 158 _doing_it_wrong( 133 159 __METHOD__, 134 160 __( 'The "get_value_callback" parameter must be a valid callback.' ), 161 '6.5.0' 162 ); 163 return false; 164 } 165 166 // Validates that the uses_context parameter is an array. 167 if ( isset( $source_properties['uses_context'] ) && ! is_array( $source_properties['uses_context'] ) ) { 168 _doing_it_wrong( 169 __METHOD__, 170 __( 'The "uses_context" parameter must be an array.' ), 171 '6.5.0' 172 ); 173 return false; 174 } 175 176 if ( ! empty( array_diff( array_keys( $source_properties ), $this->allowed_source_properties ) ) ) { 177 _doing_it_wrong( 178 __METHOD__, 179 __( 'The $source_properties array contains invalid properties.' ), 135 180 '6.5.0' 136 181 ); … … 145 190 $this->sources[ $source_name ] = $source; 146 191 192 // Adds `uses_context` defined by block bindings sources. 193 add_filter( 194 'get_block_type_uses_context', 195 function ( $uses_context, $block_type ) use ( $source ) { 196 if ( ! in_array( $block_type->name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { 197 return $uses_context; 198 } 199 // Use array_values to reset the array keys. 200 return array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) ); 201 }, 202 10, 203 2 204 ); 205 147 206 return $source; 148 207 } -
trunk/src/wp-includes/class-wp-block-bindings-source.php
r57562 r57641 47 47 48 48 /** 49 * The context added to the blocks needed by the source. 50 * 51 * @since 6.5.0 52 * @var array|null 53 */ 54 public $uses_context = null; 55 56 /** 49 57 * Constructor. 50 58 * … … 58 66 */ 59 67 public function __construct( string $name, array $source_properties ) { 60 $this->name = $name; 61 $this->label = $source_properties['label']; 62 $this->get_value_callback = $source_properties['get_value_callback']; 68 $this->name = $name; 69 foreach ( $source_properties as $property_name => $property_value ) { 70 $this->$property_name = $property_value; 71 } 63 72 } 64 73 -
trunk/src/wp-includes/class-wp-block-type.php
r57565 r57641 181 181 * @var string[] 182 182 */ 183 p ublic$uses_context = array();183 private $uses_context = array(); 184 184 185 185 /** … … 367 367 } 368 368 369 if ( 'uses_context' === $name ) { 370 return $this->get_uses_context(); 371 } 372 369 373 if ( ! in_array( $name, $this->deprecated_properties, true ) ) { 370 374 return; … … 395 399 */ 396 400 public function __isset( $name ) { 397 if ( 'variations' === $name) {401 if ( in_array( $name, array( 'variations', 'uses_context' ), true ) ) { 398 402 return true; 399 403 } … … 418 422 */ 419 423 public function __set( $name, $value ) { 420 if ( 'variations' === $name ) {421 $this->variations = $value;422 return;423 }424 425 424 if ( ! in_array( $name, $this->deprecated_properties, true ) ) { 426 425 $this->{$name} = $value; … … 617 616 return apply_filters( 'get_block_type_variations', $this->variations, $this ); 618 617 } 618 619 /** 620 * Get block uses context. 621 * 622 * @since 6.5.0 623 * 624 * @return array[] 625 */ 626 public function get_uses_context() { 627 /** 628 * Filters the registered uses context for a block type. 629 * 630 * @since 6.5.0 631 * 632 * @param array $uses_context Array of registered uses context for a block type. 633 * @param WP_Block_Type $block_type The full block type object. 634 */ 635 return apply_filters( 'get_block_type_uses_context', $this->uses_context, $this ); 636 } 619 637 } -
trunk/src/wp-includes/class-wp-block.php
r57576 r57641 232 232 */ 233 233 private function process_block_bindings() { 234 $parsed_block = $this->parsed_block; 235 236 $computed_attributes = array(); 237 238 // Allowed blocks that support block bindings. 239 // TODO: Look for a mechanism to opt-in for this. Maybe adding a property to block attributes? 240 $allowed_blocks = array( 234 $parsed_block = $this->parsed_block; 235 $computed_attributes = array(); 236 $supported_block_attributes = array( 241 237 'core/paragraph' => array( 'content' ), 242 238 'core/heading' => array( 'content' ), … … 245 241 ); 246 242 247 // If the block doesn't have the bindings property, isn't one of the allowed243 // If the block doesn't have the bindings property, isn't one of the supported 248 244 // block types, or the bindings property is not an array, return the block content. 249 245 if ( 250 ! isset( $ allowed_blocks[ $this->name ] ) ||246 ! isset( $supported_block_attributes[ $this->name ] ) || 251 247 empty( $parsed_block['attrs']['metadata']['bindings'] ) || 252 248 ! is_array( $parsed_block['attrs']['metadata']['bindings'] ) … … 256 252 257 253 foreach ( $parsed_block['attrs']['metadata']['bindings'] as $attribute_name => $block_binding ) { 258 // If the attribute is not in the allowed list, process next attribute.259 if ( ! in_array( $attribute_name, $ allowed_blocks[ $this->name ], true ) ) {254 // If the attribute is not in the supported list, process next attribute. 255 if ( ! in_array( $attribute_name, $supported_block_attributes[ $this->name ], true ) ) { 260 256 continue; 261 257 } -
trunk/tests/phpunit/tests/block-bindings/render.php
r57574 r57641 116 116 117 117 /** 118 * Tests passing `uses_context` as argument to the source. 119 * 120 * @ticket 60525 121 * 122 * @covers ::register_block_bindings_source 123 */ 124 public function test_passing_uses_context_to_source() { 125 $get_value_callback = function ( $source_args, $block_instance, $attribute_name ) { 126 $value = $block_instance->context['sourceContext']; 127 return "Value: $value"; 128 }; 129 130 register_block_bindings_source( 131 self::SOURCE_NAME, 132 array( 133 'label' => self::SOURCE_LABEL, 134 'get_value_callback' => $get_value_callback, 135 'uses_context' => array( 'sourceContext' ), 136 ) 137 ); 138 139 $block_content = <<<HTML 140 <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source", "args": {"key": "test"}}}}} --> 141 <p>This should not appear</p> 142 <!-- /wp:paragraph --> 143 HTML; 144 $parsed_blocks = parse_blocks( $block_content ); 145 $block = new WP_Block( $parsed_blocks[0], array( 'sourceContext' => 'source context value' ) ); 146 $result = $block->render(); 147 148 $this->assertSame( 149 'Value: source context value', 150 $block->attributes['content'], 151 "The 'content' should be updated with the value of the source context." 152 ); 153 $this->assertSame( 154 '<p>Value: source context value</p>', 155 trim( $result ), 156 'The block content should be updated with the value of the source context.' 157 ); 158 } 159 160 /** 118 161 * Tests if the block content is updated with the value returned by the source 119 162 * for the Image block in the placeholder state. -
trunk/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php
r57562 r57641 40 40 return 'test-value'; 41 41 }, 42 'uses_context' => array( 'sourceContext' ), 42 43 ); 43 44 } … … 158 159 159 160 self::$test_source_properties['get_value_callback'] = 'not-a-callback'; 161 162 $result = $this->registry->register( self::$test_source_name, self::$test_source_properties ); 163 $this->assertFalse( $result ); 164 } 165 166 /** 167 * Should reject block bindings registration if `uses_context` is not an array. 168 * 169 * @ticket 60525 170 * 171 * @covers WP_Block_Bindings_Registry::register 172 * 173 * @expectedIncorrectUsage WP_Block_Bindings_Registry::register 174 */ 175 public function test_register_invalid_string_uses_context() { 176 177 self::$test_source_properties['uses_context'] = 'not-an-array'; 160 178 161 179 $result = $this->registry->register( self::$test_source_name, self::$test_source_properties ); … … 180 198 $result 181 199 ); 200 $this->assertSame( 'test/source', $result->name ); 201 $this->assertSame( 'Test source', $result->label ); 202 $this->assertSame( 203 'test-value', 204 $result->get_value( array(), null, '' ) 205 ); 206 $this->assertEquals( array( 'sourceContext' ), $result->uses_context ); 182 207 } 183 208 … … 322 347 $this->assertTrue( $result ); 323 348 } 349 350 /** 351 * Tests merging `uses_context` from multiple sources. 352 * 353 * @ticket 60525 354 * 355 * @covers ::register_block_bindings_source 356 * @covers WP_Block_Type::get_uses_context 357 */ 358 public function test_merging_uses_context_from_multiple_sources() { 359 $get_value_callback = function () { 360 return 'Anything'; 361 }; 362 363 $block_registry = WP_Block_Type_Registry::get_instance(); 364 $original_uses_context = $block_registry->get_registered( 'core/paragraph' )->uses_context; 365 366 register_block_bindings_source( 367 'test/source-one', 368 array( 369 'label' => 'Test Source One', 370 'get_value_callback' => $get_value_callback, 371 'uses_context' => array( 'commonContext', 'sourceOneContext' ), 372 ) 373 ); 374 375 register_block_bindings_source( 376 'test/source-two', 377 array( 378 'label' => 'Test Source Two', 379 'get_value_callback' => $get_value_callback, 380 'uses_context' => array( 'commonContext', 'sourceTwoContext' ), 381 ) 382 ); 383 384 $new_uses_context = $block_registry->get_registered( 'core/paragraph' )->uses_context; 385 // Checks that the resulting `uses_context` contains the values from both sources. 386 $this->assertContains( 'commonContext', $new_uses_context ); 387 $this->assertContains( 'sourceOneContext', $new_uses_context ); 388 $this->assertContains( 'sourceTwoContext', $new_uses_context ); 389 // Checks that the resulting `uses_context` added 3 unique items. 390 $this->assertSame( count( $original_uses_context ) + 3, count( $new_uses_context ) ); 391 // Checks that the array isn't sparse to prevent issues in the editor. 392 $this->assertSame( array_key_last( $new_uses_context ), count( $new_uses_context ) - 1 ); 393 } 324 394 }
Note: See TracChangeset
for help on using the changeset viewer.