diff --git a/lib/blocks.php b/lib/blocks.php index d172682f932f7..3cd1ce33daa80 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -110,6 +110,7 @@ function get_dynamic_block_names() { * @return string */ function get_dynamic_blocks_regex() { + _deprecated_function( __FUNCTION__, '4.1.0', __( "Dynamic blocks shouldn't be extracted by regex. Use parse_blocks() instead.", 'gutenberg' ) ); $dynamic_block_names = get_dynamic_block_names(); $dynamic_block_pattern = ( '//'; - if ( ! preg_match( $end_tag_pattern, $content, $block_match_end, PREG_OFFSET_CAPTURE ) ) { - // If no closing tag is found, abort all matching, and continue - // to append remainder of content to rendered output. - break; - } - - // Update content to omit text up to and including closing tag. - $end_tag = $block_match_end[0][0]; - $end_offset = $block_match_end[0][1]; - - $inner_content = substr( $content, 0, $end_offset ); - $content = substr( $content, $end_offset + strlen( $end_tag ) ); - } - - // Replace dynamic block with server-rendered output. - $rendered_content .= $block_type->render( $attributes, $inner_content ); + /** + * Filters the content of a single block. + * + * During the_content, each block is parsed and added to the output individually. This filter allows + * that content to be altered immediately before it's appended. + * + * @since 5.0.0 + * + * @param string $block_content The block content about to be appended. + * @param array $block The full block, including name and attributes. + * @param array $all_blocks The array of all blocks being processed. + */ + $rendered_content .= apply_filters( 'do_block', $block_content, $block, $all_blocks ); // Restore global $post. $post = $global_post; } - // Append remaining unmatched content. - $rendered_content .= $content; - // Strip remaining block comment demarcations. - $rendered_content = preg_replace( '/\r?\n?/m', '', $rendered_content ); + $rendered_content = preg_replace( '//m', '', $rendered_content ); return $rendered_content; } -add_filter( 'the_content', 'do_blocks', 9 ); // BEFORE do_shortcode(). /** * Remove all dynamic blocks from the given content. * - * @since 3.6.0 + * @since 4.1.0 * * @param string $content Content of the current post. * @return string */ function strip_dynamic_blocks( $content ) { - return preg_replace( get_dynamic_blocks_regex(), '', $content ); + return _recurse_strip_dynamic_blocks( gutenberg_parse_blocks( $content ) ); +} + +/** + * Helper function for strip_dynamic_blocks(), to recurse through the block tree. + * + * @since 4.1.0 + * @access private + * + * @param array $blocks Array of blocks from parse_blocks() + * @return string + */ +function _recurse_strip_dynamic_blocks( $blocks ) { + $clean_content = ''; + $dynamic_blocks = get_dynamic_block_names(); + + foreach ( $blocks as $block ) { + if ( ! in_array( $block['blockName'], $dynamic_blocks ) ) { + if ( $block['innerBlocks'] ) { + $clean_content .= _recurse_strip_dynamic_blocks( $block['innerBlocks'] ); + } else { + $clean_content .= $block['innerHTML']; + } + } + } + + return $clean_content; } /** diff --git a/packages/block-serialization-default-parser/parser.php b/packages/block-serialization-default-parser/parser.php index 78b6921787cc4..96f1c3a0e4900 100644 --- a/packages/block-serialization-default-parser/parser.php +++ b/packages/block-serialization-default-parser/parser.php @@ -306,7 +306,14 @@ function proceed() { * block and add it as a new innerBlock to the parent */ $stack_top = array_pop( $this->stack ); - $stack_top->block->innerHTML .= substr( $this->document, $stack_top->prev_offset, $start_offset - $stack_top->prev_offset ); + + $html = substr( $this->document, $stack_top->prev_offset, $start_offset - $stack_top->prev_offset ); + if ( $stack_top->block->innerBlocks ) { + $stack_top->block->innerBlocks[] = (array) $this->freeform( $html ); + } else { + $stack_top->block->innerHTML = $html; + } + $stack_top->prev_offset = $start_offset + $token_length; $this->add_inner_block( @@ -440,8 +447,8 @@ function add_freeform( $length = null ) { */ function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) { $parent = $this->stack[ count( $this->stack ) - 1 ]; - $parent->block->innerBlocks[] = $block; - $parent->block->innerHTML .= substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset ); + $parent->block->innerBlocks[] = (array) $this->freeform( substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset ) ); + $parent->block->innerBlocks[] = (array) $block; $parent->prev_offset = $last_offset ? $last_offset : $token_start + $token_length; } @@ -456,10 +463,16 @@ function add_block_from_stack( $end_offset = null ) { $stack_top = array_pop( $this->stack ); $prev_offset = $stack_top->prev_offset; - $stack_top->block->innerHTML .= isset( $end_offset ) + $html = isset( $end_offset ) ? substr( $this->document, $prev_offset, $end_offset - $prev_offset ) : substr( $this->document, $prev_offset ); + if ( $stack_top->block->innerBlocks ) { + $stack_top->block->innerBlocks[] = (array) $this->freeform( $html ); + } else { + $stack_top->block->innerHTML = $html; + } + if ( isset( $stack_top->leading_html_start ) ) { $this->output[] = (array) self::freeform( substr( $this->document,