Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Bindings API: Create WP_Block_Bindings_Source class #6042

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/wp-includes/block-bindings.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
* 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.
* @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure.
*/
function register_block_bindings_source( string $source_name, array $source_properties ) {
return WP_Block_Bindings_Registry::get_instance()->register( $source_name, $source_properties );
Expand All @@ -50,7 +50,7 @@ function register_block_bindings_source( string $source_name, array $source_prop
* @since 6.5.0
*
* @param string $source_name Block bindings source name including namespace.
* @return array|false The unregistered block bindings source on success and `false` otherwise.
* @return WP_Block_Bindings_Source|false The unregistered block bindings source on success and `false` otherwise.
*/
function unregister_block_bindings_source( string $source_name ) {
return WP_Block_Bindings_Registry::get_instance()->unregister( $source_name );
Expand All @@ -61,7 +61,7 @@ function unregister_block_bindings_source( string $source_name ) {
*
* @since 6.5.0
*
* @return array The array of registered block bindings sources.
* @return WP_Block_Bindings_Source[] The array of registered block bindings sources.
*/
function get_all_registered_block_bindings_sources() {
return WP_Block_Bindings_Registry::get_instance()->get_all_registered();
Expand All @@ -73,7 +73,7 @@ function get_all_registered_block_bindings_sources() {
* @since 6.5.0
*
* @param string $source_name The name of the source.
* @return array|null The registered block bindings source, or `null` if it is not registered.
* @return WP_Block_Bindings_Source|null The registered block bindings source, or `null` if it is not registered.
*/
function get_block_bindings_source( string $source_name ) {
return WP_Block_Bindings_Registry::get_instance()->get_registered( $source_name );
Expand Down
44 changes: 37 additions & 7 deletions src/wp-includes/class-wp-block-bindings-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class WP_Block_Bindings_Registry {
* Holds the registered block bindings sources, keyed by source identifier.
*
* @since 6.5.0
* @var array
* @var WP_Block_Bindings_Source[]
*/
private $sources = array();

Expand Down Expand Up @@ -61,7 +61,7 @@ final class WP_Block_Bindings_Registry {
* 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.
* @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure.
*/
public function register( string $source_name, array $source_properties ) {
if ( ! is_string( $source_name ) ) {
Expand Down Expand Up @@ -102,8 +102,38 @@ public function register( string $source_name, array $source_properties ) {
return false;
}

$source = array_merge(
array( 'name' => $source_name ),
/* Validate that the source properties contain the label */
if ( ! isset( $source_properties['label'] ) ) {
_doing_it_wrong(
__METHOD__,
__( 'The $source_properties must contain a "label".' ),
'6.5.0'
);
return false;
}

/* Validate that the source properties contain the get_value_callback */
if ( ! isset( $source_properties['get_value_callback'] ) ) {
_doing_it_wrong(
__METHOD__,
__( 'The $source_properties must contain a "get_value_callback".' ),
'6.5.0'
);
return false;
}

/* Validate that the get_value_callback is a valid callback */
if ( ! is_callable( $source_properties['get_value_callback'] ) ) {
_doing_it_wrong(
__METHOD__,
__( 'The "get_value_callback" parameter must be a valid callback.' ),
'6.5.0'
);
return false;
}

$source = new WP_Block_Bindings_Source(
$source_name,
$source_properties
);

Expand All @@ -118,7 +148,7 @@ public function register( string $source_name, array $source_properties ) {
* @since 6.5.0
*
* @param string $source_name Block bindings source name including namespace.
* @return array|false The unregistered block bindings source on success and `false` otherwise.
* @return WP_Block_Bindings_Source|false The unregistered block bindings source on success and `false` otherwise.
*/
public function unregister( string $source_name ) {
if ( ! $this->is_registered( $source_name ) ) {
Expand All @@ -142,7 +172,7 @@ public function unregister( string $source_name ) {
*
* @since 6.5.0
*
* @return array The array of registered sources.
* @return WP_Block_Bindings_Source[] The array of registered sources.
*/
public function get_all_registered() {
return $this->sources;
Expand All @@ -154,7 +184,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 bindings source, or `null` if it is not registered.
* @return WP_Block_Bindings_Source|null The registered block bindings source, or `null` if it is not registered.
*/
public function get_registered( string $source_name ) {
if ( ! $this->is_registered( $source_name ) ) {
Expand Down
88 changes: 88 additions & 0 deletions src/wp-includes/class-wp-block-bindings-source.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
/**
* Block Bindings API: WP_Block_Bindings_Source class.
*
*
* @package WordPress
* @subpackage Block Bindings
* @since 6.5.0
*/

/**
* Class representing block bindings source.
*
* This class is designed for internal use by the Block Bindings registry.
*
* @since 6.5.0
* @access private
*
* @see WP_Block_Bindings_Registry
*/
final class WP_Block_Bindings_Source {

/**
* The name of the source.
*
* @since 6.5.0
* @var string
*/
public $name;

/**
* The label of the source.
*
* @since 6.5.0
* @var string
*/
public $label;


/**
* The function used to get the value from the source.
*
* @since 6.5.0
* @var callable
*/
private $get_value_callback;

/**
* Constructor.
*
* Do not use this constructor directly. Instead, use the
* `WP_Block_Bindings_Registry::register` method or the `register_block_bindings_source` function.
*
* @since 6.5.0
*
* @param string $name The name of the 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'];
}

/**
* Retrieves the value from the source.
*
* @since 6.5.0
*
* @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.
*
* @return mixed The value of the source.
*/
public function get_value( array $source_args, $block_instance, string $attribute_name ) {
return call_user_func_array( $this->get_value_callback, array( $source_args, $block_instance, $attribute_name ) );
}

/**
* Wakeup magic method.
*
* @since 6.5.0
*/
public function __wakeup() {
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
}
}
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 2 additions & 3 deletions src/wp-includes/class-wp-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,8 @@ private function process_block_bindings( $block_content ) {
continue;
}

$source_callback = $block_binding_source['get_value_callback'];
$source_args = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array();
$source_value = call_user_func_array( $source_callback, array( $source_args, $this, $attribute_name ) );
$source_args = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array();
$source_value = $block_binding_source->get_value( $source_args, $this, $attribute_name );

// If the value is not null, process the HTML based on the block and the attribute.
if ( ! is_null( $source_value ) ) {
Expand Down
1 change: 1 addition & 0 deletions src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
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-bindings-source.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';
Expand Down
48 changes: 32 additions & 16 deletions tests/phpunit/tests/block-bindings/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,24 @@
*/
class Tests_Block_Bindings_Register extends WP_UnitTestCase {

const TEST_SOURCE_NAME = 'test/source';
const TEST_SOURCE_PROPERTIES = array(
'label' => 'Test source',
);
public static $test_source_name = 'test/source';
public static $test_source_properties = array();

/**
* Set up before each test.
*
* @since 6.5.0
*/
public function set_up() {
parent::set_up();

self::$test_source_properties = array(
'label' => 'Test source',
'get_value_callback' => function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It would be possible to inject only get_value_callback here, but we can change that with the refactoring. Overall, that makes perfect sense to use a static variable 👍🏻

return 'test-value';
},
);
}

/**
* Tear down after each test.
Expand All @@ -39,24 +53,25 @@ public function tear_down() {
* @covers ::register_block_bindings_source
* @covers ::get_all_registered_block_bindings_sources
* @covers ::get_block_bindings_source
* @covers WP_Block_Bindings_Source::__construct
*/
public function test_get_all_registered() {
$source_one_name = 'test/source-one';
$source_one_properties = self::TEST_SOURCE_PROPERTIES;
$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;
$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;
$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 ),
$source_one_name => new WP_Block_Bindings_Source( $source_one_name, $source_one_properties ),
$source_two_name => new WP_Block_Bindings_Source( $source_two_name, $source_two_properties ),
$source_three_name => new WP_Block_Bindings_Source( $source_three_name, $source_three_properties ),
'core/post-meta' => get_block_bindings_source( 'core/post-meta' ),
'core/pattern-overrides' => get_block_bindings_source( 'core/pattern-overrides' ),
);
Expand All @@ -72,15 +87,16 @@ public function test_get_all_registered() {
*
* @covers ::register_block_bindings_source
* @covers ::unregister_block_bindings_source
* @covers WP_Block_Bindings_Source::__construct
*/
public function test_unregister_block_source() {
register_block_bindings_source( self::TEST_SOURCE_NAME, self::TEST_SOURCE_PROPERTIES );
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 = unregister_block_bindings_source( self::$test_source_name );
$this->assertEquals(
gziolo marked this conversation as resolved.
Show resolved Hide resolved
new WP_Block_Bindings_Source(
self::$test_source_name,
self::$test_source_properties
),
$result
);
Expand Down
Loading
Loading