diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php index 6e3b8bc39..f959c61f7 100644 --- a/includes/classes/InternalConnections/NetworkSiteConnection.php +++ b/includes/classes/InternalConnections/NetworkSiteConnection.php @@ -87,7 +87,13 @@ public function push( $post_id, $args = array() ) { // Distribute raw HTML when going from Gutenberg enabled to Gutenberg enabled. $remote_using_gutenberg = \Distributor\Utils\is_using_gutenberg( $post ); if ( $using_gutenberg && $remote_using_gutenberg ) { - $new_post_args['post_content'] = $post->post_content; + + // If DOMDocument is not installed, skip parsing the content. + if ( class_exists( 'DOMDocument' ) ) { + $new_post_args['post_content'] = $this->filter_gutenberg_blocks( $post->post_content, $post_id, $original_blog_id, $this->site->blog_id ); + } else { + $new_post_args['post_content'] = $post->post_content; + } } // Handle existing posts. @@ -159,6 +165,128 @@ public function push( $post_id, $args = array() ) { return $new_post_id; } + /** + * Parses and allows filtering on the gutenberg blocks and their attributes + * + * @param string $content post content of the source post + * @param int $source_post_id Post ID on the source site + * @param int $source_blog_id ID of the source blog for the post + * @param int $destination_blog_id ID of the destination site for the post + * + * @return mixed|string + */ + public function filter_gutenberg_blocks( $content, $source_post_id, $source_blog_id, $destination_blog_id ) { + $content = $this->gutenbergCommentsToElements( $content ); + + $dom = new \DOMDocument(); + + $converted_content = function_exists( 'mb_convert_encoding' ) ? mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) : htmlspecialchars_decode( utf8_decode( htmlentities( $content, ENT_COMPAT, 'utf-8', false ) ) ); + + $dom->loadHTML( $converted_content ); + + $body = $dom->getElementsByTagName( 'body' )->item( 0 ); + foreach ( $body->childNodes as $node ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName + if ( 'gutenberg' !== $node->tagName ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName + continue; + } + + $block_name = $node->getAttribute( 'blockname' ); + $block_attributes = json_decode( $node->getAttribute( 'blockattributes' ), true ); + + /** + * Action fired when a sync is being logged. + * + * @since 1.6.0 + * + * @param array $block_attributes Array of block attributes from the comment json + * @param string $block_name The name of the block + * @param int $source_post_id The post ID on the originating site + * @param int $source_blog_id The blog_id of the source site + */ + $block_attributes = apply_filters( 'dt_filter_block_attributes', $block_attributes, $block_name, $source_post_id, $source_blog_id, $destination_blog_id ); + + if ( ! empty( $block_attributes ) ) { + $node->setAttribute( 'blockattributes', wp_json_encode( $block_attributes ) ); + } else { + $node->removeAttribute( 'blockattributes' ); + } + } + + $string = $dom->saveHTML( $dom->getElementsByTagName( 'body' )->item( 0 ) ); + + $string = str_replace( '
', '', $string ); + $string = str_replace( '', '', $string ); + + $string = $this->gutenbergElementsToComments( $string ); + + return $string; + } + + /** + * Converts post content with gutenberg html comments to