Ticket #62002: add-metadata-registry-v3.diff
File add-metadata-registry-v3.diff, 12.7 KB (added by , 5 months ago) |
---|
-
src/wp-includes/blocks.php
diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 1a8f3459c5..7a66781974 100644
a b function get_block_metadata_i18n_schema() { 375 375 return $i18n_block_schema; 376 376 } 377 377 378 /** 379 * Registers block metadata from a given source. 380 * 381 * This function allows core and third-party plugins to register their block metadata 382 * in a centralized location. Registering metadata can improve performance by avoiding 383 * multiple reads from the filesystem. 384 * 385 * @since 6.X.0 386 * 387 * @param string $source The source identifier for the metadata within the namespace. 388 * This can be a unique identifier for your plugin's blocks. 389 * @param array $metadata The block metadata to be registered. 390 */ 391 function wp_register_block_metadata( $source, $metadata ) { 392 WP_Block_Metadata_Registry::register( $source, $metadata ); 393 } 394 378 395 /** 379 396 * Registers a block type from the metadata stored in the `block.json` file. 380 397 * … … function get_block_metadata_i18n_schema() { 387 404 * @since 6.5.0 Added support for `allowedBlocks`, `viewScriptModule`, and `viewStyle` fields. 388 405 * @since 6.7.0 Allow PHP filename as `variations` argument. 389 406 * 390 * @param string $file_or_ folderPath to the JSON file with metadata definition for407 * @param string $file_or_metadata_source Path to the JSON file with metadata definition for 391 408 * the block or path to the folder where the `block.json` file is located. 392 409 * If providing the path to a JSON file, the filename must end with `block.json`. 410 * Alternatively, it can be a metadata source identifier 411 * (previously registered with `wp_register_block_metadata`). 393 412 * @param array $args Optional. Array of block type arguments. Accepts any public property 394 413 * of `WP_Block_Type`. See WP_Block_Type::__construct() for information 395 414 * on accepted arguments. Default empty array. 396 415 * @return WP_Block_Type|false The registered block type on success, or false on failure. 397 416 */ 398 function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 399 /* 400 * Get an array of metadata from a PHP file. 401 * This improves performance for core blocks as it's only necessary to read a single PHP file 402 * instead of reading a JSON file per-block, and then decoding from JSON to PHP. 403 * Using a static variable ensures that the metadata is only read once per request. 404 */ 405 static $core_blocks_meta; 406 if ( ! $core_blocks_meta ) { 407 $core_blocks_meta = require ABSPATH . WPINC . '/blocks/blocks-json.php'; 408 } 409 410 $metadata_file = ( ! str_ends_with( $file_or_folder, 'block.json' ) ) ? 411 trailingslashit( $file_or_folder ) . 'block.json' : 412 $file_or_folder; 417 function register_block_type_from_metadata( $file_or_metadata_source, $args = array() ) { 418 $metadata = array(); 413 419 414 $is_core_block = str_starts_with( $file_or_folder, ABSPATH . WPINC ); 415 // If the block is not a core block, the metadata file must exist. 416 $metadata_file_exists = $is_core_block || file_exists( $metadata_file ); 417 if ( ! $metadata_file_exists && empty( $args['name'] ) ) { 418 return false; 420 // Determine if we're dealing with a file/folder or a metadata source 421 if ( WP_Block_Metadata_Registry::has_metadata( $file_or_metadata_source ) ) { 422 $metadata_source = $file_or_metadata_source; 423 $file_or_folder = null; 424 } else { 425 $metadata_source = null; 426 $file_or_folder = $file_or_metadata_source; 419 427 } 420 428 421 // Try to get metadata from the static cache for core blocks.422 $metadata = array(); 429 $is_core_block = $file_or_folder && str_starts_with( $file_or_folder, ABSPATH . WPINC ); 430 423 431 if ( $is_core_block ) { 424 $core_block_name = str_replace( ABSPATH . WPINC . '/blocks/', '', $file_or_folder ); 425 if ( ! empty( $core_blocks_meta[ $core_block_name ] ) ) { 426 $metadata = $core_blocks_meta[ $core_block_name ]; 432 $core_block_name = 'core/' . str_replace( ABSPATH . WPINC . '/blocks/', '', $file_or_folder ); 433 $metadata = WP_Block_Metadata_Registry::get_metadata( $core_block_name ); 434 435 if ( null === $metadata ) { 436 // Load core metadata if not already registered. 437 $core_blocks_meta = require ABSPATH . WPINC . '/blocks/blocks-json.php'; 438 foreach ( $core_blocks_meta as $block_name => $block_meta ) { 439 $block_name = 'core/' . $block_name; 440 wp_register_block_metadata( $block_name, $block_meta ); 441 } 442 $metadata = WP_Block_Metadata_Registry::get_metadata( $core_block_name ); 427 443 } 444 } elseif ( $metadata_source ) { 445 $metadata = WP_Block_Metadata_Registry::get_metadata( $metadata_source ); 428 446 } 429 447 430 // If metadata is not found in the static cache, read it from the file. 431 if ( $metadata_file_exists && empty( $metadata ) ) { 432 $metadata = wp_json_file_decode( $metadata_file, array( 'associative' => true ) ); 448 // If metadata is not found in the registry, read from JSON file. 449 $metadata_file_exists = false; 450 if ( empty( $metadata ) && $file_or_folder ) { 451 $metadata_file = ( ! str_ends_with( $file_or_folder, 'block.json' ) ) ? 452 trailingslashit( $file_or_folder ) . 'block.json' : 453 $file_or_folder; 454 455 $metadata_file_exists = file_exists( $metadata_file ); 456 if ( $metadata_file_exists ) { 457 $metadata = wp_json_file_decode( $metadata_file, array( 'associative' => true ) ); 458 } else if ( ! $metadata_file_exists && empty( $args['name'] ) ) { 459 return false; 460 } 433 461 } 434 462 435 463 if ( ! is_array( $metadata ) || ( empty( $metadata['name'] ) && empty( $args['name'] ) ) ) { … … function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 716 744 * 717 745 * @since 5.0.0 718 746 * @since 5.8.0 First parameter now accepts a path to the `block.json` file. 747 * @since x.x.x First parameter now also accepts a metadata source identifier. 719 748 * 720 749 * @param string|WP_Block_Type $block_type Block type name including namespace, or alternatively 721 750 * a path to the JSON file with metadata definition for the block, 722 751 * or a path to the folder where the `block.json` file is located, 752 * or a metadata source identifier (previously registered with 753 * `wp_register_block_metadata`), 723 754 * or a complete WP_Block_Type instance. 724 755 * In case a WP_Block_Type is provided, the $args parameter will be ignored. 725 756 * @param array $args Optional. Array of block type arguments. Accepts any public property … … function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 729 760 * @return WP_Block_Type|false The registered block type on success, or false on failure. 730 761 */ 731 762 function register_block_type( $block_type, $args = array() ) { 732 if ( is_string( $block_type ) && file_exists( $block_type ) ) { 763 $passed_metadata_source = false; 764 if ( WP_Block_Metadata_Registry::has_metadata( $block_type ) && ( empty( $args ) || is_array( $args ) ) ) { 765 $passed_metadata_source = true; 766 } 767 768 if ( is_string( $block_type ) && 769 ( $passed_metadata_source || file_exists( $block_type ) ) ) { 733 770 return register_block_type_from_metadata( $block_type, $args ); 734 771 } 735 772 -
new file src/wp-includes/class-wp-block-metadata-registry.php
diff --git a/src/wp-includes/class-wp-block-metadata-registry.php b/src/wp-includes/class-wp-block-metadata-registry.php new file mode 100644 index 0000000000..5a3a4cb335
- + 1 <?php 2 /** 3 * Block Metadata Registry 4 * 5 * @package WordPress 6 * @subpackage Blocks 7 * @since 6.X.0 8 */ 9 10 /** 11 * Class used for managing block metadata from various sources. 12 * 13 * @since 6.X.0 14 */ 15 class WP_Block_Metadata_Registry { 16 17 /** 18 * Container for storing block metadata. 19 * 20 * @since 6.X.0 21 * @var array 22 */ 23 private static $metadata = array(); 24 25 /** 26 * Registers block metadata for a given source. 27 * 28 * @since 6.X.0 29 * 30 * @param string $source The source identifier for the metadata. 31 * @param array $metadata The block metadata. 32 */ 33 public static function register( $source, $metadata ) { 34 self::$metadata[ $source ] = $metadata; 35 } 36 37 /** 38 * Retrieves block metadata for a given source. 39 * 40 * @since 6.X.0 41 * 42 * @param string $source The source identifier for the metadata. 43 * @return array|null The block metadata for the source, or null if not found. 44 */ 45 public static function get_metadata( $source ) { 46 return isset( self::$metadata[ $source ] ) ? self::$metadata[ $source ] : null; 47 } 48 49 /** 50 * Checks if metadata exists for a given source. 51 * 52 * @since 6.X.0 53 * 54 * @param string $source The source identifier for the metadata. 55 * @return bool True if metadata exists for the source, false otherwise. 56 */ 57 public static function has_metadata( $source ) { 58 return isset( self::$metadata[ $source ] ); 59 } 60 61 /** 62 * Private constructor to prevent instantiation. 63 */ 64 private function __construct() { 65 // Prevent instantiation 66 } 67 } -
src/wp-settings.php
diff --git a/src/wp-settings.php b/src/wp-settings.php index d3dfe5776e..a152dd3f4f 100644
a b require ABSPATH . WPINC . '/class-wp-block-styles-registry.php'; 353 353 require ABSPATH . WPINC . '/class-wp-block-type-registry.php'; 354 354 require ABSPATH . WPINC . '/class-wp-block.php'; 355 355 require ABSPATH . WPINC . '/class-wp-block-list.php'; 356 require ABSPATH . WPINC . '/class-wp-block-metadata-registry.php'; 356 357 require ABSPATH . WPINC . '/class-wp-block-parser-block.php'; 357 358 require ABSPATH . WPINC . '/class-wp-block-parser-frame.php'; 358 359 require ABSPATH . WPINC . '/class-wp-block-parser.php'; -
tests/phpunit/tests/blocks/register.php
diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php index 7e0c391e1f..f371eca6cd 100644
a b class Tests_Blocks_Register extends WP_UnitTestCase { 1501 1501 $block_type->block_hooks 1502 1502 ); 1503 1503 } 1504 1505 /** 1506 * Tests registering a third-party block type using metadata from the registry. 1507 * 1508 * This test ensures that a block type can be registered using metadata stored 1509 * in the `WP_Block_Metadata_Registry` by providing a `$metadata_source` argument. 1510 * 1511 * @covers ::register_block_type_from_metadata 1512 */ 1513 public function test_register_block_type_from_registry_metadata() { 1514 $metadata = array( 1515 'name' => 'test/block-from-registry', 1516 'title' => 'Test Block From Registry', 1517 'category' => 'widgets', 1518 'icon' => 'smiley', 1519 'description' => 'This is a test block.', 1520 ); 1521 1522 WP_Block_Metadata_Registry::register( 'test/block-from-registry', $metadata ); 1523 1524 $result = register_block_type_from_metadata( 'test/block-from-registry', array() ); 1525 1526 $this->assertInstanceOf( 'WP_Block_Type', $result ); 1527 $this->assertEquals( 'test/block-from-registry', $result->name ); 1528 } 1529 1530 /** 1531 * Tests registering a block type from a `block.json` file. 1532 * 1533 * This test ensures that `register_block_type_from_metadata()` can still register 1534 * a block type using metadata from a `block.json` file when no `$metadata_source` 1535 * argument is provided. 1536 * 1537 * @covers ::register_block_type_from_metadata 1538 */ 1539 public function test_register_block_type_from_json_file() { 1540 $temp_dir = get_temp_dir(); 1541 $block_json = $temp_dir . 'block.json'; 1542 file_put_contents( 1543 $block_json, 1544 json_encode( 1545 array( 1546 'name' => 'test/json-block', 1547 'title' => 'Test JSON Block', 1548 ) 1549 ) 1550 ); 1551 1552 $result = register_block_type_from_metadata( $temp_dir ); 1553 1554 $this->assertInstanceOf( 'WP_Block_Type', $result ); 1555 $this->assertEquals( 'test/json-block', $result->name ); 1556 1557 unlink( $block_json ); 1558 } 1504 1559 } -
new file tests/phpunit/tests/blocks/wpBlockMetadataRegistry.php
diff --git a/tests/phpunit/tests/blocks/wpBlockMetadataRegistry.php b/tests/phpunit/tests/blocks/wpBlockMetadataRegistry.php new file mode 100644 index 0000000000..8d4f9a9bb7
- + 1 <?php 2 3 /** 4 * Tests for WP_Block_Metadata_Registry class. 5 * 6 * @group blocks 7 */ 8 class Tests_Blocks_WpBlockMetadataRegistry extends WP_UnitTestCase { 9 public function test_register_and_get_metadata() { 10 $source = 'test-source'; 11 $metadata = array( 12 'name' => 'test-block', 13 'title' => 'Test Block', 14 ); 15 16 WP_Block_Metadata_Registry::register( $source, $metadata ); 17 18 $retrieved_metadata = WP_Block_Metadata_Registry::get_metadata( $source ); 19 $this->assertEquals( $metadata, $retrieved_metadata ); 20 } 21 22 public function test_get_nonexistent_metadata() { 23 $retrieved_metadata = WP_Block_Metadata_Registry::get_metadata( 'nonexistent', 'nonexistent' ); 24 $this->assertNull( $retrieved_metadata ); 25 } 26 }