diff --git a/blocks/header/class-header-block.php b/blocks/header/class-header-block.php index 63a0117..577b101 100644 --- a/blocks/header/class-header-block.php +++ b/blocks/header/class-header-block.php @@ -11,39 +11,43 @@ * Header block definition. */ class HeaderBlock extends Block { + /** + * @inheritdoc + */ + protected $icon = 'menu'; /** * {@inheritDoc} */ - protected function name() { + protected function name(): string { return 'creode-header'; } /** * {@inheritDoc} */ - protected function label() { + protected function label(): string { return 'Creode Header'; } /** * {@inheritDoc} */ - protected function fields() { + protected function fields(): array { return array(); } /** * {@inheritDoc} */ - protected function template() { + protected function template(): string { return plugin_dir_path( __FILE__ ) . 'templates/header.php'; } /** * {@inheritDoc} */ - protected function child_blocks() { + protected function child_blocks(): array { $menus_choices = array( '' => 'None', ); diff --git a/includes/class-block-cache.php b/includes/class-block-cache.php new file mode 100644 index 0000000..729d5f9 --- /dev/null +++ b/includes/class-block-cache.php @@ -0,0 +1,52 @@ +add_actions(); + } + + /** + * Clears block cache. + * + * @return void + */ + public function clear_block_cache(): void { + self::clear(); + } + + /** + * Gets the block cache directory. + * + * @return string + */ + public static function get_directory(): string { + return WP_CONTENT_DIR . '/cache/wp-blocks/'; + } + + /** + * Clears the block cache. + * + * @return void + */ + public static function clear(): void { + // Clear the cache. + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php'; + + $file_system_direct = new \WP_Filesystem_Direct( false ); + $file_system_direct->rmdir( self::get_directory(), true ); + } + + /** + * Adds actions to class. + */ + protected function add_actions(): void { + add_action( 'load-post.php', array( $this, 'clear_block_cache' ) ); + add_action( 'load-post-new.php', array( $this, 'clear_block_cache' ) ); + } +} diff --git a/includes/class-block.php b/includes/class-block.php index 12a9b9a..9e1a57c 100644 --- a/includes/class-block.php +++ b/includes/class-block.php @@ -11,41 +11,47 @@ * Abstract class to extend for each block. */ abstract class Block { + /** + * The blocks icon from https://developer.wordpress.org/resource/dashicons/ + * + * @var string + */ + protected $icon = 'block-default'; /** * Function for providing the block's name. * * @return string The block's name (must be hyphen separated). */ - abstract protected function name(); + abstract protected function name(): string; /** * Function for providing the block's label to be used within the WordPress UI. * * @return string The block's label. */ - abstract protected function label(); + abstract protected function label(): string; /** * Function for providing fields array. * * @return array An array of field definitions in ACF format. Please see: https://www.advancedcustomfields.com/resources/register-fields-via-php/. */ - abstract protected function fields(); + abstract protected function fields(): array; /** * Function for providing a path to the render template. * * @return string The path to the render template. */ - abstract protected function template(); + abstract protected function template(): string; /** * Function for providing the block's category. * * @return string The block's category. */ - protected function category() { + protected function category(): string { return 'common'; } @@ -54,7 +60,7 @@ protected function category() { * * @return ChildBlock[] Array of child blocks. */ - protected function child_blocks() { + protected function child_blocks(): array { return array(); } @@ -66,35 +72,76 @@ public function __construct() { $this->register_acf_fields(); foreach ( $this->child_blocks() as $child_block ) { - $this->register_child_block( $this->name(), $child_block, $this->name() ); + $this->register_child_block( 'acf/' . $this->name(), $child_block, $this->name() ); } } /** * Function to register the block with ACF. */ - protected function register_acf_block() { - if ( ! function_exists( 'acf_register_block_type' ) ) { + protected function register_acf_block(): void { + $this->register_block_type( + array( + 'name' => 'acf/' . $this->name(), + 'title' => $this->label(), + 'category' => $this->category(), + 'icon' => $this->icon, + 'render' => $this->template(), + 'textdomain' => 'wordpress-blocks', + ) + ); + } + + /** + * Registers the block type using the provided block data. + * + * @param array $block_data + * + * @return void + */ + protected function register_block_type( array $block_data ): void { + // Check if the cache folder exists. + $cache_folder = WP_CONTENT_DIR . '/cache/wp-blocks/'; + $block_folder = $cache_folder . str_replace( '/', '-', $block_data['name'] ); + $cache_file = $block_folder . '/block.json'; + if ( file_exists( $cache_file ) ) { + register_block_type( $block_folder ); return; } - acf_register_block_type( - array( - 'name' => $this->name(), - 'title' => $this->label(), - 'category' => $this->category(), - 'render_template' => $this->template(), - 'supports' => array( - 'jsx' => true, - ), - ) + // Create cache folder. + if ( ! file_exists( $cache_folder ) ) { + mkdir( $cache_folder, 0755, true ); + } + + // Create block folder. + if ( ! file_exists( $block_folder ) ) { + mkdir( $block_folder, 0755, true ); + } + + // Attach block schema to block data. + $block_data['$schema'] = 'https://schemas.wp.org/trunk/block.json'; + $block_data['apiVersion'] = 3; + + // Setup ACF Configuration for block. + $block_data['acf'] = array( + 'mode' => 'preview', + 'renderTemplate' => $block_data['render'], ); + + // Remove render key from block data as we no longer need it. + unset( $block_data['render'] ); + + // Save the block contents to cache file. + file_put_contents( $cache_file, json_encode( $block_data, JSON_UNESCAPED_SLASHES ) ); + + register_block_type( $block_folder ); } /** * Function to register the block's fields with ACF. */ - protected function register_acf_fields() { + protected function register_acf_fields(): void { if ( ! function_exists( 'acf_add_local_field_group' ) ) { return; } @@ -123,24 +170,22 @@ protected function register_acf_fields() { * @param string $parent_block The parent block name. * @param ChildBlock $child_block The child block to register. */ - protected function register_child_block( string $parent_block, ChildBlock $child_block ) { + protected function register_child_block( string $parent_block, ChildBlock $child_block ): void { if ( ! function_exists( 'acf_register_block_type' ) ) { return; } - // Register ACF block. - acf_register_block_type( + $this->register_block_type( array( - 'name' => $parent_block . '-' . $child_block->name, - 'title' => $child_block->label, - 'render_template' => $child_block->template, - 'category' => $this->category(), - 'parent' => array( - 'acf/' . $parent_block, - ), - 'supports' => array( - 'jsx' => true, + 'name' => $parent_block . '-' . $child_block->name, + 'title' => $child_block->label, + 'render' => $child_block->template, + 'category' => $this->category(), + 'icon' => $child_block->icon, + 'parent' => array( + $parent_block, ), + 'textdomain' => 'wordpress-blocks', ) ); @@ -148,10 +193,10 @@ protected function register_child_block( string $parent_block, ChildBlock $child add_filter( 'creode_blocks_parent_child_relationship', function ( array $blocks ) use ( $parent_block, $child_block ) { - if ( empty( $blocks[ 'acf/' . $parent_block ] ) ) { - $blocks[ 'acf/' . $parent_block ] = array(); + if ( empty( $blocks[ $parent_block ] ) ) { + $blocks[ $parent_block ] = array(); } - array_push( $blocks[ 'acf/' . $parent_block ], 'acf/' . $parent_block . '-' . $child_block->name ); + array_push( $blocks[ $parent_block ], $parent_block . '-' . $child_block->name ); return $blocks; } @@ -169,7 +214,7 @@ function ( array $blocks ) use ( $parent_block, $child_block ) { array( 'param' => 'block', 'operator' => '==', - 'value' => 'acf/' . $parent_block . '-' . $child_block->name, + 'value' => $parent_block . '-' . $child_block->name, ), ), ), diff --git a/includes/class-child-block.php b/includes/class-child-block.php index 3c002ab..f96d9b5 100644 --- a/includes/class-child-block.php +++ b/includes/class-child-block.php @@ -47,6 +47,13 @@ class ChildBlock { */ protected $child_blocks = array(); + /** + * Icon for Child block. + * + * @var string + */ + protected $icon = 'block-default'; + /** * Data input function. * @@ -61,13 +68,15 @@ public function __construct( string $label, array $fields = array(), string $template = '', - array $child_blocks = array() + array $child_blocks = array(), + string $icon = 'block-default' ) { $this->name = $name; $this->label = $label; $this->fields = $fields; $this->template = $template; $this->child_blocks = $child_blocks; + $this->icon = $icon; } /** diff --git a/plugin.php b/plugin.php index d7a0f3c..96b1da1 100644 --- a/plugin.php +++ b/plugin.php @@ -16,7 +16,10 @@ require_once plugin_dir_path( __FILE__ ) . 'includes/class-block.php'; require_once plugin_dir_path( __FILE__ ) . 'blocks/all.php'; require_once plugin_dir_path( __FILE__ ) . 'commands/class-make-block-command.php'; +require_once plugin_dir_path( __FILE__ ) . 'includes/class-block-cache.php'; if ( defined( 'WP_CLI' ) && WP_CLI ) { WP_CLI::add_command( 'make-block', 'Make_Block_Command' ); -} \ No newline at end of file +} + +new CreodeBlocks\Block_Cache();