133 lines
3.3 KiB
PHP
133 lines
3.3 KiB
PHP
<?php
|
|
/**
|
|
* Block Template Utils class
|
|
*
|
|
* @since 4.7.0
|
|
* @package elasticpress
|
|
*/
|
|
|
|
namespace ElasticPress;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly.
|
|
}
|
|
|
|
/**
|
|
* Block Template Utils class
|
|
*/
|
|
class BlockTemplateUtils {
|
|
const CACHE_KEY = 'ep_blocks';
|
|
|
|
/**
|
|
* Hook cache cleanup calls
|
|
*/
|
|
public function setup() {
|
|
add_action( 'save_post_wp_template', [ $this, 'regenerate_cache' ] );
|
|
add_action( 'save_post_wp_template_part', [ $this, 'regenerate_cache' ] );
|
|
add_action( 'switch_theme', [ $this, 'regenerate_cache' ] );
|
|
}
|
|
|
|
/**
|
|
* Delete and regenerate the cache
|
|
*/
|
|
public function regenerate_cache() {
|
|
delete_transient( self::CACHE_KEY );
|
|
|
|
// Simply calling it will reset the transient (if the `ep_blocks_pre_all_blocks` filter isn't in use.)
|
|
$this->get_all_blocks_in_all_templates();
|
|
}
|
|
|
|
/**
|
|
* Given a block name, return all its instances across all block templates
|
|
*
|
|
* @param string $block_name The block name, e.g., `elasticpress/facet-meta`
|
|
* @return array
|
|
*/
|
|
public function get_specific_block_in_all_templates( string $block_name ) : array {
|
|
$blocks = array_filter(
|
|
$this->get_all_blocks_in_all_templates(),
|
|
function ( $block ) use ( $block_name ) {
|
|
return ( $block['blockName'] === $block_name );
|
|
}
|
|
);
|
|
|
|
return $blocks;
|
|
}
|
|
|
|
/**
|
|
* Get all blocks in all block templates
|
|
*
|
|
* It returns a flat list of all blocks, including innerBlocks.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_all_blocks_in_all_templates() : array {
|
|
/**
|
|
* Short-circuits the process of getting all blocks of a template.
|
|
*
|
|
* Returning a non-null value will effectively short-circuit the function.
|
|
*
|
|
* @since 4.7.0
|
|
* @hook ep_blocks_pre_all_blocks
|
|
* @param {null} $meta_keys Blocks array
|
|
* @return {null|array} Blocks array or `null` to keep default behavior
|
|
*/
|
|
$pre_all_blocks = apply_filters( 'ep_blocks_pre_all_blocks', null );
|
|
if ( null !== $pre_all_blocks ) {
|
|
return (array) $pre_all_blocks;
|
|
}
|
|
|
|
$cache = get_transient( self::CACHE_KEY );
|
|
if ( is_array( $cache ) ) {
|
|
return $cache;
|
|
}
|
|
|
|
$all_blocks = [];
|
|
|
|
$template_types = [ 'wp_template', 'wp_template_part' ];
|
|
|
|
foreach ( $template_types as $template_type ) {
|
|
$block_templates = get_block_templates( [], $template_type );
|
|
foreach ( $block_templates as $block_template ) {
|
|
$template_blocks = parse_blocks( $block_template->content );
|
|
|
|
foreach ( $template_blocks as $block ) {
|
|
$all_blocks[] = [
|
|
'blockName' => $block['blockName'],
|
|
'attrs' => $block['attrs'],
|
|
];
|
|
|
|
$all_blocks = $this->recursively_get_inner_blocks( $all_blocks, $block );
|
|
}
|
|
}
|
|
}
|
|
|
|
set_transient( self::CACHE_KEY, $all_blocks, MONTH_IN_SECONDS );
|
|
|
|
return $all_blocks;
|
|
}
|
|
|
|
/**
|
|
* Get all inner blocks recursively
|
|
*
|
|
* @param array $all_blocks All blocks analyzed so far
|
|
* @param array $block Block to be analyzed now
|
|
* @return array
|
|
*/
|
|
protected function recursively_get_inner_blocks( array $all_blocks, array $block ) : array {
|
|
if ( empty( $block['innerBlocks'] ) ) {
|
|
return $all_blocks;
|
|
}
|
|
|
|
foreach ( $block['innerBlocks'] as $inner_block ) {
|
|
$all_blocks[] = [
|
|
'blockName' => $inner_block['blockName'],
|
|
'attrs' => $inner_block['attrs'],
|
|
];
|
|
|
|
$all_blocks = $this->recursively_get_inner_blocks( $all_blocks, $inner_block );
|
|
}
|
|
|
|
return $all_blocks;
|
|
}
|
|
}
|