BlockRegistry.php
<?php
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor;
use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
class BlockRegistry {
const GENERIC_BLOCKS_DIR = 'product-editor/blocks/generic';
const PRODUCT_FIELDS_BLOCKS_DIR = 'product-editor/blocks/product-fields';
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',
);
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',
);
private static $instance = null;
public static function get_instance(): BlockRegistry {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
protected function __construct() {
add_filter( 'block_categories_all', array( $this, 'register_categories' ), 10, 2 );
$this->register_product_blocks();
}
private function get_file_path( $path, $dir ) {
return WC_ABSPATH . WCAdminAssets::get_path( 'js' ) . trailingslashit( $dir ) . $path;
}
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 );
}
}
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;
}
private function remove_block_prefix( $block_name ) {
if ( 0 === strpos( $block_name, 'woocommerce/' ) ) {
return substr_replace( $block_name, '', 0, strlen( 'woocommerce/' ) );
}
return $block_name;
}
private function augment_attributes( $attributes ) {
return array_merge(
$attributes,
array(
'_templateBlockId' => array(
'type' => 'string',
'__experimentalRole' => 'content',
),
'_templateBlockOrder' => array(
'type' => 'integer',
'__experimentalRole' => 'content',
),
'_templateBlockHideConditions' => array(
'type' => 'array',
'__experimentalRole' => 'content',
),
'_templateBlockDisableConditions' => array(
'type' => 'array',
'__experimentalRole' => 'content',
),
'disabled' => isset( $attributes['disabled'] ) ? $attributes['disabled'] : array(
'type' => 'boolean',
'__experimentalRole' => 'content',
),
)
);
}
private function augment_uses_context( $uses_context ) {
return array_merge(
isset( $uses_context ) ? $uses_context : array(),
array(
'postType',
)
);
}
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( $block_json_file );
}
public function is_registered( $block_name ): bool {
$registry = \WP_Block_Type_Registry::get_instance();
return $registry->is_registered( $block_name );
}
public function unregister( $block_name ) {
$registry = \WP_Block_Type_Registry::get_instance();
if ( $registry->is_registered( $block_name ) ) {
$registry->unregister( $block_name );
}
}
public function register_block_type_from_metadata( $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;
}
$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() ),
)
);
}
}