File: //home/globfdxw/www/wp-content/plugins/kirki/includes/Frontend/Preview/DataHelper.php
<?php
/**
* Preview scripts data and styles helper
*
* @package kirki
*/
namespace Kirki\Frontend\Preview;
use Kirki\HelperFunctions;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class DataHelper
*/
class DataHelper {
/**
* Temporary IDs store
*
* @var array
*/
public $temp_ids = array();
/**
* Temporary Data store
*
* @var array
*/
public $temp_data = array();
public $temp_styles = array();
/**
* Generate or retrieve a unique new ID for a given original ID.
*
* @param int $id Original ID.
* @param string $prefix ID prefix.
*
* @return string Unique new ID.
*/
private function get_unique_new_id( $id, $prefix = 'kirki-s' ) {
if ( isset( $this->temp_ids[ $id ] ) ) {
return $this->temp_ids[ $id ];
}
$new_id = $prefix . '-' . uniqid();
$this->temp_ids[ $id ] = $new_id;
return $new_id;
}
/**
* Recursively update IDs and build a new data structure.
*
* @param array $data Source data array.
* @param string $root Root element ID.
* @param string $symbol_id Optional symbol ID for class prefixing.
*/
public function rec_update_data_id_to_new_id( $data, $styles, $root, $symbol_id = null ) {
if ( ! isset( $data[ $root ] ) ) {
return;
}
$prefix = $symbol_id ? 'kirki-s' . $symbol_id : null;
$new_id = $this->get_unique_new_id( $root );
$element = $data[ $root ];
$element['id'] = $new_id;
if ( isset( $element['styleIds'] ) && ! empty( $element['styleIds'] ) ) {
foreach ( $element['styleIds'] as $style_id ) {
if ( isset( $styles[ $style_id ] ) ) {
$this->temp_styles[ $style_id ] = $styles[ $style_id ];
}
}
}
// Update parent ID
if ( $element['parentId'] !== null ) {
$element['parentId'] = $this->get_unique_new_id( $element['parentId'] );
}
// Update children
if ( ! empty( $element['children'] ) ) {
$children = array();
foreach ( $element['children'] as $child_id ) {
$child_new_id = $this->get_unique_new_id( $child_id );
$children[] = $child_new_id;
$this->rec_update_data_id_to_new_id( $data, $styles, $child_id, $symbol_id );
}
$element['children'] = $children;
}
// Update content elements
if ( isset( $element['properties']['contents'] ) && is_array( $element['properties']['contents'] ) ) {
$contents = array();
foreach ( $element['properties']['contents'] as $content ) {
if ( is_array( $content ) && isset( $content['id'] ) ) {
$content_id = $this->get_unique_new_id( $content['id'] );
$contents[] = array( 'id' => $content_id );
$this->rec_update_data_id_to_new_id( $data, $styles, $content['id'], $symbol_id );
} else {
$contents[] = $content;
}
}
$element['properties']['contents'] = $contents;
}
// Update interaction class names and element IDs
if ( isset( $element['properties']['interactions'] ) ) {
$this->update_interactions( $element['properties']['interactions'], $prefix, $styles );
}
$this->temp_data[ $element['id'] ] = $element;
}
/**
* Helper function to update interaction class names and element IDs.
*
* @param array &$interactions Interaction properties reference.
* @param string $prefix Optional prefix for class names.
*/
private function update_interactions( &$interactions, $prefix, $styles ) {
// TODO: we need to set $this->styles if available in interaction panel.
foreach ( $interactions as $key => &$value ) {
if ( $key === 'deviceAndClassList' && isset( $value['classList'] ) && $prefix ) {
$value['classList'] = HelperFunctions::add_prefix_to_class_name( $prefix, $value['classList'] );
} elseif ( $key === 'elementAsTrigger' ) {
foreach ( $value as &$event ) {
foreach ( $event as &$preset_or_custom ) {
foreach ( $preset_or_custom as &$action ) {
$new_data = array();
foreach ( $action['data'] as $ele_id => $animation ) {
if ( strpos( $ele_id, '____info' ) !== false ) {
continue;
}
$new_id = $this->get_unique_new_id( $ele_id );
$new_data[ $new_id ] = $animation;
// Copy associated info and update classList if needed
$info_key = $ele_id . '____info';
if ( isset( $action['data'][ $info_key ] ) ) {
$info = $action['data'][ $info_key ];
if ( isset( $info['classList'] ) && $prefix ) {
$info['classList'] = HelperFunctions::add_prefix_to_class_name( $prefix, $info['classList'] );
}
$new_data[ $new_id . '____info' ] = $info;
}
}
$action['data'] = $new_data;
}
}
}
}
}
}
/**
* Recursively collect data and styles starting from a root block.
*
* @param string $root_id Root block ID.
* @param array &$data_n_styles Output container for blocks and styles.
* @param array $data Full block data set.
* @param array $styles Full styles data set.
*/
public static function get_data_and_styles_from_root( $root_id, &$data_n_styles, $data = array(), $styles = array() ) {
if ( ! isset( $data[ $root_id ] ) ) {
return;
}
$block = $data[ $root_id ];
$data_n_styles['blocks'][ $root_id ] = $block;
// Add styles for this block
if ( ! empty( $block['styleIds'] ) ) {
foreach ( $block['styleIds'] as $style_id ) {
if ( isset( $styles[ $style_id ] ) ) {
$data_n_styles['styles'][ $style_id ] = $styles[ $style_id ];
}
}
}
// Traverse contents for text-based blocks
if ( isset( $block['name'] ) && in_array( $block['name'], array( 'paragraph', 'heading', 'text' ), true ) ) {
if ( ! empty( $block['properties']['contents'] ) && is_array( $block['properties']['contents'] ) ) {
foreach ( $block['properties']['contents'] as $content ) {
if ( is_array( $content ) && isset( $content['id'] ) ) {
self::get_data_and_styles_from_root( $content['id'], $data_n_styles, $data, $styles );
}
}
}
}
// Traverse children
if ( ! empty( $block['children'] ) ) {
foreach ( $block['children'] as $child_id ) {
self::get_data_and_styles_from_root( $child_id, $data_n_styles, $data, $styles );
}
}
}
}