-
Notifications
You must be signed in to change notification settings - Fork 800
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
jetpack plugin: Add support for WordPress 6.7+'s block metadata colle…
…ction registration (#40064) * WIP: Add wp_register_block_metadata_collection to the jetpack plugin * changelog * Ignore WP sniffs for a build script Co-authored-by: Brad Jorsch <[email protected]> * Add new built file to gitignore to avoid committing and gitattributes to ensure it exists in built packages * fix some issues * fix directory constants, add comments * move register_block_metadata_collection * build_block_manifest: More error checking and comments * add unit test * add phan suppress comment * try to fix phan suppression * better changelog comment * change to _inc/blocks when registering * Update projects/plugins/jetpack/changelog/update-wp_register_block_metadata_collection Co-authored-by: Brad Jorsch <[email protected]> * Update projects/plugins/jetpack/tools/build-block-manifest.php Co-authored-by: Brad Jorsch <[email protected]> * Update projects/plugins/jetpack/tools/build-block-manifest.php Co-authored-by: Brad Jorsch <[email protected]> * move to build-extensions step * fix comment * move to _inc path --------- Co-authored-by: Brandon Kraft <[email protected]> Co-authored-by: Brad Jorsch <[email protected]>
- Loading branch information
1 parent
3de8166
commit 7e694b3
Showing
6 changed files
with
286 additions
and
1 deletion.
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
projects/plugins/jetpack/changelog/update-wp_register_block_metadata_collection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: minor | ||
Type: enhancement | ||
|
||
Use wp_register_block_metadata_collection() on WordPress 6.7+ to improve block registration performance by reducing filesystem operations. (See https://core.trac.wordpress.org/changeset/59132) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
projects/plugins/jetpack/tests/php/test_block_manifest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
<?php | ||
/** | ||
* Test file for Jetpack Block Manifest functionality. | ||
* | ||
* @package Jetpack | ||
*/ | ||
|
||
require_once dirname( __DIR__, 2 ) . '/tools/build-block-manifest.php'; | ||
|
||
/** | ||
* Test case for block manifest generation. | ||
*/ | ||
class WP_Test_Block_Manifest extends WP_UnitTestCase { | ||
|
||
/** | ||
* Temporary test directory path. | ||
* | ||
* @var string | ||
*/ | ||
private $test_dir; | ||
|
||
/** | ||
* Track files and directories we create. | ||
* | ||
* @var array | ||
*/ | ||
private $cleanup_paths = array(); | ||
|
||
/** | ||
* Set up the test environment. | ||
* | ||
* @return void | ||
*/ | ||
public function set_up() { | ||
parent::set_up(); | ||
|
||
// Create a temporary test directory. | ||
$this->test_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/jetpack-block-manifest-test-' . uniqid(); | ||
mkdir( $this->test_dir, 0777, true ); | ||
$this->cleanup_paths[] = $this->test_dir; | ||
} | ||
|
||
/** | ||
* Clean up after ourselves. | ||
* | ||
* @return void | ||
*/ | ||
public function tear_down() { | ||
// Remove files first, then directories in reverse order. | ||
foreach ( array_reverse( $this->cleanup_paths ) as $path ) { | ||
if ( is_file( $path ) ) { | ||
unlink( $path ); | ||
} elseif ( is_dir( $path ) ) { | ||
rmdir( $path ); | ||
} | ||
} | ||
parent::tear_down(); | ||
} | ||
|
||
/** | ||
* Test that the script fails properly when directory doesn't exist. | ||
* | ||
* @return void | ||
*/ | ||
public function test_nonexistent_directory() { | ||
$this->expectException( Exception::class ); | ||
$this->expectExceptionMessage( 'Input directory does not exist: /path/does/not/exist' ); | ||
build_block_manifest( '/path/does/not/exist' ); | ||
} | ||
|
||
/** | ||
* Test that the script handles empty directories correctly. | ||
* | ||
* @return void | ||
*/ | ||
public function test_empty_directory() { | ||
$this->expectException( Exception::class ); | ||
$this->expectExceptionMessage( "No block.json files found in: {$this->test_dir}" ); | ||
build_block_manifest( $this->test_dir ); | ||
} | ||
|
||
/** | ||
* Test invalid JSON handling. | ||
* | ||
* @return void | ||
*/ | ||
public function test_invalid_json() { | ||
// Create test directory and file. | ||
$block_dir = $this->test_dir . '/invalid-block'; | ||
mkdir( $block_dir ); | ||
$this->cleanup_paths[] = $block_dir; | ||
|
||
$json_file = $block_dir . '/block.json'; | ||
file_put_contents( $json_file, '{invalid json}' ); | ||
$this->cleanup_paths[] = $json_file; | ||
|
||
$this->expectException( Exception::class ); | ||
$this->expectExceptionMessage( 'No valid block.json files were processed' ); | ||
build_block_manifest( $this->test_dir ); | ||
} | ||
|
||
/** | ||
* Test successful manifest generation. | ||
* | ||
* @return void | ||
*/ | ||
public function test_successful_manifest_generation() { | ||
// Create test directories and files. | ||
$block1_dir = $this->test_dir . '/block1'; | ||
mkdir( $block1_dir ); | ||
$this->cleanup_paths[] = $block1_dir; | ||
|
||
$block1_json = $block1_dir . '/block.json'; | ||
file_put_contents( | ||
$block1_json, | ||
wp_json_encode( | ||
array( | ||
'name' => 'test/block1', | ||
'title' => 'Test Block 1', | ||
) | ||
) | ||
); | ||
$this->cleanup_paths[] = $block1_json; | ||
|
||
$block2_dir = $this->test_dir . '/block2'; | ||
mkdir( $block2_dir ); | ||
$this->cleanup_paths[] = $block2_dir; | ||
|
||
$block2_json = $block2_dir . '/block.json'; | ||
file_put_contents( | ||
$block2_json, | ||
wp_json_encode( | ||
array( | ||
'name' => 'test/block2', | ||
'title' => 'Test Block 2', | ||
) | ||
) | ||
); | ||
$this->cleanup_paths[] = $block2_json; | ||
|
||
// Generate manifest. | ||
$result = build_block_manifest( $this->test_dir ); | ||
$this->assertTrue( $result ); | ||
|
||
// Track manifest file for cleanup. | ||
$manifest_path = $this->test_dir . '/blocks-manifest.php'; | ||
$this->cleanup_paths[] = $manifest_path; | ||
|
||
// Verify the manifest was created and contains expected data. | ||
$this->assertFileExists( $manifest_path ); | ||
|
||
// Include and check manifest content. | ||
$manifest = include $manifest_path; | ||
$this->assertIsArray( $manifest ); | ||
$this->assertArrayHasKey( 'block1', $manifest ); | ||
$this->assertArrayHasKey( 'block2', $manifest ); | ||
$this->assertEquals( 'Test Block 1', $manifest['block1']['title'] ); | ||
$this->assertEquals( 'Test Block 2', $manifest['block2']['title'] ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
/** | ||
* Build script to generate a PHP manifest file containing block metadata from block.json files. | ||
* This reduces filesystem reads and JSON parsing at runtime. | ||
* | ||
* @package automattic/jetpack | ||
*/ | ||
|
||
// phpcs:disable WordPress.WP.AlternativeFunctions, WordPress.PHP.DevelopmentFunctions.error_log_var_export | ||
|
||
/** | ||
* Generates a manifest file containing block metadata from block.json files. | ||
* | ||
* Scans the given directory for block.json files, combines their metadata | ||
* into a single PHP file that returns an array. This improves performance | ||
* by avoiding filesystem reads and JSON parsing at runtime. | ||
* | ||
* @param string $base_path Optional. Base directory to scan for block.json files. | ||
* Defaults to Jetpack blocks directory. | ||
* @return bool True on success, throws Exception with error message on failure. | ||
* @throws Exception If directory doesn't exist, no files found, or write fails. | ||
*/ | ||
function build_block_manifest( $base_path = null ) { | ||
if ( null === $base_path ) { | ||
$base_path = __DIR__ . '/../_inc/blocks'; | ||
} | ||
|
||
if ( ! file_exists( $base_path ) ) { | ||
throw new Exception( "Input directory does not exist: {$base_path}", 1 ); | ||
} | ||
|
||
$blocks = array(); | ||
$files = glob( $base_path . '/*/block.json' ); | ||
|
||
if ( empty( $files ) ) { | ||
throw new Exception( "No block.json files found in: {$base_path}", 1 ); | ||
} | ||
|
||
foreach ( $files as $file ) { | ||
if ( ! file_exists( $file ) ) { | ||
// Log warning but continue processing other files. | ||
fwrite( STDERR, "\033[33mWarning:\033[0m Skipping missing file: {$file}\n" ); | ||
continue; | ||
} | ||
|
||
$json_content = file_get_contents( $file ); | ||
if ( false === $json_content ) { | ||
fwrite( STDERR, "\033[33mWarning:\033[0m Could not read file: {$file}\n" ); | ||
continue; | ||
} | ||
|
||
$block_data = json_decode( $json_content, true ); | ||
if ( null === $block_data ) { | ||
fwrite( STDERR, "\033[33mWarning:\033[0m Invalid JSON in file: {$file}\n" ); | ||
continue; | ||
} | ||
|
||
$dir_name = basename( dirname( $file ) ); | ||
$blocks[ $dir_name ] = $block_data; | ||
} | ||
|
||
if ( empty( $blocks ) ) { | ||
throw new Exception( 'No valid block.json files were processed', 1 ); | ||
} | ||
|
||
$output_path = $base_path . '/blocks-manifest.php'; | ||
$content = sprintf( | ||
"<?php\n" . | ||
"/**\n" . | ||
" * Generated block metadata manifest.\n" . | ||
" * @generated This file is generated. Do not modify it manually.\n" . | ||
" */\n\n" . | ||
"return %s;\n", | ||
var_export( $blocks, true ) | ||
); | ||
|
||
$file_put_result = file_put_contents( $output_path, $content ); | ||
if ( false === $file_put_result ) { | ||
throw new Exception( "Failed to write manifest file: {$output_path}", 1 ); | ||
} | ||
|
||
echo '✅ Generated block manifest at ' . $output_path . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | ||
echo 'Found ' . count( $blocks ) . " blocks\n"; | ||
|
||
return true; | ||
} | ||
|
||
// Only run the function if this script is being executed directly | ||
if ( defined( 'ABSPATH' ) && defined( 'DOING_TESTS' ) ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf | ||
// Do nothing - we're in a test environment | ||
} else { | ||
build_block_manifest(); | ||
} |