WP_Block_Processor::extract_full_block_and_advancepublicWP 6.9.0

Extracts a block object, and all inner content, starting at a matched opening block delimiter, or at a matched top-level HTML span as freeform HTML content.

Use this function to extract some blocks within a document, but not all. For example, one might want to find image galleries, parse them, modify them, and then reserialize them in place.

Once this function returns, the parser will be matched on token following the close of the given block.

The return type of this method is compatible with the return of \parse_blocks().

Example:

$processor = new WP_Block_Processor( $post_content );
if ( ! $processor->next_block( 'gallery' ) ) {
	return $post_content;
}
$gallery_at  = $processor->get_span()->start;
$gallery     = $processor->extract_full_block_and_advance();
$ends_before = $processor->get_span();
$ends_before = $ends_before->start ?? strlen( $post_content );
$new_gallery = update_gallery( $gallery );
$new_gallery = serialize_block( $new_gallery );
return (
	substr( $post_content, 0, $gallery_at ) .
	$new_gallery .
	substr( $post_content, $ends_before )
);

Method of the class: WP_Block_Processor{}

No Hooks.

Returns

Array[]|null. Array of block structures.

Usage

$WP_Block_Processor = new WP_Block_Processor();
$WP_Block_Processor->extract_full_block_and_advance(): ?array;

Changelog

Since 6.9.0 Introduced.

WP_Block_Processor::extract_full_block_and_advance() code WP 6.9.1

public function extract_full_block_and_advance(): ?array {
	if ( $this->is_html() ) {
		$chunk = $this->get_html_content();

		return array(
			'blockName'    => null,
			'attrs'        => array(),
			'innerBlocks'  => array(),
			'innerHTML'    => $chunk,
			'innerContent' => array( $chunk ),
		);
	}

	$block = array(
		'blockName'    => $this->get_block_type(),
		'attrs'        => $this->allocate_and_return_parsed_attributes() ?? array(),
		'innerBlocks'  => array(),
		'innerHTML'    => '',
		'innerContent' => array(),
	);

	$depth = $this->get_depth();
	while ( $this->next_token() && $this->get_depth() > $depth ) {
		if ( $this->is_html() ) {
			$chunk                   = $this->get_html_content();
			$block['innerHTML']     .= $chunk;
			$block['innerContent'][] = $chunk;
			continue;
		}

		/**
		 * Inner blocks.
		 *
		 * @todo This is a decent place to call {@link \render_block()}
		 * @todo Use iteration instead of recursion, or at least refactor to tail-call form.
		 */
		if ( $this->opens_block() ) {
			$inner_block             = $this->extract_full_block_and_advance();
			$block['innerBlocks'][]  = $inner_block;
			$block['innerContent'][] = null;
		}

		/*
		 * Because the parser has advanced past the closing block token, it
		 * may be matched on an HTML span. This needs to be processed before
		 * moving on to the next token at the start of the next loop iteration.
		 */
		if ( $this->is_html() ) {
			$chunk                   = $this->get_html_content();
			$block['innerHTML']     .= $chunk;
			$block['innerContent'][] = $chunk;
		}
	}

	return $block;
}