Automattic\WooCommerce\Admin\Features\ProductBlockEditor
BlockRegistry{} │ WC 1.0
Deprecated since 10.9.0 Product editor extension APIs will be removed in WooCommerce 11.0.. It is no longer supported and may be removed in future releases. It is recommended to replace this function with the same one.
Product block registration and style registration functionality.
No Hooks.
Usage
$BlockRegistry = new BlockRegistry(); // use class methods
Methods
- public static get_instance()
- public is_registered( $block_name )
- public register_block_type_from_metadata( $file_or_folder )
- public register_categories( $block_categories, $editor_context )
- public unregister( $block_name )
- protected __construct()
- private augment_attributes( $attributes )
- private augment_uses_context( $uses_context )
- private get_file_path( $path, $dir )
- private has_role_support()
- private register_block( $block_name, $block_dir )
- private register_block_type_from_metadata_without_deprecation_notice( $file_or_folder )
- private register_product_blocks()
- private remove_block_prefix( $block_name )
Changelog
| Deprecated since 10.9.0 | Product editor extension APIs will be removed in WooCommerce 11.0. |
BlockRegistry{} BlockRegistry{} code WC 10.9.1
class BlockRegistry {
/**
* Version that product editor APIs were deprecated in.
*/
const DEPRECATED_SINCE = '10.9.0';
/**
* Generic blocks directory.
*/
const GENERIC_BLOCKS_DIR = 'product-editor/blocks/generic';
/**
* Product fields blocks directory.
*/
const PRODUCT_FIELDS_BLOCKS_DIR = 'product-editor/blocks/product-fields';
/**
* Array of all available generic blocks.
*/
const GENERIC_BLOCKS = array(
'woocommerce/conditional',
'woocommerce/product-checkbox-field',
'woocommerce/product-collapsible',
'woocommerce/product-radio-field',
'woocommerce/product-pricing-field',
'woocommerce/product-section',
'woocommerce/product-section-description',
'woocommerce/product-subsection',
'woocommerce/product-subsection-description',
'woocommerce/product-details-section-description',
'woocommerce/product-tab',
'woocommerce/product-toggle-field',
'woocommerce/product-taxonomy-field',
'woocommerce/product-text-field',
'woocommerce/product-text-area-field',
'woocommerce/product-number-field',
'woocommerce/product-linked-list-field',
'woocommerce/product-select-field',
'woocommerce/product-notice-field',
);
/**
* Array of all available product fields blocks.
*/
const PRODUCT_FIELDS_BLOCKS = array(
'woocommerce/product-catalog-visibility-field',
'woocommerce/product-custom-fields',
'woocommerce/product-custom-fields-toggle-field',
'woocommerce/product-description-field',
'woocommerce/product-downloads-field',
'woocommerce/product-images-field',
'woocommerce/product-inventory-email-field',
'woocommerce/product-sku-field',
'woocommerce/product-name-field',
'woocommerce/product-regular-price-field',
'woocommerce/product-sale-price-field',
'woocommerce/product-schedule-sale-fields',
'woocommerce/product-shipping-class-field',
'woocommerce/product-shipping-dimensions-fields',
'woocommerce/product-summary-field',
'woocommerce/product-tag-field',
'woocommerce/product-inventory-quantity-field',
'woocommerce/product-variation-items-field',
'woocommerce/product-password-field',
'woocommerce/product-list-field',
'woocommerce/product-has-variations-notice',
'woocommerce/product-single-variation-notice',
);
/**
* Singleton instance.
*
* @var BlockRegistry
*/
private static $instance = null;
/**
* Get the singleton instance.
*/
public static function get_instance(): BlockRegistry {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
protected function __construct() {
add_filter( 'block_categories_all', array( $this, 'register_categories' ), 10, 2 );
$this->register_product_blocks();
}
/**
* Get a file path for a given block file.
*
* @param string $path File path.
* @param string $dir File directory.
*/
private function get_file_path( $path, $dir ) {
return WC_ABSPATH . WCAdminAssets::get_path( 'js' ) . trailingslashit( $dir ) . $path;
}
/**
* Register all the product blocks.
*/
private function register_product_blocks() {
foreach ( self::PRODUCT_FIELDS_BLOCKS as $block_name ) {
$this->register_block( $block_name, self::PRODUCT_FIELDS_BLOCKS_DIR );
}
foreach ( self::GENERIC_BLOCKS as $block_name ) {
$this->register_block( $block_name, self::GENERIC_BLOCKS_DIR );
}
}
/**
* Register product related block categories.
*
* @param array[] $block_categories Array of categories for block types.
* @param WP_Block_Editor_Context $editor_context The current block editor context.
*/
public function register_categories( $block_categories, $editor_context ) {
if ( INIT::EDITOR_CONTEXT_NAME === $editor_context->name ) {
$block_categories[] = array(
'slug' => 'woocommerce',
'title' => __( 'WooCommerce', 'woocommerce' ),
'icon' => null,
);
}
return $block_categories;
}
/**
* Get the block name without the "woocommerce/" prefix.
*
* @param string $block_name Block name.
*
* @return string
*/
private function remove_block_prefix( $block_name ) {
if ( 0 === strpos( $block_name, 'woocommerce/' ) ) {
return substr_replace( $block_name, '', 0, strlen( 'woocommerce/' ) );
}
return $block_name;
}
/**
* Augment the attributes of a block by adding attributes that are used by the product editor.
*
* @param array $attributes Block attributes.
*/
private function augment_attributes( $attributes ) {
global $wp_version;
// Note: If you modify this function, also update the client-side
// registerWooBlockType function in @woocommerce/block-templates.
$augmented_attributes = array_merge(
$attributes,
array(
'_templateBlockId' => array(
'type' => 'string',
'role' => 'content',
),
'_templateBlockOrder' => array(
'type' => 'integer',
'role' => 'content',
),
'_templateBlockHideConditions' => array(
'type' => 'array',
'role' => 'content',
),
'_templateBlockDisableConditions' => array(
'type' => 'array',
'role' => 'content',
),
'disabled' => isset( $attributes['disabled'] ) ? $attributes['disabled'] : array(
'type' => 'boolean',
'role' => 'content',
),
)
);
if ( ! $this->has_role_support() ) {
foreach ( $augmented_attributes as $key => $attribute ) {
if ( isset( $attribute['role'] ) ) {
$augmented_attributes[ $key ]['__experimentalRole'] = $attribute['role'];
}
}
}
return $augmented_attributes;
}
/**
* Checks for block attribute role support.
*/
private function has_role_support() {
if ( Utils::wp_version_compare( '6.7', '>=' ) ) {
return true;
}
if ( is_plugin_active( 'gutenberg/gutenberg.php' ) ) {
$gutenberg_version = '';
if ( defined( 'GUTENBERG_VERSION' ) ) {
$gutenberg_version = GUTENBERG_VERSION;
}
if ( ! $gutenberg_version ) {
$gutenberg_data = get_file_data(
WP_PLUGIN_DIR . '/gutenberg/gutenberg.php',
array( 'Version' => 'Version' )
);
$gutenberg_version = $gutenberg_data['Version'];
}
return version_compare( $gutenberg_version, '19.4', '>=' );
}
return false;
}
/**
* Augment the uses_context of a block by adding attributes that are used by the product editor.
*
* @param array $uses_context Block uses_context.
*/
private function augment_uses_context( $uses_context ) {
// Note: If you modify this function, also update the client-side
// registerProductEditorBlockType function in @woocommerce/product-editor.
return array_merge(
isset( $uses_context ) ? $uses_context : array(),
array(
'postType',
)
);
}
/**
* Register a single block.
*
* @param string $block_name Block name.
* @param string $block_dir Block directory.
*
* @return WP_Block_Type|false The registered block type on success, or false on failure.
*/
private function register_block( $block_name, $block_dir ) {
$block_name = $this->remove_block_prefix( $block_name );
$block_json_file = $this->get_file_path( $block_name . '/block.json', $block_dir );
return $this->register_block_type_from_metadata_without_deprecation_notice( $block_json_file );
}
/**
* Check if a block is registered.
*
* @param string $block_name Block name.
*/
public function is_registered( $block_name ): bool {
$registry = \WP_Block_Type_Registry::get_instance();
return $registry->is_registered( $block_name );
}
/**
* Unregister a block.
*
* @param string $block_name Block name.
*/
public function unregister( $block_name ) {
$registry = \WP_Block_Type_Registry::get_instance();
if ( $registry->is_registered( $block_name ) ) {
$registry->unregister( $block_name );
}
}
/**
* Register a block type from metadata stored in the block.json file.
*
* @param string $file_or_folder Path to the JSON file with metadata definition for the block or
* path to the folder where the `block.json` file is located.
*
* @return \WP_Block_Type|false The registered block type on success, or false on failure.
*
* @deprecated 10.9.0 Product editor extension APIs will be removed in WooCommerce 11.0.
*/
public function register_block_type_from_metadata( $file_or_folder ) {
wc_deprecated_function(
'Automattic\WooCommerce\Admin\Features\ProductBlockEditor\BlockRegistry::register_block_type_from_metadata, which will be removed in WooCommerce 11.0',
self::DEPRECATED_SINCE
);
return $this->register_block_type_from_metadata_without_deprecation_notice( $file_or_folder );
}
/**
* Register a block type from metadata without emitting a deprecation notice for internal block registration.
*
* @param string $file_or_folder Path to the JSON file with metadata definition for the block or
* path to the folder where the `block.json` file is located.
*
* @return \WP_Block_Type|false The registered block type on success, or false on failure.
*/
private function register_block_type_from_metadata_without_deprecation_notice( $file_or_folder ) {
$metadata_file = ( ! str_ends_with( $file_or_folder, 'block.json' ) )
? trailingslashit( $file_or_folder ) . 'block.json'
: $file_or_folder;
if ( ! file_exists( $metadata_file ) ) {
return false;
}
// We are dealing with a local file, so we can use file_get_contents.
// phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
$metadata = json_decode( file_get_contents( $metadata_file ), true );
if ( ! is_array( $metadata ) || ! $metadata['name'] ) {
return false;
}
$this->unregister( $metadata['name'] );
return register_block_type_from_metadata(
$metadata_file,
array(
'attributes' => $this->augment_attributes( isset( $metadata['attributes'] ) ? $metadata['attributes'] : array() ),
'uses_context' => $this->augment_uses_context( isset( $metadata['usesContext'] ) ? $metadata['usesContext'] : array() ),
)
);
}
}