wp core update 6.6

This commit is contained in:
Tony Volpe
2024-07-17 03:05:30 +00:00
parent 8f93917880
commit 4950d23a30
912 changed files with 103325 additions and 124480 deletions

View File

@@ -858,11 +858,11 @@ function get_hooked_blocks() {
* @since 6.5.0
* @access private
*
* @param array $parsed_anchor_block The anchor block, in parsed block array format.
* @param string $relative_position The relative position of the hooked blocks.
* Can be one of 'before', 'after', 'first_child', or 'last_child'.
* @param array $hooked_blocks An array of hooked block types, grouped by anchor block and relative position.
* @param WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to.
* @param array $parsed_anchor_block The anchor block, in parsed block array format.
* @param string $relative_position The relative position of the hooked blocks.
* Can be one of 'before', 'after', 'first_child', or 'last_child'.
* @param array $hooked_blocks An array of hooked block types, grouped by anchor block and relative position.
* @param WP_Block_Template|WP_Post|array $context The block template, template part, or pattern that the anchor block belongs to.
* @return string
*/
function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooked_blocks, $context ) {
@@ -949,12 +949,12 @@ function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooke
* @since 6.5.0
* @access private
*
* @param array $parsed_anchor_block The anchor block, in parsed block array format.
* @param string $relative_position The relative position of the hooked blocks.
* Can be one of 'before', 'after', 'first_child', or 'last_child'.
* @param array $hooked_blocks An array of hooked block types, grouped by anchor block and relative position.
* @param WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to.
* @return string An empty string.
* @param array $parsed_anchor_block The anchor block, in parsed block array format.
* @param string $relative_position The relative position of the hooked blocks.
* Can be one of 'before', 'after', 'first_child', or 'last_child'.
* @param array $hooked_blocks An array of hooked block types, grouped by anchor block and relative position.
* @param WP_Block_Template|WP_Post|array $context The block template, template part, or pattern that the anchor block belongs to.
* @return string Empty string.
*/
function set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_position, $hooked_blocks, $context ) {
$anchor_block_type = $parsed_anchor_block['blockName'];
@@ -1002,6 +1002,183 @@ function set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_po
return '';
}
/**
* Runs the hooked blocks algorithm on the given content.
*
* @since 6.6.0
* @access private
*
* @param string $content Serialized content.
* @param WP_Block_Template|WP_Post|array $context A block template, template part, `wp_navigation` post object,
* or pattern that the blocks belong to.
* @param callable $callback A function that will be called for each block to generate
* the markup for a given list of blocks that are hooked to it.
* Default: 'insert_hooked_blocks'.
* @return string The serialized markup.
*/
function apply_block_hooks_to_content( $content, $context, $callback = 'insert_hooked_blocks' ) {
$hooked_blocks = get_hooked_blocks();
if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) {
return $content;
}
$blocks = parse_blocks( $content );
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $context, $callback );
$after_block_visitor = make_after_block_visitor( $hooked_blocks, $context, $callback );
return traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
}
/**
* Accepts the serialized markup of a block and its inner blocks, and returns serialized markup of the inner blocks.
*
* @since 6.6.0
* @access private
*
* @param string $serialized_block The serialized markup of a block and its inner blocks.
* @return string The serialized markup of the inner blocks.
*/
function remove_serialized_parent_block( $serialized_block ) {
$start = strpos( $serialized_block, '-->' ) + strlen( '-->' );
$end = strrpos( $serialized_block, '<!--' );
return substr( $serialized_block, $start, $end - $start );
}
/**
* Updates the wp_postmeta with the list of ignored hooked blocks where the inner blocks are stored as post content.
* Currently only supports `wp_navigation` post types.
*
* @since 6.6.0
* @access private
*
* @param stdClass $post Post object.
* @return stdClass The updated post object.
*/
function update_ignored_hooked_blocks_postmeta( $post ) {
/*
* In this scenario the user has likely tried to create a navigation via the REST API.
* In which case we won't have a post ID to work with and store meta against.
*/
if ( empty( $post->ID ) ) {
return $post;
}
/*
* Skip meta generation when consumers intentionally update specific Navigation fields
* and omit the content update.
*/
if ( ! isset( $post->post_content ) ) {
return $post;
}
/*
* Skip meta generation when the post content is not a navigation block.
*/
if ( ! isset( $post->post_type ) || 'wp_navigation' !== $post->post_type ) {
return $post;
}
$attributes = array();
$ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
if ( ! empty( $ignored_hooked_blocks ) ) {
$ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
$attributes['metadata'] = array(
'ignoredHookedBlocks' => $ignored_hooked_blocks,
);
}
$markup = get_comment_delimited_block_content(
'core/navigation',
$attributes,
$post->post_content
);
$serialized_block = apply_block_hooks_to_content( $markup, get_post( $post->ID ), 'set_ignored_hooked_blocks_metadata' );
$root_block = parse_blocks( $serialized_block )[0];
$ignored_hooked_blocks = isset( $root_block['attrs']['metadata']['ignoredHookedBlocks'] )
? $root_block['attrs']['metadata']['ignoredHookedBlocks']
: array();
if ( ! empty( $ignored_hooked_blocks ) ) {
$existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
if ( ! empty( $existing_ignored_hooked_blocks ) ) {
$existing_ignored_hooked_blocks = json_decode( $existing_ignored_hooked_blocks, true );
$ignored_hooked_blocks = array_unique( array_merge( $ignored_hooked_blocks, $existing_ignored_hooked_blocks ) );
}
update_post_meta( $post->ID, '_wp_ignored_hooked_blocks', json_encode( $ignored_hooked_blocks ) );
}
$post->post_content = remove_serialized_parent_block( $serialized_block );
return $post;
}
/**
* Returns the markup for blocks hooked to the given anchor block in a specific relative position and then
* adds a list of hooked block types to an anchor block's ignored hooked block types.
*
* This function is meant for internal use only.
*
* @since 6.6.0
* @access private
*
* @param array $parsed_anchor_block The anchor block, in parsed block array format.
* @param string $relative_position The relative position of the hooked blocks.
* Can be one of 'before', 'after', 'first_child', or 'last_child'.
* @param array $hooked_blocks An array of hooked block types, grouped by anchor block and relative position.
* @param WP_Block_Template|WP_Post|array $context The block template, template part, or pattern that the anchor block belongs to.
* @return string
*/
function insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_position, $hooked_blocks, $context ) {
$markup = insert_hooked_blocks( $parsed_anchor_block, $relative_position, $hooked_blocks, $context );
$markup .= set_ignored_hooked_blocks_metadata( $parsed_anchor_block, $relative_position, $hooked_blocks, $context );
return $markup;
}
/**
* Hooks into the REST API response for the core/navigation block and adds the first and last inner blocks.
*
* @since 6.6.0
*
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
* @return WP_REST_Response The response object.
*/
function insert_hooked_blocks_into_rest_response( $response, $post ) {
if ( ! isset( $response->data['content']['raw'] ) || ! isset( $response->data['content']['rendered'] ) ) {
return $response;
}
$attributes = array();
$ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
if ( ! empty( $ignored_hooked_blocks ) ) {
$ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
$attributes['metadata'] = array(
'ignoredHookedBlocks' => $ignored_hooked_blocks,
);
}
$content = get_comment_delimited_block_content(
'core/navigation',
$attributes,
$response->data['content']['raw']
);
$content = apply_block_hooks_to_content( $content, $post );
// Remove mock Navigation block wrapper.
$content = remove_serialized_parent_block( $content );
$response->data['content']['raw'] = $content;
/** This filter is documented in wp-includes/post-template.php */
$response->data['content']['rendered'] = apply_filters( 'the_content', $content );
return $response;
}
/**
* Returns a function that injects the theme attribute into, and hooked blocks before, a given block.
*
@@ -1201,7 +1378,17 @@ function get_comment_delimited_block_content( $block_name, $block_attributes, $b
*
* @since 5.3.1
*
* @param array $block A representative array of a single parsed block object. See WP_Block_Parser_Block.
* @param array $block {
* A representative array of a single parsed block object. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* @return string String of rendered HTML.
*/
function serialize_block( $block ) {
@@ -1229,7 +1416,21 @@ function serialize_block( $block ) {
*
* @since 5.3.1
*
* @param array[] $blocks An array of representative arrays of parsed block objects. See serialize_block().
* @param array[] $blocks {
* Array of block structures.
*
* @type array ...$0 {
* A representative array of a single parsed block object. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* }
* @return string String of rendered HTML.
*/
function serialize_blocks( $blocks ) {
@@ -1320,6 +1521,83 @@ function traverse_and_serialize_block( $block, $pre_callback = null, $post_callb
);
}
/**
* Replaces patterns in a block tree with their content.
*
* @since 6.6.0
*
* @param array $blocks An array blocks.
*
* @return array An array of blocks with patterns replaced by their content.
*/
function resolve_pattern_blocks( $blocks ) {
static $inner_content;
// Keep track of seen references to avoid infinite loops.
static $seen_refs = array();
$i = 0;
while ( $i < count( $blocks ) ) {
if ( 'core/pattern' === $blocks[ $i ]['blockName'] ) {
$attrs = $blocks[ $i ]['attrs'];
if ( empty( $attrs['slug'] ) ) {
++$i;
continue;
}
$slug = $attrs['slug'];
if ( isset( $seen_refs[ $slug ] ) ) {
// Skip recursive patterns.
array_splice( $blocks, $i, 1 );
continue;
}
$registry = WP_Block_Patterns_Registry::get_instance();
$pattern = $registry->get_registered( $slug );
// Skip unknown patterns.
if ( ! $pattern ) {
++$i;
continue;
}
$blocks_to_insert = parse_blocks( $pattern['content'] );
$seen_refs[ $slug ] = true;
$prev_inner_content = $inner_content;
$inner_content = null;
$blocks_to_insert = resolve_pattern_blocks( $blocks_to_insert );
$inner_content = $prev_inner_content;
unset( $seen_refs[ $slug ] );
array_splice( $blocks, $i, 1, $blocks_to_insert );
// If we have inner content, we need to insert nulls in the
// inner content array, otherwise serialize_blocks will skip
// blocks.
if ( $inner_content ) {
$null_indices = array_keys( $inner_content, null, true );
$content_index = $null_indices[ $i ];
$nulls = array_fill( 0, count( $blocks_to_insert ), null );
array_splice( $inner_content, $content_index, 1, $nulls );
}
// Skip inserted blocks.
$i += count( $blocks_to_insert );
} else {
if ( ! empty( $blocks[ $i ]['innerBlocks'] ) ) {
$prev_inner_content = $inner_content;
$inner_content = $blocks[ $i ]['innerContent'];
$blocks[ $i ]['innerBlocks'] = resolve_pattern_blocks(
$blocks[ $i ]['innerBlocks']
);
$blocks[ $i ]['innerContent'] = $inner_content;
$inner_content = $prev_inner_content;
}
++$i;
}
}
return $blocks;
}
/**
* Given an array of parsed block trees, applies callbacks before and after serializing them and
* returns their concatenated output.
@@ -1483,7 +1761,6 @@ function filter_block_kses_value( $value, $allowed_html, $allowed_protocols = ar
if ( isset( $block_context['blockName'] ) && 'core/template-part' === $block_context['blockName'] ) {
$filtered_value = filter_block_core_template_part_attributes( $filtered_value, $filtered_key, $allowed_html );
}
if ( $filtered_key !== $key ) {
unset( $value[ $key ] );
}
@@ -1502,11 +1779,11 @@ function filter_block_kses_value( $value, $allowed_html, $allowed_protocols = ar
*
* @since 6.5.5
*
* @param string $attribute_value The attribute value to filter.
* @param string $attribute_name The attribute name.
* @param array[]|string $allowed_html An array of allowed HTML elements and attributes,
* or a context name such as 'post'. See wp_kses_allowed_html()
* for the list of accepted context names.
* @param string $attribute_value The attribute value to filter.
* @param string $attribute_name The attribute name.
* @param array[]|string $allowed_html An array of allowed HTML elements and attributes,
* or a context name such as 'post'. See wp_kses_allowed_html()
* for the list of accepted context names.
* @return string The sanitized attribute value.
*/
function filter_block_core_template_part_attributes( $attribute_value, $attribute_name, $allowed_html ) {
@@ -1666,7 +1943,17 @@ function _excerpt_render_inner_blocks( $parsed_block, $allowed_blocks ) {
*
* @global WP_Post $post The post to edit.
*
* @param array $parsed_block A single parsed block object.
* @param array $parsed_block {
* A representative array of the block being rendered. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* @return string String of rendered HTML.
*/
function render_block( $parsed_block ) {
@@ -1680,7 +1967,17 @@ function render_block( $parsed_block ) {
* @since 5.9.0 The `$parent_block` parameter was added.
*
* @param string|null $pre_render The pre-rendered content. Default null.
* @param array $parsed_block The block being rendered.
* @param array $parsed_block {
* A representative array of the block being rendered. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
$pre_render = apply_filters( 'pre_render_block', null, $parsed_block, $parent_block );
@@ -1696,8 +1993,29 @@ function render_block( $parsed_block ) {
* @since 5.1.0
* @since 5.9.0 The `$parent_block` parameter was added.
*
* @param array $parsed_block The block being rendered.
* @param array $source_block An un-modified copy of $parsed_block, as it appeared in the source content.
* @param array $parsed_block {
* A representative array of the block being rendered. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* @param array $source_block {
* An un-modified copy of `$parsed_block`, as it appeared in the source content.
* See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
$parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block, $parent_block );
@@ -1723,7 +2041,17 @@ function render_block( $parsed_block ) {
* @since 5.9.0 The `$parent_block` parameter was added.
*
* @param array $context Default context.
* @param array $parsed_block Block being rendered, filtered by `render_block_data`.
* @param array $parsed_block {
* A representative array of the block being rendered. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
$context = apply_filters( 'render_block_context', $context, $parsed_block, $parent_block );
@@ -1739,7 +2067,21 @@ function render_block( $parsed_block ) {
* @since 5.0.0
*
* @param string $content Post content.
* @return array[] Array of parsed block objects.
* @return array[] {
* Array of block structures.
*
* @type array ...$0 {
* A representative array of a single parsed block object. See WP_Block_Parser_Block.
*
* @type string $blockName Name of block.
* @type array $attrs Attributes from block comment delimiters.
* @type array[] $innerBlocks List of inner blocks. An array of arrays that
* have the same structure as this one.
* @type string $innerHTML HTML from inside block comment delimiters.
* @type array $innerContent List of string fragments and null markers where
* inner blocks were found.
* }
* }
*/
function parse_blocks( $content ) {
/**
@@ -1818,14 +2160,16 @@ function block_version( $content ) {
* Registers a new block style.
*
* @since 5.3.0
* @since 6.6.0 Added support for registering styles for multiple block types.
*
* @link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/
*
* @param string $block_name Block type name including namespace.
* @param array $style_properties Array containing the properties of the style name, label,
* style_handle (name of the stylesheet to be enqueued),
* inline_style (string containing the CSS to be added).
* See WP_Block_Styles_Registry::register().
* @param string|string[] $block_name Block type name including namespace or array of namespaced block type names.
* @param array $style_properties Array containing the properties of the style name, label,
* style_handle (name of the stylesheet to be enqueued),
* inline_style (string containing the CSS to be added),
* style_data (theme.json-like array to generate CSS from).
* See WP_Block_Styles_Registry::register().
* @return bool True if the block style was registered with success and false otherwise.
*/
function register_block_style( $block_name, $style_properties ) {