Skip to content

Commit

Permalink
Editor: Add Block Bindings API helpers
Browse files Browse the repository at this point in the history
It is part of the sync from the Gutenberg plugin that introduces the registry for block binding sources required for the new Block Bindings API: WordPress/gutenberg#54536.

See #60282.
Follow-up [57373].
Props czapla, artemiosans, santosguillamot, sc0ttkclark, lgladdy, talldanwp, swissspidy, youknowriad, fabiankaegy, mukesh27.



git-svn-id: https://develop.svn.wordpress.org/trunk@57375 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
gziolo committed Jan 29, 2024
1 parent 9b0d0af commit 2ce87aa
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 16 deletions.
66 changes: 66 additions & 0 deletions src/wp-includes/block-bindings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* Block Bindings API
*
* Contains functions for managing block bindings in WordPress.
*
* @package WordPress
* @subpackage Block Bindings
* @since 6.5.0
*/

/**
* Registers a new block bindings source.
*
* Sources are used to override block's original attributes with a value
* coming from the source. Once a source is registered, it can be used by a
* block by setting its `metadata.bindings` attribute to a value that refers
* to the source.
*
* @since 6.5.0
*
* @param string $source_name The name of the source.
* @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 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.
* }
* @return array|false Source when the registration was successful, or `false` on failure.
*/
function register_block_bindings_source( $source_name, array $source_properties ) {
return WP_Block_Bindings_Registry::get_instance()->register( $source_name, $source_properties );
}

/**
* Unregisters a block bindings source.
*
* @since 6.5.0
*
* @param string $source_name Block bindings source name including namespace.
* @return array|false The unregistred block bindings source on success and `false` otherwise.
*/
function unregister_block_bindings_source( $source_name ) {
return WP_Block_Bindings_Registry::get_instance()->unregister( $source_name );
}

/**
* Retrieves the list of all registered block bindings sources.
*
* @since 6.5.0
*
* @return array The array of registered block bindings sources.
*/
function get_all_registered_block_bindings_sources() {
return WP_Block_Bindings_Registry::get_instance()->get_all_registered();
}
29 changes: 14 additions & 15 deletions src/wp-includes/class-wp-block-bindings-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

/**
* Core class used for interacting with block binding sources.
* Core class used for interacting with block bindings sources.
*
* @since 6.5.0
*/
Expand All @@ -20,7 +20,6 @@ final class WP_Block_Bindings_Registry {
* Holds the registered block bindings sources, keyed by source identifier.
*
* @since 6.5.0
*
* @var array
*/
private $sources = array();
Expand All @@ -34,7 +33,7 @@ final class WP_Block_Bindings_Registry {
private static $instance = null;

/**
* Registers a new block binding source.
* Registers a new block bindings source.
*
* Sources are used to override block's original attributes with a value
* coming from the source. Once a source is registered, it can be used by a
Expand Down Expand Up @@ -66,7 +65,7 @@ public function register( $source_name, array $source_properties ) {
if ( ! is_string( $source_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Block binding source name must be a string.' ),
__( 'Block bindings source name must be a string.' ),
'6.5.0'
);
return false;
Expand All @@ -75,7 +74,7 @@ public function register( $source_name, array $source_properties ) {
if ( preg_match( '/[A-Z]+/', $source_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Block binding source names must not contain uppercase characters.' ),
__( 'Block bindings source names must not contain uppercase characters.' ),
'6.5.0'
);
return false;
Expand All @@ -85,7 +84,7 @@ public function register( $source_name, array $source_properties ) {
if ( ! preg_match( $name_matcher, $source_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Block binding source names must contain a namespace prefix. Example: my-plugin/my-custom-source' ),
__( 'Block bindings source names must contain a namespace prefix. Example: my-plugin/my-custom-source' ),
'6.5.0'
);
return false;
Expand All @@ -94,8 +93,8 @@ public function register( $source_name, array $source_properties ) {
if ( $this->is_registered( $source_name ) ) {
_doing_it_wrong(
__METHOD__,
/* translators: %s: Block binding source name. */
sprintf( __( 'Block binding source "%s" already registered.' ), $source_name ),
/* translators: %s: Block bindings source name. */
sprintf( __( 'Block bindings source "%s" already registered.' ), $source_name ),
'6.5.0'
);
return false;
Expand All @@ -112,18 +111,18 @@ public function register( $source_name, array $source_properties ) {
}

/**
* Unregisters a block binding source.
* Unregisters a block bindings source.
*
* @since 6.5.0
*
* @param string $source_name Block binding source name including namespace.
* @return array|false The unregistred block binding source on success and `false` otherwise.
* @param string $source_name Block bindings source name including namespace.
* @return array|false The unregistred block bindings source on success and `false` otherwise.
*/
public function unregister( $source_name ) {
if ( ! $this->is_registered( $source_name ) ) {
_doing_it_wrong(
__METHOD__,
/* translators: %s: Block binding source name. */
/* translators: %s: Block bindings source name. */
sprintf( __( 'Block binding "%s" not found.' ), $source_name ),
'6.5.0'
);
Expand Down Expand Up @@ -153,7 +152,7 @@ public function get_all_registered() {
* @since 6.5.0
*
* @param string $source_name The name of the source.
* @return array|null The registered block binding source, or `null` if it is not registered.
* @return array|null The registered block bindings source, or `null` if it is not registered.
*/
public function get_registered( $source_name ) {
if ( ! $this->is_registered( $source_name ) ) {
Expand All @@ -164,12 +163,12 @@ public function get_registered( $source_name ) {
}

/**
* Checks if a block binding source is registered.
* Checks if a block bindings source is registered.
*
* @since 6.5.0
*
* @param string $source_name The name of the source.
* @return bool `true` if the block binding source is registered, `false` otherwise.
* @return bool `true` if the block bindings source is registered, `false` otherwise.
*/
public function is_registered( $source_name ) {
return isset( $this->sources[ $source_name ] );
Expand Down
3 changes: 2 additions & 1 deletion src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@
require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-posts.php';
require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-taxonomies.php';
require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-users.php';
require ABSPATH . WPINC . '/class-wp-block-editor-context.php';
require ABSPATH . WPINC . '/class-wp-block-bindings-registry.php';
require ABSPATH . WPINC . '/class-wp-block-editor-context.php';
require ABSPATH . WPINC . '/class-wp-block-type.php';
require ABSPATH . WPINC . '/class-wp-block-pattern-categories-registry.php';
require ABSPATH . WPINC . '/class-wp-block-patterns-registry.php';
Expand All @@ -343,6 +343,7 @@
require ABSPATH . WPINC . '/class-wp-block-parser.php';
require ABSPATH . WPINC . '/class-wp-classic-to-block-menu-converter.php';
require ABSPATH . WPINC . '/class-wp-navigation-fallback.php';
require ABSPATH . WPINC . '/block-bindings.php';
require ABSPATH . WPINC . '/blocks.php';
require ABSPATH . WPINC . '/blocks/index.php';
require ABSPATH . WPINC . '/block-editor.php';
Expand Down
86 changes: 86 additions & 0 deletions tests/phpunit/tests/block-bindings/register.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php
/**
* Tests for Block Bindings API helper functions.
*
* @package WordPress
* @subpackage Blocks
* @since 6.5.0
*
* @group blocks
* @group block-bindings
*/
class Tests_Block_Bindings_Register extends WP_UnitTestCase {

const TEST_SOURCE_NAME = 'test/source';
const TEST_SOURCE_PROPERTIES = array(
'label' => 'Test source',
);

/**
* Tear down after each test.
*
* @since 6.5.0
*/
public function tear_down() {
foreach ( get_all_registered_block_bindings_sources() as $source_name => $source_properties ) {
if ( str_starts_with( $source_name, 'test/' ) ) {
unregister_block_bindings_source( $source_name );
}
unregister_block_bindings_source( $source_name );
}

parent::tear_down();
}

/**
* Should find all registered sources.
*
* @ticket 60282
*
* @covers ::register_block_bindings_source
* @covers ::get_all_registered_block_bindings_sources
*/
public function test_get_all_registered() {
$source_one_name = 'test/source-one';
$source_one_properties = self::TEST_SOURCE_PROPERTIES;
register_block_bindings_source( $source_one_name, $source_one_properties );

$source_two_name = 'test/source-two';
$source_two_properties = self::TEST_SOURCE_PROPERTIES;
register_block_bindings_source( $source_two_name, $source_two_properties );

$source_three_name = 'test/source-three';
$source_three_properties = self::TEST_SOURCE_PROPERTIES;
register_block_bindings_source( $source_three_name, $source_three_properties );

$expected = array(
$source_one_name => array_merge( array( 'name' => $source_one_name ), $source_one_properties ),
$source_two_name => array_merge( array( 'name' => $source_two_name ), $source_two_properties ),
$source_three_name => array_merge( array( 'name' => $source_three_name ), $source_three_properties ),
);

$registered = get_all_registered_block_bindings_sources();
$this->assertSame( $expected, $registered );
}

/**
* Should unregister existing block binding source.
*
* @ticket 60282
*
* @covers ::register_block_bindings_source
* @covers ::unregister_block_bindings_source
*/
public function test_unregister_block_source() {
register_block_bindings_source( self::TEST_SOURCE_NAME, self::TEST_SOURCE_PROPERTIES );

$result = unregister_block_bindings_source( self::TEST_SOURCE_NAME );
$this->assertSame(
array_merge(
array( 'name' => self::TEST_SOURCE_NAME ),
self::TEST_SOURCE_PROPERTIES
),
$result
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public function test_unregister_not_registered_block() {
*
* @ticket 60282
*
* @covers WP_Block_Bindings_Registry::register
* @covers WP_Block_Bindings_Registry::unregister
*/
public function test_unregister_block_source() {
Expand Down

0 comments on commit 2ce87aa

Please sign in to comment.