File "blocks-20250110184737-20250111010006.php"
Full Path: /home/pumpbmko/public_html/wp-content/plugins/gutenberg/lib/compat/wordpress-6.5/blocks-20250110184737-20250111010006.php
File size: 15.29 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Temporary compatibility shims for block APIs present in Gutenberg.
*
* @package gutenberg
*/
/**
* Shim for the `variation_callback` block type argument.
*
* @param array $args The block type arguments.
* @return array The updated block type arguments.
*/
function gutenberg_register_block_type_args_shim( $args ) {
if ( isset( $args['variation_callback'] ) && is_callable( $args['variation_callback'] ) ) {
$args['variations'] = call_user_func( $args['variation_callback'] );
unset( $args['variation_callback'] );
}
return $args;
}
if ( ! method_exists( 'WP_Block_Type', 'get_variations' ) ) {
add_filter( 'register_block_type_args', 'gutenberg_register_block_type_args_shim' );
}
/**
* Registers the metadata block attribute for all block types.
*
* @param array $args Array of arguments for registering a block type.
* @return array $args
*/
function gutenberg_register_metadata_attribute( $args ) {
// Setup attributes if needed.
if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
$args['attributes'] = array();
}
if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) {
$args['attributes']['metadata'] = array(
'type' => 'object',
);
}
return $args;
}
add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' );
// Only process block bindings if they are not processed in core.
if ( ! class_exists( 'WP_Block_Bindings_Registry' ) ) {
/**
* Depending on the block attribute name, replace its value in the HTML based on the value provided.
*
* @param string $block_content Block Content.
* @param string $block_name The name of the block to process.
* @param string $attribute_name The attribute name to replace.
* @param mixed $source_value The value used to replace in the HTML.
* @return string The modified block content.
*/
function gutenberg_block_bindings_replace_html( $block_content, $block_name, string $attribute_name, $source_value ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name );
if ( ! isset( $block_type->attributes[ $attribute_name ]['source'] ) ) {
return $block_content;
}
// Depending on the attribute source, the processing will be different.
switch ( $block_type->attributes[ $attribute_name ]['source'] ) {
case 'html':
case 'rich-text':
$block_reader = new WP_HTML_Tag_Processor( $block_content );
// TODO: Support for CSS selectors whenever they are ready in the HTML API.
// In the meantime, support comma-separated selectors by exploding them into an array.
$selectors = explode( ',', $block_type->attributes[ $attribute_name ]['selector'] );
// Add a bookmark to the first tag to be able to iterate over the selectors.
$block_reader->next_tag();
$block_reader->set_bookmark( 'iterate-selectors' );
// TODO: This shouldn't be needed when the `set_inner_html` function is ready.
// Store the parent tag and its attributes to be able to restore them later in the button.
// The button block has a wrapper while the paragraph and heading blocks don't.
if ( 'core/button' === $block_name ) {
$button_wrapper = $block_reader->get_tag();
$button_wrapper_attribute_names = $block_reader->get_attribute_names_with_prefix( '' );
$button_wrapper_attrs = array();
foreach ( $button_wrapper_attribute_names as $name ) {
$button_wrapper_attrs[ $name ] = $block_reader->get_attribute( $name );
}
}
foreach ( $selectors as $selector ) {
// If the parent tag, or any of its children, matches the selector, replace the HTML.
if ( strcasecmp( $block_reader->get_tag( $selector ), $selector ) === 0 || $block_reader->next_tag(
array(
'tag_name' => $selector,
)
) ) {
$block_reader->release_bookmark( 'iterate-selectors' );
// TODO: Use `set_inner_html` method whenever it's ready in the HTML API.
// Until then, it is hardcoded for the paragraph, heading, and button blocks.
// Store the tag and its attributes to be able to restore them later.
$selector_attribute_names = $block_reader->get_attribute_names_with_prefix( '' );
$selector_attrs = array();
foreach ( $selector_attribute_names as $name ) {
$selector_attrs[ $name ] = $block_reader->get_attribute( $name );
}
$selector_markup = "<$selector>" . wp_kses_post( $source_value ) . "</$selector>";
$amended_content = new WP_HTML_Tag_Processor( $selector_markup );
$amended_content->next_tag();
foreach ( $selector_attrs as $attribute_key => $attribute_value ) {
$amended_content->set_attribute( $attribute_key, $attribute_value );
}
if ( 'core/paragraph' === $block_name || 'core/heading' === $block_name ) {
return $amended_content->get_updated_html();
}
if ( 'core/button' === $block_name ) {
$button_markup = "<$button_wrapper>{$amended_content->get_updated_html()}</$button_wrapper>";
$amended_button = new WP_HTML_Tag_Processor( $button_markup );
$amended_button->next_tag();
foreach ( $button_wrapper_attrs as $attribute_key => $attribute_value ) {
$amended_button->set_attribute( $attribute_key, $attribute_value );
}
return $amended_button->get_updated_html();
}
} else {
$block_reader->seek( 'iterate-selectors' );
}
}
$block_reader->release_bookmark( 'iterate-selectors' );
return $block_content;
case 'attribute':
$amended_content = new WP_HTML_Tag_Processor( $block_content );
if ( ! $amended_content->next_tag(
array(
// TODO: build the query from CSS selector.
'tag_name' => $block_type->attributes[ $attribute_name ]['selector'],
)
) ) {
return $block_content;
}
$amended_content->set_attribute( $block_type->attributes[ $attribute_name ]['attribute'], $source_value );
return $amended_content->get_updated_html();
default:
return $block_content;
}
}
/**
* Process the block bindings attribute.
*
* @param string $block_content Block Content.
* @param array $parsed_block The full block, including name and attributes.
* @param WP_Block $block_instance The block instance.
* @return string Block content with the bind applied.
*/
function gutenberg_process_block_bindings( $block_content, $parsed_block, $block_instance ) {
$supported_block_attrs = array(
'core/paragraph' => array( 'content' ),
'core/heading' => array( 'content' ),
'core/image' => array( 'id', 'url', 'title', 'alt' ),
'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ),
);
// If the block doesn't have the bindings property or isn't one of the supported block types, return.
if (
! isset( $supported_block_attrs[ $block_instance->name ] ) ||
empty( $parsed_block['attrs']['metadata']['bindings'] ) ||
! is_array( $parsed_block['attrs']['metadata']['bindings'] )
) {
return $block_content;
}
/*
* Assuming the following format for the bindings property of the "metadata" attribute:
*
* "bindings": {
* "title": {
* "source": "core/post-meta",
* "args": { "key": "text_custom_field" }
* },
* "url": {
* "source": "core/post-meta",
* "args": { "key": "url_custom_field" }
* }
* }
*/
$modified_block_content = $block_content;
foreach ( $parsed_block['attrs']['metadata']['bindings'] as $attribute_name => $block_binding ) {
// If the attribute is not in the supported list, process next attribute.
if ( ! in_array( $attribute_name, $supported_block_attrs[ $block_instance->name ], true ) ) {
continue;
}
// If no source is provided, or that source is not registered, process next attribute.
if ( ! isset( $block_binding['source'] ) || ! is_string( $block_binding['source'] ) ) {
continue;
}
$block_binding_source = get_block_bindings_source( $block_binding['source'] );
if ( null === $block_binding_source ) {
continue;
}
$source_args = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array();
$source_value = $block_binding_source->get_value( $source_args, $block_instance, $attribute_name );
// If the value is not null, process the HTML based on the block and the attribute.
if ( ! is_null( $source_value ) ) {
$modified_block_content = gutenberg_block_bindings_replace_html( $modified_block_content, $block_instance->name, $attribute_name, $source_value );
}
}
return $modified_block_content;
}
add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 );
}
/**
* Enable the viewStyle block API for core versions < 6.5
*
*/
if ( ! property_exists( 'WP_Block_Type', 'view_style_handles' ) ) {
/**
* Registers viewStyle assets on block type registration (=same moment core would do it).
*
* @param array $settings Array of determined settings for registering a block type.
* @param array $metadata Metadata provided for registering a block type.
* @return array The block type settings
*/
function gutenberg_filter_block_type_metadata_settings_register_view_styles( $settings, $metadata ) {
if ( empty( $metadata['viewStyle'] ) ) {
return $settings;
}
$styles = $metadata['viewStyle'];
$processed_styles = array();
if ( is_array( $styles ) ) {
for ( $index = 0; $index < count( $styles ); $index++ ) {
$result = gutenberg_register_block_view_style_handle(
$metadata,
$index
);
if ( $result ) {
$processed_styles[] = $result;
}
}
} else {
$result = gutenberg_register_block_view_style_handle(
$metadata
);
if ( $result ) {
$processed_styles[] = $result;
}
}
if ( ! empty( $processed_styles ) ) {
$settings['view_style_handles'] = $processed_styles;
}
return $settings;
}
add_filter( 'block_type_metadata_settings', 'gutenberg_filter_block_type_metadata_settings_register_view_styles', 10, 2 );
/**
* Enqueue view styles associated with the block.
*
* @param string $block_content The block content.
* @param array $block The full block, including name and attributes.
* @param WP_Block $instance The block instance.
*/
function gutenberg_filter_render_block_enqueue_view_styles( $block_content, $parsed_block, $block_instance ) {
$block_type = $block_instance->block_type;
if ( ! empty( $block_type->view_style_handles ) ) {
foreach ( $block_type->view_style_handles as $view_style_handle ) {
wp_enqueue_style( $view_style_handle );
}
}
return $block_content;
}
add_filter( 'render_block', 'gutenberg_filter_render_block_enqueue_view_styles', 10, 3 );
/**
* Registers a REST field for block types to provide view styles.
*
* Adds the `view_style_handles` field to block type objects in the REST API, which
* lists the style handles associated with the block's viewStyle key.
*/
function gutenberg_register_view_style_rest_field() {
register_rest_field(
'block-type',
'view_style_handles',
array(
'get_callback' => function ( $item ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $item['name'] );
if ( isset( $block_type->view_style_handles ) ) {
return $block_type->view_style_handles;
}
return array();
},
)
);
}
add_action( 'rest_api_init', 'gutenberg_register_view_style_rest_field' );
/**
* A compat version of `register_block_style_handle()` to use the viewStyle handle.
* Required for core versions < 6.5, since a custom version of generate_block_asset_handle has to be used
* that supports the viewStyle property and correctly creates the handle
*
* @param array $metadata Block metadata.
* @param int $index Optional. Index of the style to register when multiple items passed.
* Default 0.
* @return string|false Style handle provided directly or created through
* style's registration, or false on failure.
*/
function gutenberg_register_block_view_style_handle( $metadata, $index = 0 ) {
$style_handle = $metadata['viewStyle'];
if ( is_array( $style_handle ) ) {
if ( empty( $style_handle[ $index ] ) ) {
return false;
}
$style_handle = $style_handle[ $index ];
}
$style_handle_name = gutenberg_generate_view_style_block_asset_handle( $metadata['name'], $index );
// If the style handle is already registered, skip re-registering.
if ( wp_style_is( $style_handle_name, 'registered' ) ) {
return $style_handle_name;
}
static $wpinc_path_norm = '';
if ( ! $wpinc_path_norm ) {
$wpinc_path_norm = wp_normalize_path( realpath( ABSPATH . WPINC ) );
}
$is_core_block = isset( $metadata['file'] ) && str_starts_with( $metadata['file'], $wpinc_path_norm );
// Skip registering individual styles for each core block when a bundled version provided.
if ( $is_core_block && ! wp_should_load_separate_core_block_assets() ) {
return false;
}
$style_path = remove_block_asset_path_prefix( $style_handle );
$is_style_handle = $style_handle === $style_path;
// Allow only passing style handles for core blocks.
if ( $is_core_block && ! $is_style_handle ) {
return false;
}
// Return the style handle unless it's the first item for every core block that requires special treatment.
if ( $is_style_handle && ! ( $is_core_block && 0 === $index ) ) {
return $style_handle;
}
// Check whether styles should have a ".min" suffix or not.
$suffix = SCRIPT_DEBUG ? '' : '.min';
if ( $is_core_block ) {
$style_path = "view{$suffix}.css"; // Use view.css for viewStyle of core blocks
}
$style_path_norm = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $style_path ) );
$style_uri = get_block_asset_url( $style_path_norm );
$version = ! $is_core_block && isset( $metadata['version'] ) ? $metadata['version'] : false;
$result = wp_register_style(
$style_handle_name,
$style_uri,
array(),
$version
);
if ( ! $result ) {
return false;
}
if ( $style_uri ) {
wp_style_add_data( $style_handle_name, 'path', $style_path_norm );
if ( $is_core_block ) {
$rtl_file = str_replace( "{$suffix}.css", "-rtl{$suffix}.css", $style_path_norm );
} else {
$rtl_file = str_replace( '.css', '-rtl.css', $style_path_norm );
}
if ( is_rtl() && file_exists( $rtl_file ) ) {
wp_style_add_data( $style_handle_name, 'rtl', 'replace' );
wp_style_add_data( $style_handle_name, 'suffix', $suffix );
wp_style_add_data( $style_handle_name, 'path', $rtl_file );
}
}
return $style_handle_name;
}
/**
* A compat version of `generate_block_asset_handle()` to use the viewStyle asset handle.
*
* @param string $block_name Name of the block.
* @param string $field_name Name of the metadata field.
* @param int $index Optional. Index of the asset when multiple items passed.
* Default 0.
* @return string Generated asset name for the block's field.
*/
function gutenberg_generate_view_style_block_asset_handle( $block_name, $index = 0 ) {
if ( str_starts_with( $block_name, 'core/' ) ) {
$asset_handle = str_replace( 'core/', 'wp-block-', $block_name );
$asset_handle .= '-view';
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}
$asset_handle = str_replace( '/', '-', $block_name ) . '-view-style';
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}
}