,
and tags, instead of the HTML * that belongs within a tag. */ public function __construct( $content, $flags = false, $is_html_document = false ) { if ( $is_html_document ) { // The content is a full HTML document. Add the UTF-8 Content-Type meta tag to its // , instead of wrapping the document in another document, which would result // in the document's elements being output within its . $content = $this->add_content_type_meta_tag( $content ); } else { // Wrap content in , and tags with an UTF-8 Content-Type meta tag. // Forcibly tell DOMDocument that this HTML uses the UTF-8 charset. // isn't enough, as DOMDocument still interprets the HTML as ISO-8859, which breaks character encoding // Use of mb_convert_encoding() with HTML-ENTITIES is deprecated in PHP 8.2, so we have to use this method. // If we don't, special characters render incorrectly. $content = '' . $content . ''; } // Load the HTML into a DOMDocument. libxml_use_internal_errors( true ); $this->html = new DOMDocument(); if ( $flags ) { $this->html->loadHTML( $content, $flags ); } else { $this->html->loadHTML( $content ); } // Load DOMDocument into XPath. $this->xpath = new DOMXPath( $this->html ); } /** * Adds a UTF-8 Content-Type meta tag to the given HTML document's . * * DOMDocument doesn't honor a document's tag, interpreting the * HTML as ISO-8859 and therefore rendering special characters incorrectly. Use of * mb_convert_encoding() with HTML-ENTITIES is deprecated in PHP 8.2, so we have to * use this method. * * @since 3.4.1 * * @param string $content HTML document. * @return string HTML document, with a UTF-8 Content-Type meta tag. */ private function add_content_type_meta_tag( $content ) { $meta_tag = ''; // Add the meta tag immediately after the opening tag. $html = preg_replace( '/]*)?>/i', '$0' . $meta_tag, $content, 1, $count ); if ( $count ) { return (string) $html; } // No tag exists; add one immediately after the opening tag. $html = preg_replace( '/]*)?>/i', '$0' . $meta_tag . '', $content, 1, $count ); if ( $count ) { return (string) $html; } // Neither a or tag exists; prepend the meta tag in its own tag. return '' . $meta_tag . '' . $content; } /** * Returns the HTML within the DOMDocument's tag as a string. * * @since 3.0.0 * * @return string */ public function get_body_html() { $body = $this->html->getElementsByTagName( 'body' )->item( 0 ); $html = ''; foreach ( $body->childNodes as $child ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase $html .= $this->html->saveHTML( $child ); } return $html; } }