-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Introduce proper PHP classes for interacting with block types #1322
Changes from all commits
ce45293
d213309
9aa5fde
a84b787
8e379bf
a408132
6542555
e0539c7
ecc6dbb
c8e1464
d45da39
547b89b
75a065a
ca02a61
11c47bc
6b3ec26
d45a92a
c296165
b7d1824
21d8ee6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<?php | ||
/** | ||
* Blocks API: WP_Block_Type_Registry class | ||
* | ||
* @package gutenberg | ||
* @since 0.6.0 | ||
*/ | ||
|
||
/** | ||
* Core class used for interacting with block types. | ||
* | ||
* @since 0.6.0 | ||
*/ | ||
final class WP_Block_Type_Registry { | ||
/** | ||
* Registered block types, as `$name => $instance` pairs. | ||
* | ||
* @since 0.6.0 | ||
* @access private | ||
* @var array | ||
*/ | ||
private $registered_block_types = array(); | ||
|
||
/** | ||
* Container for the main instance of the class. | ||
* | ||
* @since 0.6.0 | ||
* @access private | ||
* @static | ||
* @var WP_Block_Type_Registry|null | ||
*/ | ||
private static $instance = null; | ||
|
||
/** | ||
* Registers a block type. | ||
* | ||
* @since 0.6.0 | ||
* @access public | ||
* | ||
* @param string|WP_Block_Type $name Block type name including namespace, or alternatively a | ||
* complete WP_Block_Type instance. In case a WP_Block_Type | ||
* is provided, the $args parameter will be ignored. | ||
* @param array $args { | ||
* Optional. Array of block type arguments. Any arguments may be defined, however the | ||
* ones described below are supported by default. Default empty array. | ||
* | ||
* @type callable $render_callback Callback used to render blocks of this block type. | ||
* } | ||
* @return WP_Block_Type|false The registered block type on success, or false on failure. | ||
*/ | ||
public function register( $name, $args = array() ) { | ||
$block_type = null; | ||
if ( is_a( $name, 'WP_Block_Type' ) ) { | ||
$block_type = $name; | ||
$name = $block_type->name; | ||
} | ||
|
||
if ( ! is_string( $name ) ) { | ||
$message = __( 'Block type names must be strings.', 'gutenberg' ); | ||
_doing_it_wrong( __METHOD__, $message, '0.1.0' ); | ||
return false; | ||
} | ||
|
||
$name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/'; | ||
if ( ! preg_match( $name_matcher, $name ) ) { | ||
$message = __( 'Block type names must contain a namespace prefix. Example: my-plugin/my-custom-block-type', 'gutenberg' ); | ||
_doing_it_wrong( __METHOD__, $message, '0.1.0' ); | ||
return false; | ||
} | ||
|
||
if ( $this->is_registered( $name ) ) { | ||
/* translators: 1: block name */ | ||
$message = sprintf( __( 'Block type "%s" is already registered.', 'gutenberg' ), $name ); | ||
_doing_it_wrong( __METHOD__, $message, '0.1.0' ); | ||
return false; | ||
} | ||
|
||
if ( ! $block_type ) { | ||
$block_type = new WP_Block_Type( $name, $args ); | ||
} | ||
|
||
$this->registered_block_types[ $name ] = $block_type; | ||
|
||
return $block_type; | ||
} | ||
|
||
/** | ||
* Unregisters a block type. | ||
* | ||
* @since 0.6.0 | ||
* @access public | ||
* | ||
* @param string|WP_Block_Type $name Block type name including namespace, or alternatively a | ||
* complete WP_Block_Type instance. | ||
* @return WP_Block_Type|false The unregistered block type on success, or false on failure. | ||
*/ | ||
public function unregister( $name ) { | ||
if ( is_a( $name, 'WP_Block_Type' ) ) { | ||
$name = $name->name; | ||
} | ||
|
||
if ( ! $this->is_registered( $name ) ) { | ||
/* translators: 1: block name */ | ||
$message = sprintf( __( 'Block type "%s" is not registered.', 'gutenberg' ), $name ); | ||
_doing_it_wrong( __METHOD__, $message, '0.1.0' ); | ||
return false; | ||
} | ||
|
||
$unregistered_block_type = $this->registered_block_types[ $name ]; | ||
unset( $this->registered_block_types[ $name ] ); | ||
|
||
return $unregistered_block_type; | ||
} | ||
|
||
/** | ||
* Retrieves a registered block type. | ||
* | ||
* @since 0.6.0 | ||
* @access public | ||
* | ||
* @param string $name Block type name including namespace. | ||
* @return WP_Block_Type|null The registered block type, or null if it is not registered. | ||
*/ | ||
public function get_registered( $name ) { | ||
if ( ! $this->is_registered( $name ) ) { | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of having mixed return types, is there an advantage to returning an instance of a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is a good question. Generally returning something like you say (implementing a general block type interface) makes sense, however these practices have never been followed by WordPress core. I'm wary of introducing such a pattern here as it contradicts of what people are used from working with core. I think such a topic belongs into a discussion of a bigger scope, which I'd love to have a working group for at some point (we had a similar discussion at WCEU). |
||
} | ||
|
||
return $this->registered_block_types[ $name ]; | ||
} | ||
|
||
/** | ||
* Retrieves all registered block types. | ||
* | ||
* @since 0.6.0 | ||
* @access public | ||
* | ||
* @return array Associative array of `$block_type_name => $block_type` pairs. | ||
*/ | ||
public function get_all_registered() { | ||
return $this->registered_block_types; | ||
} | ||
|
||
/** | ||
* Checks if a block type is registered. | ||
* | ||
* @since 0.6.0 | ||
* @access public | ||
* | ||
* @param tring $name Block type name including namespace. | ||
* @return bool True if the block type is registered, false otherwise. | ||
*/ | ||
public function is_registered( $name ) { | ||
return isset( $this->registered_block_types[ $name ] ); | ||
} | ||
|
||
/** | ||
* Utility method to retrieve the main instance of the class. | ||
* | ||
* The instance will be created if it does not exist yet. | ||
* | ||
* @since 0.6.0 | ||
* @access public | ||
* @static | ||
* | ||
* @return WP_Block_Type_Registry The main instance. | ||
*/ | ||
public static function get_instance() { | ||
if ( null === self::$instance ) { | ||
self::$instance = new self(); | ||
} | ||
|
||
return self::$instance; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to facilitate testing since the instance can't be cleared?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think testing should be possible as we could manually spin up instances of the
WP_Block_Type_Registry
class for most test cases, as we wouldn't need to use the main instance. Once tests have been added, we'll know for sure.