• File: class-parse-blocks.php
  • Full Path: /home/matthif/www/wp-content/plugins/visual-portfolio/classes/class-parse-blocks.php
  • Date Modified: 12/12/2023 4:36 AM
  • File size: 4.79 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php
/**
 * Parse blocks from content and widgets
 *
 * @package visual-portfolio
 */

/**
 * Visual_Portfolio_Parse_Blocks
 */
class Visual_Portfolio_Parse_Blocks {
    
/**
     * Array of content, that already parsed.
     *
     * @var array
     */
    
public static $parsed_content = array();

    
/**
     * Array of reusable block IDs, that already parsed.
     *
     * @var array
     */
    
public static $parsed_reusable_blocks = array();

    
/**
     * Init.
     */
    
public static function init() {
        
add_action(
            
'wp',
            function() {
                
// Simple use `render_block` in FSE themes to enqueue assets.
                
if ( current_theme_supports'block-templates' ) ) {
                    
// Parse all blocks.
                    
add_action'render_block''Visual_Portfolio_Parse_Blocks::render_block'11);

                    
// Parse blocks manually from content and custom locations in Classic themes.
                
} else {
                    
// parse blocks from post content.
                    
Visual_Portfolio_Parse_Blocks::maybe_parse_blocks_from_content();

                    
// parse blocks from custom locations, that uses 'the_content' filter.
                    
add_filter'the_content''Visual_Portfolio_Parse_Blocks::maybe_parse_blocks_from_custom_location');
                    
add_filter'widget_block_content''Visual_Portfolio_Parse_Blocks::maybe_parse_blocks_from_custom_location');
                }
            }
        );
    }

    
/**
     * Standard callback to parse blocks (mostly solves problem with FSE themes and blocks inside templates).
     *
     * @param string $block_content - block content.
     * @param array  $block - block data.
     *
     * @return string
     */
    
public static function render_block$block_content$block ) {
        
// We don't need to parse inner blocks manually, because `render_block` filter will make it for us.
        
$block['innerBlocks'] = false;

        
self::parse_blocks( array( $block ), 'general' );

        return 
$block_content;
    }

    
/**
     * Parse blocks from custom locations.
     *
     * @param string $content - custom content.
     */
    
public static function maybe_parse_blocks_from_custom_location$content ) {
        if ( 
is_admin() ) {
            return 
$content;
        }

        if ( isset( 
$content ) ) {
            
self::maybe_parse_blocks$content'content' );
        }

        return 
$content;
    }

    
/**
     * Maybe parse blocks.
     *
     * @param string $content - content.
     * @param string $location - blocks location [content,widget].
     */
    
public static function maybe_parse_blocks$content$location 'content' ) {
        if (
            isset( 
$content ) &&
            
function_exists'has_blocks' ) &&
            
function_exists'parse_blocks' ) &&
            
$content &&
            
has_blocks$content )
        ) {
            
$is_parsed false;

            
// check if this content is already parsed.
            
foreach ( self::$parsed_content as $parsed ) {
                
$is_parsed $is_parsed || $parsed === $content;
            }

            if ( ! 
$is_parsed ) {
                
$blocks parse_blocks$content );

                
self::parse_blocks$blocks$location );

                
self::$parsed_content[] = $content;
            }
        }
    }

    
/**
     * Parse blocks from content.
     */
    
public static function maybe_parse_blocks_from_content() {
        global 
$wp_query;

        if ( 
is_admin() || ! isset( $wp_query->posts ) ) {
            return;
        }

        
// parse all posts content.
        
foreach ( $wp_query->posts as $post ) {
            if (
                isset( 
$post->post_content ) &&
                
function_exists'has_blocks' ) &&
                
function_exists'parse_blocks' ) &&
                
has_blocks$post )
            ) {
                
$blocks parse_blocks$post->post_content );
                
self::parse_blocks$blocks'content' );
            }
        }
    }

    
/**
     * Parse blocks including reusable and InnerBlocks and call action `vpf_parse_blocks`.
     *
     * @param array   $blocks - blocks array.
     * @param string  $location - blocks location [content,widget].
     * @param boolean $is_reusable - is from reusable block.
     * @param boolean $is_inner_blocks - is from inner blocks.
     */
    
public static function parse_blocks$blocks$location 'content'$is_reusable false$is_inner_blocks false ) {
        if ( ! 
is_array$blocks ) || empty( $blocks ) ) {
            return;
        }

        
do_action'vpf_parse_blocks'$blocks$location$is_reusable$is_inner_blocks );

        foreach ( 
$blocks as $block ) {
            
// Reusable Blocks.
            
if ( isset( $block['blockName'] ) && 'core/block' === $block['blockName'] && isset( $block['attrs']['ref'] ) ) {
                
// Check if this reusable block already parsed.
                // Fixes possible error with nested reusable blocks.
                
if ( ! in_array$block['attrs']['ref'], self::$parsed_reusable_blockstrue ) ) {
                    
self::$parsed_reusable_blocks[] = $block['attrs']['ref'];

                    
$reusable_block get_post$block['attrs']['ref'] );

                    if ( 
has_blocks$reusable_block ) && isset( $reusable_block->post_content ) ) {
                        
$post_blocks parse_blocks$reusable_block->post_content );
                        
self::parse_blocks$post_blocks$locationtrue );
                    }
                }
            }

            
// Inner blocks.
            
if ( isset( $block['innerBlocks'] ) ) {
                
self::parse_blocks$block['innerBlocks'], $location$is_reusabletrue );
            }
        }
    }
}

Visual_Portfolio_Parse_Blocks::init();