/home/preegmxb/bricks.theoriginalsstudios.com/wp-content/themes/bricks/includes/blocks.php
<?php
namespace Bricks;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Convert Gutenberg blocks to Bricks elements and vice versa
*/
class Blocks {
// Bricks elements objects that are able to be converted
private $elements = [];
// Converted Bricks data
private $output = [];
/**
* In order to convert Gutenberg content into a flat Bricks data, this object needs to be instantiated
*/
public function __construct() {}
/**
* Load post gutenberg blocks
*
* @param int $post_id
*/
public static function load_blocks( $post_id ) {
$post = get_post( $post_id );
if ( ! has_blocks( $post ) ) {
return false;
}
return parse_blocks( $post->post_content );
}
/**
* Prepare Bricks elements instances that are possible to be converted
*/
public static function load_elements() {
$elements = [];
foreach ( Elements::$elements as $element ) {
$element_class_name = $element['class'];
$element_instance = new $element_class_name( $element );
if ( isset( $element_instance->block ) && method_exists( $element_instance, 'convert_block_to_element_settings' ) ) {
foreach ( (array) $element_instance->block as $block ) {
$elements[ $block ] = $element_instance;
}
}
}
return $elements;
}
/**
* Convert gutenberg post content into bricks data
*
* @param int $post_id
*/
public function convert_blocks_to_bricks( $post_id ) {
$this->output = [];
// Loads Gutenberg data
$blocks = self::load_blocks( $post_id );
if ( empty( $blocks ) ) {
return [];
}
$this->elements = self::load_elements();
foreach ( $blocks as $block ) {
$this->convert_block_to_element( $block );
}
return $this->output;
}
/**
* Convert Gutenberg block to Bricks element
*
* To populate Bricks with existing Gutenberg blocks.
*
* Supported blocks (Gutenberg blockName > Bricks element['name']):
* - core/columns, core/buttons, core/group > container
* - core/heading > heading
* - core/paragraph > text
* - core/list > text
* - core/buttons > button
* - core/image > image
* - core/html > html
* - core/code > code
* - core/preformatted > code
* - core/video > video
* - core-embed/youtube > video
* - core-embed/vimeo > video
* - core/audio > audio
* - core/shortcode > shortcode
* - core/search > search
*/
public function convert_block_to_element( $block, $parent_id = 0 ) {
// Skip block without blockName (e.g. Classic Editor generated post_content, etc.)
if ( empty( $block['blockName'] ) ) {
return;
}
// Block is core/columns, core/buttons or core/group
if ( ! empty( $block['innerBlocks'] ) ) {
$row_id = Helpers::generate_random_id( false );
$row_settings = $this->add_common_block_settings( [], $block['attrs'] );
$row = [
'name' => 'container',
'id' => $row_id,
'parent' => $parent_id,
'settings' => $row_settings,
'children' => []
];
// Iterate through all the inner blocks
foreach ( $block['innerBlocks'] as $child_block ) {
if ( empty( $child_block['blockName'] ) ) {
continue;
}
// Child block is a column
if ( $child_block['blockName'] === 'core/column' ) {
$column_id = Helpers::generate_random_id( false );
$row['children'][] = $column_id;
$column_settings = $this->add_common_block_settings( [], $child_block['attrs'] );
$column = [
'name' => 'container',
'id' => $column_id,
'parent' => $row_id,
'settings' => $column_settings,
'children' => []
];
if ( ! empty( $child_block['innerBlocks'] ) && is_array( $child_block['innerBlocks'] ) ) {
foreach ( $child_block['innerBlocks'] as $inner_child_block ) {
$element = $this->convert_block_to_element( $inner_child_block, $column_id );
if ( ! empty( $element['id'] ) ) {
$column['children'][] = $element['id'];
}
}
}
// Add column to the flat list
$this->output[] = $column;
}
// Not a column, maybe a core/button
else {
$element = $this->convert_block_to_element( $child_block, $row_id );
if ( ! empty( $element['id'] ) ) {
$row['children'][] = $element['id'];
}
}
}
// Add row to the flat list
$this->output[] = $row;
// Leave, this block is added.
return $row;
}
// Regular block, check if we can convert it
if ( ! array_key_exists( $block['blockName'], $this->elements ) ) {
return false;
}
$bricks_element_instance = $this->elements[ $block['blockName'] ];
$element_settings = $bricks_element_instance->convert_block_to_element_settings( $block, $block['attrs'] );
if ( empty( $element_settings ) || ! is_array( $element_settings ) ) {
return false;
}
$element_settings = $this->add_common_block_settings( $element_settings, $block['attrs'] );
$element = [
'name' => $bricks_element_instance->name,
'id' => Helpers::generate_random_id( false ),
'parent' => $parent_id,
'settings' => $element_settings,
'children' => []
];
// Add element to the flat list
$this->output[] = $element;
return $element;
}
/**
* Add common block settings to Bricks data
*
* @param array $settings Bricks element settings.
* @param array $attributes GT block attributes.
*
* @return array
*/
public function add_common_block_settings( $settings, $attributes ) {
if ( empty( $attributes ) ) {
return $settings;
}
if ( isset( $attributes['className'] ) ) {
$settings['_cssClasses'] = trim( $attributes['className'] );
}
return $settings;
}
/**
* Generate blocks HTML string from Bricks content elements (to store as post_content)
*
* @param array $elements Array of all Bricks elements on a section.
* @param int $post_id The post ID.
*
* @return string
*
* @since 1.0
*/
public static function serialize_bricks_to_blocks( $elements, $post_id ) {
$blocks = [];
foreach ( $elements as $element ) {
$element_class_name = isset( Elements::$elements[ $element['name'] ]['class'] ) ? Elements::$elements[ $element['name'] ]['class'] : $element['name'];
$element_instance = new $element_class_name( $element );
$element_instance->set_post_id( $post_id );
$element_settings = isset( $element['settings'] ) && is_array( $element['settings'] ) ? $element['settings'] : [];
// Skip: Element has no settings / $block defined / convert_element_settings_to_block() function
if ( ! count( $element_settings ) || ! $element_instance->block || ! method_exists( $element_instance, 'convert_element_settings_to_block' ) ) {
continue;
}
// Get block HTML string plus comment attributes
$block = $element_instance->convert_element_settings_to_block( $element['settings'] );
// Process block content and handle {post_content}
$processed_block = serialize_block( $block );
// Remove curly brackets from {post_content} to avoid endless loop and memory exhaustion (@since 1.9.8)
if ( strpos( $processed_block, '{post_content}' ) !== false ) {
$processed_block = str_replace( '{post_content}', '(post_content)', $processed_block );
}
$blocks[] = $processed_block;
}
if ( count( $blocks ) ) {
return join( "\n\n", $blocks );
}
}
}