<?php
namespace Elementor\Modules\GlobalClasses\Utils;
use Elementor\Core\Utils\Template_Library_Element_Iterator;
use Elementor\Core\Utils\Template_Library_Import_Export_Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Template_Library_Global_Classes_Element_Transformer {
public static function rewrite_elements_classes_ids( array $elements, array $id_map ): array {
if ( empty( $elements ) || empty( $id_map ) ) {
return $elements;
}
return Template_Library_Element_Iterator::iterate(
$elements,
function ( $element_data ) use ( $id_map ) {
$class_values = $element_data['settings']['classes']['value'] ?? null;
if ( ! is_array( $class_values ) ) {
return $element_data;
}
$element_data['settings']['classes']['value'] = self::map_class_values( $class_values, $id_map );
return $element_data;
}
);
}
public static function flatten_elements_classes( array $elements, array $global_classes, ?array $only_ids = null ): array {
$items = $global_classes['items'] ?? [];
if ( empty( $elements ) || empty( $items ) ) {
return $elements;
}
$ids_to_flatten = null !== $only_ids ? array_fill_keys( $only_ids, true ) : null;
return Template_Library_Element_Iterator::iterate(
$elements,
function ( $element_data ) use ( $items, $ids_to_flatten ) {
$class_values = $element_data['settings']['classes']['value'] ?? null;
if ( ! is_array( $class_values ) || empty( $class_values ) ) {
return $element_data;
}
[ $updated_values, $element_styles ] = self::flatten_class_values( $class_values, $element_data, $items, $ids_to_flatten );
$element_data['settings']['classes']['value'] = array_values( array_unique( $updated_values ) );
$element_data['styles'] = $element_styles;
return $element_data;
}
);
}
private static function map_class_values( array $class_values, array $id_map ): array {
$updated_values = [];
foreach ( $class_values as $class_id ) {
if ( ! is_string( $class_id ) || '' === $class_id ) {
continue;
}
$updated_values[] = $id_map[ $class_id ] ?? $class_id;
}
return array_values( array_unique( $updated_values ) );
}
private static function flatten_class_values( array $class_values, array $element_data, array $items, ?array $ids_to_flatten ): array {
$updated_values = [];
$element_styles = $element_data['styles'] ?? [];
$local_style_id = self::find_existing_local_style_id( $element_styles );
$local_style_used = false;
foreach ( $class_values as $class_id ) {
if ( ! is_string( $class_id ) || '' === $class_id ) {
continue;
}
if ( self::should_flatten_class_id( $class_id, $items, $ids_to_flatten ) ) {
$incoming_variants = $items[ $class_id ]['variants'] ?? [];
if ( null === $local_style_id ) {
$local_style_id = self::create_local_class_id( $element_data );
$element_styles[ $local_style_id ] = self::build_local_class_style( $local_style_id, [] );
}
$element_styles[ $local_style_id ]['variants'] = array_merge(
$element_styles[ $local_style_id ]['variants'],
$incoming_variants
);
if ( ! $local_style_used ) {
$updated_values[] = $local_style_id;
$local_style_used = true;
}
continue;
}
$is_global = self::is_global_class_id( $class_id );
if ( ! $is_global || ( null !== $ids_to_flatten && isset( $items[ $class_id ] ) ) ) {
$updated_values[] = $class_id;
}
}
return [ $updated_values, $element_styles ];
}
private static function find_existing_local_style_id( array $element_styles ): ?string {
foreach ( $element_styles as $style_id => $style ) {
if ( isset( $style['label'] ) && Template_Library_Import_Export_Utils::LOCAL_CLASS_LABEL === $style['label'] ) {
return $style_id;
}
}
return null;
}
private static function is_global_class_id( string $class_id ): bool {
return str_starts_with( $class_id, Template_Library_Import_Export_Utils::GLOBAL_CLASS_ID_PREFIX );
}
private static function should_flatten_class_id( string $class_id, array $items, ?array $ids_to_flatten ): bool {
if ( ! isset( $items[ $class_id ] ) ) {
return false;
}
if ( null !== $ids_to_flatten && ! isset( $ids_to_flatten[ $class_id ] ) ) {
return false;
}
return true;
}
private static function create_local_class_id( array $element_data ): string {
return Template_Library_Import_Export_Utils::LOCAL_CLASS_ID_PREFIX
. substr( $element_data['id'] ?? '', 0, 8 )
. '-'
. Template_Library_Import_Export_Utils::generate_random_string();
}
private static function build_local_class_style( string $local_id, array $variants ): array {
return [
'id' => $local_id,
'label' => Template_Library_Import_Export_Utils::LOCAL_CLASS_LABEL,
'type' => 'class',
'variants' => $variants,
];
}
}