From 788c3b4ba88316d213f1c5cb9933f55530774145 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 29 Jan 2024 11:41:03 +0100 Subject: [PATCH 1/3] Blocks: Add block bindings registry class --- .../class-wp-block-bindings-registry.php | 194 +++++++++++++ .../wpBlockBindingsRegistry.php | 255 ++++++++++++++++++ 2 files changed, 449 insertions(+) create mode 100644 src/wp-includes/block-bindings/class-wp-block-bindings-registry.php create mode 100644 tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php diff --git a/src/wp-includes/block-bindings/class-wp-block-bindings-registry.php b/src/wp-includes/block-bindings/class-wp-block-bindings-registry.php new file mode 100644 index 0000000000000..baffd2f3dc900 --- /dev/null +++ b/src/wp-includes/block-bindings/class-wp-block-bindings-registry.php @@ -0,0 +1,194 @@ +is_registered( $source_name ) ) { + _doing_it_wrong( + __METHOD__, + /* translators: %s: Block binding source name. */ + sprintf( __( 'Block binding source "%s" already registered.' ), $source_name ), + '6.5.0' + ); + return false; + } + + $source = array_merge( + array( 'name' => $source_name ), + $source_properties + ); + + $this->sources[ $source_name ] = $source; + + return $source; + } + + /** + * Unregisters a block binding 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. + */ + public function unregister( $source_name ) { + if ( ! $this->is_registered( $source_name ) ) { + _doing_it_wrong( + __METHOD__, + /* translators: %s: Block binding source name. */ + sprintf( __( 'Block binding "%s" not found.' ), $source_name ), + '6.5.0' + ); + return false; + } + + $unregistered_source = $this->sources[ $source_name ]; + unset( $this->sources[ $source_name ] ); + + return $unregistered_source; + } + + /** + * Retrieves the list of all registered block bindings sources. + * + * @since 6.5.0 + * + * @return array The array of registered sources. + */ + public function get_all_registered() { + return $this->sources; + } + + /** + * Retrieves a registered block bindings source. + * + * @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. + */ + public function get_registered( $source_name ) { + if ( ! $this->is_registered( $source_name ) ) { + return null; + } + + return $this->sources[ $source_name ]; + } + + /** + * Checks if a block binding 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. + */ + public function is_registered( $source_name ) { + return isset( $this->sources[ $source_name ] ); + } + + /** + * Utility method to retrieve the main instance of the class. + * + * The instance will be created if it does not exist yet. + * + * @since 6.5.0 + * + * @return WP_Block_Bindings_Registry The main instance. + */ + public static function get_instance() { + if ( null === self::$instance ) { + self::$instance = new self(); + } + + return self::$instance; + } +} diff --git a/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php b/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php new file mode 100644 index 0000000000000..cdb602054dee3 --- /dev/null +++ b/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php @@ -0,0 +1,255 @@ + 'Test source', + ); + + /** + * Fake block bindings registry. + * + * @since 6.5.0 + * @var WP_Block_Bindings_Registry + */ + private $registry = null; + + /** + * Set up each test method. + * + * @since 6.5.0 + */ + public function set_up() { + parent::set_up(); + + $this->registry = new WP_Block_Bindings_Registry(); + } + + /** + * Tear down each test method. + * + * @since 6.5.0 + */ + public function tear_down() { + $this->registry = null; + + parent::tear_down(); + } + + /** + * Should reject numbers as block binding source name. + * + * @ticket 60282 + * + * @expectedIncorrectUsage WP_Block_Bindings_Registry::register + */ + public function test_register_invalid_non_string_names() { + $result = $this->registry->register( 1, self::TEST_SOURCE_PROPERTIES ); + $this->assertFalse( $result ); + } + + /** + * Should reject block binding source name without a namespace. + * + * @ticket 60282 + * + * @expectedIncorrectUsage WP_Block_Bindings_Registry::register + */ + public function test_register_invalid_names_without_namespace() { + $result = $this->registry->register( 'post-meta', self::TEST_SOURCE_PROPERTIES ); + $this->assertFalse( $result ); + } + + /** + * Should reject block binding source name with invalid characters. + * + * @ticket 60282 + * + * @expectedIncorrectUsage WP_Block_Bindings_Registry::register + */ + public function test_register_invalid_characters() { + $result = $this->registry->register( 'still/_doing_it_wrong', array() ); + $this->assertFalse( $result ); + } + + /** + * Should reject block binding source name with uppercase characters. + * + * @ticket 60282 + * + * @expectedIncorrectUsage WP_Block_Bindings_Registry::register + */ + public function test_register_invalid_uppercase_characters() { + $result = $this->registry->register( 'Core/PostMeta', self::TEST_SOURCE_PROPERTIES ); + $this->assertFalse( $result ); + } + + /** + * Should accept valid block binding source. + * + * @covers WP_Block_Bindings_Registry::register + * + * @ticket 60282 + */ + public function test_register_block_binding_source() { + $result = $this->registry->register( self::TEST_SOURCE_NAME, self::TEST_SOURCE_PROPERTIES ); + $this->assertSame( + array_merge( + array( 'name' => self::TEST_SOURCE_NAME ), + self::TEST_SOURCE_PROPERTIES + ), + $result + ); + } + + /** + * Unregistering should fail if a block binding source is not registered. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::unregister + * + * @expectedIncorrectUsage WP_Block_Bindings_Registry::unregister + */ + public function test_unregister_not_registered_block() { + $result = $this->registry->unregister( 'test/unregistered' ); + $this->assertFalse( $result ); + } + + /** + * Should unregister existing block binding source. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::unregister + */ + public function test_unregister_block_source() { + $this->registry->register( self::TEST_SOURCE_NAME, self::TEST_SOURCE_PROPERTIES ); + + $result = $this->registry->unregister( self::TEST_SOURCE_NAME ); + $this->assertSame( + array_merge( + array( 'name' => self::TEST_SOURCE_NAME ), + self::TEST_SOURCE_PROPERTIES + ), + $result + ); + } + + /** + * Should find all registered sources. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::register + * @covers WP_Block_Bindings_Registry::get_all_registered + */ + public function test_get_all_registered() { + $source_one_name = 'test/source-one'; + $source_one_properties = self::TEST_SOURCE_PROPERTIES; + $this->registry->register( $source_one_name, $source_one_properties ); + + $source_two_name = 'test/source-two'; + $source_two_properties = self::TEST_SOURCE_PROPERTIES; + $this->registry->register( $source_two_name, $source_two_properties ); + + $source_three_name = 'test/source-three'; + $source_three_properties = self::TEST_SOURCE_PROPERTIES; + $this->registry->register( $source_three_name, $source_three_properties ); + + $expected = array( + array_merge( array( 'name' => $source_one_name ), $source_one_properties ), + array_merge( array( 'name' => $source_two_name ), $source_two_properties ), + array_merge( array( 'name' => $source_three_name ), $source_three_properties ), + ); + + $registered = $this->registry->get_all_registered(); + $this->assertSame( $expected, $registered ); + } + + /** + * Should not find source that's not registered. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::register + * @covers WP_Block_Bindings_Registry::get_registered + */ + public function test_get_registered_rejects_unknown_source_name() { + $this->registry->register( self::TEST_SOURCE_NAME, self::TEST_SOURCE_PROPERTIES ); + + $source = $this->registry->get_registered( 'test/unknown-source' ); + $this->assertNull( $source ); + } + + /** + * Should find registered block binding source by name. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::register + * @covers WP_Block_Bindings_Registry::get_registered + */ + public function test_get_registered() { + $source_one_name = 'test/source-one'; + $source_one_properties = self::TEST_SOURCE_PROPERTIES; + $this->registry->register( $source_one_name, $source_one_properties ); + + $source_two_name = 'test/source-two'; + $source_two_properties = self::TEST_SOURCE_PROPERTIES; + $this->registry->register( $source_two_name, $source_two_properties ); + + $source_three_name = 'test/source-three'; + $source_three_properties = self::TEST_SOURCE_PROPERTIES; + $this->registry->register( $source_three_name, $source_three_properties ); + + $result = $this->registry->get_registered( 'test/source-two' ); + $this->assertSame( + array_merge( + array( 'name' => $source_two_name ), + $source_two_properties + ), + $result + ); + } + + /** + * Should return false for source that's not registered. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::register + * @covers WP_Block_Bindings_Registry::is_registered + */ + public function test_is_registered_for_unknown_source() { + $result = $this->registry->is_registered( 'test/one' ); + $this->assertFalse( $result ); + } + + /** + * Should return true if source is registered. + * + * @ticket 60282 + * + * @covers WP_Block_Bindings_Registry::register + * @covers WP_Block_Bindings_Registry::is_registered + */ + public function test_is_registered_for_known_source() { + $this->registry->register( self::TEST_SOURCE_NAME, self::TEST_SOURCE_PROPERTIES ); + + $result = $this->registry->is_registered( self::TEST_SOURCE_NAME ); + $this->assertTrue( $result ); + } +} From 145fb22df0842ae171171d5ff19bf51396dcd8fc Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 29 Jan 2024 11:46:34 +0100 Subject: [PATCH 2/3] Move and require the class --- .../{block-bindings => }/class-wp-block-bindings-registry.php | 0 src/wp-settings.php | 1 + 2 files changed, 1 insertion(+) rename src/wp-includes/{block-bindings => }/class-wp-block-bindings-registry.php (100%) diff --git a/src/wp-includes/block-bindings/class-wp-block-bindings-registry.php b/src/wp-includes/class-wp-block-bindings-registry.php similarity index 100% rename from src/wp-includes/block-bindings/class-wp-block-bindings-registry.php rename to src/wp-includes/class-wp-block-bindings-registry.php diff --git a/src/wp-settings.php b/src/wp-settings.php index e30eeb493b86b..9904bf500371f 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -330,6 +330,7 @@ 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-type.php'; require ABSPATH . WPINC . '/class-wp-block-pattern-categories-registry.php'; require ABSPATH . WPINC . '/class-wp-block-patterns-registry.php'; From 1a408d51337767a15fbcc78f80699158694947c3 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 29 Jan 2024 11:50:44 +0100 Subject: [PATCH 3/3] Fix the failing test --- .../tests/block-bindings/wpBlockBindingsRegistry.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php b/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php index cdb602054dee3..8fcd9648ad846 100644 --- a/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php +++ b/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php @@ -170,9 +170,9 @@ public function test_get_all_registered() { $this->registry->register( $source_three_name, $source_three_properties ); $expected = array( - array_merge( array( 'name' => $source_one_name ), $source_one_properties ), - array_merge( array( 'name' => $source_two_name ), $source_two_properties ), - array_merge( array( 'name' => $source_three_name ), $source_three_properties ), + $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 = $this->registry->get_all_registered(); @@ -230,7 +230,6 @@ public function test_get_registered() { * * @ticket 60282 * - * @covers WP_Block_Bindings_Registry::register * @covers WP_Block_Bindings_Registry::is_registered */ public function test_is_registered_for_unknown_source() {