|
<?php |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_create_block_style_variation_instance_name( $block, $variation ) { |
|
return $variation . '--' . md5( serialize( $block ) ); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_get_block_style_variation_name_from_class( $class_string ) { |
|
if ( ! is_string( $class_string ) ) { |
|
return null; |
|
} |
|
|
|
preg_match_all( '/\bis-style-(?!default)(\S+)\b/', $class_string, $matches ); |
|
return $matches[1] ?? null; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_resolve_block_style_variation_ref_values( &$variation_data, $theme_json ) { |
|
foreach ( $variation_data as $key => &$value ) { |
|
|
|
if ( is_array( $value ) ) { |
|
|
|
if ( array_key_exists( 'ref', $value ) ) { |
|
|
|
if ( empty( $value['ref'] ) || ! is_string( $value['ref'] ) ) { |
|
unset( $variation_data[ $key ] ); |
|
} |
|
|
|
$value_path = explode( '.', $value['ref'] ?? '' ); |
|
$ref_value = _wp_array_get( $theme_json, $value_path ); |
|
|
|
|
|
if ( null === $ref_value ) { |
|
unset( $variation_data[ $key ] ); |
|
} else { |
|
$value = $ref_value; |
|
} |
|
} else { |
|
|
|
wp_resolve_block_style_variation_ref_values( $value, $theme_json ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_render_block_style_variation_support_styles( $parsed_block ) { |
|
$classes = $parsed_block['attrs']['className'] ?? null; |
|
$variations = wp_get_block_style_variation_name_from_class( $classes ); |
|
|
|
if ( ! $variations ) { |
|
return $parsed_block; |
|
} |
|
|
|
$tree = WP_Theme_JSON_Resolver::get_merged_data(); |
|
$theme_json = $tree->get_raw_data(); |
|
|
|
|
|
$variation_data = array(); |
|
foreach ( $variations as $variation ) { |
|
$variation_data = $theme_json['styles']['blocks'][ $parsed_block['blockName'] ]['variations'][ $variation ] ?? array(); |
|
|
|
if ( ! empty( $variation_data ) ) { |
|
break; |
|
} |
|
} |
|
|
|
if ( empty( $variation_data ) ) { |
|
return $parsed_block; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
wp_resolve_block_style_variation_ref_values( $variation_data, $theme_json ); |
|
|
|
$variation_instance = wp_create_block_style_variation_instance_name( $parsed_block, $variation ); |
|
$class_name = "is-style-$variation_instance"; |
|
$updated_class_name = $parsed_block['attrs']['className'] . " $class_name"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$elements_data = $variation_data['elements'] ?? array(); |
|
$blocks_data = $variation_data['blocks'] ?? array(); |
|
unset( $variation_data['elements'] ); |
|
unset( $variation_data['blocks'] ); |
|
|
|
_wp_array_set( |
|
$blocks_data, |
|
array( $parsed_block['blockName'], 'variations', $variation_instance ), |
|
$variation_data |
|
); |
|
|
|
$config = array( |
|
'version' => WP_Theme_JSON::LATEST_SCHEMA, |
|
'styles' => array( |
|
'elements' => $elements_data, |
|
'blocks' => $blocks_data, |
|
), |
|
); |
|
|
|
|
|
if ( ! is_admin() ) { |
|
remove_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); |
|
} |
|
|
|
|
|
$styles_registry = WP_Block_Styles_Registry::get_instance(); |
|
$styles_registry->register( $parsed_block['blockName'], array( 'name' => $variation_instance ) ); |
|
|
|
$variation_theme_json = new WP_Theme_JSON( $config, 'blocks' ); |
|
$variation_styles = $variation_theme_json->get_stylesheet( |
|
array( 'styles' ), |
|
array( 'custom' ), |
|
array( |
|
'include_block_style_variations' => true, |
|
'skip_root_layout_styles' => true, |
|
'scope' => ".$class_name", |
|
) |
|
); |
|
|
|
|
|
$styles_registry->unregister( $parsed_block['blockName'], $variation_instance ); |
|
|
|
|
|
if ( ! is_admin() ) { |
|
add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); |
|
} |
|
|
|
if ( empty( $variation_styles ) ) { |
|
return $parsed_block; |
|
} |
|
|
|
wp_register_style( 'block-style-variation-styles', false, array( 'global-styles', 'wp-block-library' ) ); |
|
wp_add_inline_style( 'block-style-variation-styles', $variation_styles ); |
|
|
|
|
|
|
|
|
|
|
|
_wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); |
|
|
|
return $parsed_block; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_render_block_style_variation_class_name( $block_content, $block ) { |
|
if ( ! $block_content || empty( $block['attrs']['className'] ) ) { |
|
return $block_content; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
preg_match( '/\bis-style-(\S+?--\w+)\b/', $block['attrs']['className'], $matches ); |
|
|
|
if ( empty( $matches ) ) { |
|
return $block_content; |
|
} |
|
|
|
$tags = new WP_HTML_Tag_Processor( $block_content ); |
|
|
|
if ( $tags->next_tag() ) { |
|
|
|
|
|
|
|
|
|
|
|
$tags->add_class( $matches[0] ); |
|
} |
|
|
|
return $tags->get_updated_html(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_enqueue_block_style_variation_styles() { |
|
wp_enqueue_style( 'block-style-variation-styles' ); |
|
} |
|
|
|
|
|
WP_Block_Supports::get_instance()->register( 'block-style-variation', array() ); |
|
|
|
add_filter( 'render_block_data', 'wp_render_block_style_variation_support_styles', 10, 2 ); |
|
add_filter( 'render_block', 'wp_render_block_style_variation_class_name', 10, 2 ); |
|
add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles', 1 ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function wp_register_block_style_variations_from_theme_json_partials( $variations ) { |
|
if ( empty( $variations ) ) { |
|
return; |
|
} |
|
|
|
$registry = WP_Block_Styles_Registry::get_instance(); |
|
|
|
foreach ( $variations as $variation ) { |
|
if ( empty( $variation['blockTypes'] ) || empty( $variation['styles'] ) ) { |
|
continue; |
|
} |
|
|
|
$variation_name = $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ); |
|
$variation_label = $variation['title'] ?? $variation_name; |
|
|
|
foreach ( $variation['blockTypes'] as $block_type ) { |
|
$registered_styles = $registry->get_registered_styles_for_block( $block_type ); |
|
|
|
|
|
if ( ! array_key_exists( $variation_name, $registered_styles ) ) { |
|
register_block_style( |
|
$block_type, |
|
array( |
|
'name' => $variation_name, |
|
'label' => $variation_label, |
|
) |
|
); |
|
} |
|
} |
|
} |
|
} |
|
|