PHP error after upgrade to 6.2.1: Uncaught ValueError: DOMDocument::loadHTML()
-
Hi Héctor, thanks for making this great plugin available. I hope you can help with the below.
After upgrading from 6.1.4 to 6.2.1, the shortcode caused a white screen and the following error:
An error of type E_ERROR was caused in line 166 of the file /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Output.php. Error message: Uncaught ValueError: DOMDocument::loadHTML(): Argument #1 ($source) must not be empty in /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Output.php:166 Stack trace: #0 /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Output.php(166): DOMDocument->loadHTML('', 8292) #1 /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Front/Front.php(475): WordPressPopularPosts\Output->get_output() #2 /path/to/site/wp-includes/shortcodes.php(355): WordPressPopularPosts\Front\Front->wpp_shortcode(Array, '', 'wpp') #3 [internal function]: do_shortcode_tag(Array) #4 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(wpp|vc...', 'do_shortcode_ta...', '\n
Here’s my shortcode:
[wpp wpp_start='<ul class="wpp-grid">' post_html='<li>{thumb}{title}</li>' header='My header text' header_start='<h3 class="popular">' header_end='</h3>' range="last30days" post_type='post,page,my-CPT' excerpt_format=1 stats_views=0 thumbnail_width=350 thumbnail_height=350]</ul>
I’ve experimented, starting with the basic shortcode and gradually adding the parameters, but that didn’t help.
The error message mentions DOM, and after finding other posts in here that dealt with that, I checked to see if DOM was installed on the server (using phpinfo) and it is.
So I don’t know. Hopefully the solution will be clear to you ??
Thanks in advance!
Paul
-
Hi @inselaeffchen,
Thanks for the report, I’m already looking into it. I might need your help to test the fix, if so I’ll make sure to leave a comment below with detailed instructions.
Alright, please try following these instructions and report back your results:
#1 Go to Plugins > Plugin File Editor and select WordPress Popular Posts using the dropdown at the top right of your screen.
#2 Click on src > Output.php to edit this file.
#3 Find this block of code (should be around lines 158 to 166) and replace it with this one:
// Process special characters $html = htmlspecialchars_decode(mb_encode_numericentity(htmlentities(trim($this->output), ENT_QUOTES, 'UTF-8'), [0x80, 0x10FFFF, 0, ~0], 'UTF-8')); // Remove empty tags $clean_html = ''; $html = '<!DOCTYPE html><html><head><meta charset="UTF-8" /></head><body>' . $html . '</body></html>'; $dom = new \DOMDocument(); $dom->loadHTML($html, LIBXML_NOERROR | LIBXML_NOWARNING | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
The end result should look something like this:
/** * Return the HTML. * * @since 4.0.0 * @return string */ public function get_output() { $this->output = ( WP_DEBUG ? "\n" . '<!-- WordPress Popular Posts v' . WPP_VERSION . ( $this->admin_options['tools']['cache']['active'] ? ' - cached' : '' ) . ' -->' . "\n" : '' ) . $this->output; // Attempt to close open tags $this->output = force_balance_tags($this->output); // Process special characters $html = htmlspecialchars_decode(mb_encode_numericentity(htmlentities(trim($this->output), ENT_QUOTES, 'UTF-8'), [0x80, 0x10FFFF, 0, ~0], 'UTF-8')); // Remove empty tags $clean_html = ''; $html = '<!DOCTYPE html><html><head><meta charset="UTF-8" /></head><body>' . $html . '</body></html>'; $dom = new \DOMDocument(); $dom->loadHTML($html, LIBXML_NOERROR | LIBXML_NOWARNING | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $xpath = new \DOMXPath($dom); while ( ($node_list = $xpath->query('//*[not(*) and not(@*) and not(text()[normalize-space()])]')) && $node_list->length ) { foreach ($node_list as $node) { $node->parentNode->removeChild($node); } } $body = $dom->getElementsByTagName('body')->item(0); foreach( $body->childNodes as $node ) { $clean_html .= $dom->saveHTML($node); } $this->output = trim($clean_html); // Sanitize HTML $allowed_tags = wp_kses_allowed_html('post'); if ( isset($allowed_tags['form']) ) { unset($allowed_tags['form']); } if ( isset($this->public_options['theme']['name']) && $this->public_options['theme']['name'] ) { $allowed_tags['style'] = [ 'id' => 1, 'nonce' => 1, ]; } $allowed_tags['img']['decoding'] = true; $allowed_tags['img']['srcset'] = true; $this->output = wp_kses($this->output, $allowed_tags); return $this->output; }
#4 Click on the Update File button (botton left of your screen) to save changes.
If everything went well your popular posts list should load normally now.
Thanks for looking at this so quickly. Nope, still causing a critical error. I’ve tried it a few times, as something confused me. Part of the highlighted code to replace includes this:
// Attempt to close open tags $this->output = force_balance_tags($this->output);
That bit isn’t in the replacement, but it IS in the “end result” bit. I’ve tried with and without that bit, but both cause the error.
I’ve cleared the WP cache and browser cache after saving in each case.
Hope that (sort of) helps? Thanks in advance.
That’s odd. Alright, please try replacing the contents of Output.php with this version and save changes, then report back if you’re still getting errors (and make sure to include the details so I can see what’s going on).
Great, thanks. Quite a big error message this time! I’ve anonymised the site details, but a lot of them seem to relate to the theme:
Fatal error: Uncaught Error: Call to undefined function WordPressPopularPosts\mb_encode_numericentity() in /Fatal error: Uncaught Error: Call to undefined function WordPressPopularPosts\mb_encode_numericentity() in /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Output.php:162 Stack trace: #0 /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Front/Front.php(475): WordPressPopularPosts\Output->get_output() #1 /path/to/site/wp-includes/shortcodes.php(355): WordPressPopularPosts\Front\Front->wpp_shortcode(Array, '', 'wpp') #2 [internal function]: do_shortcode_tag(Array) #3 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(sharif...', 'do_shortcode_ta...', '\n<div class="bo...') #4 /path/to/site/wp-includes/class-wp-hook.php(308): do_shortcode('\n<div class="bo...') #5 /path/to/site/wp-includes/plugin.php(205): WP_Hook->apply_filters('\n<div class="bo...', Array) #6 /path/to/site/wp-content/plugins/total-theme-core/inc/vcex/templates/vcex_post_content.php(142): apply_filters('the_content', '<!-- wp:block {...') #7 /path/to/site/wp-content/plugins/total-theme-core/inc/vcex/shortcode-abstract.php(139): include('/home/xxxxxdo/...') #8 /path/to/site/wp-includes/shortcodes.php(355): TotalThemeCore\Vcex\Shortcode_Abstract::output(Array, '', 'vcex_post_conte...') #9 [internal function]: do_shortcode_tag(Array) #10 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(vcex_s...', 'do_shortcode_ta...', '[vc_column_text...') #11 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(240): do_shortcode('[vc_column_text...') #12 /path/to/site/wp-content/themes/Total/vc_templates/vc_column.php(94): wpb_js_remove_wpautop('[vc_column_text...') #13 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(271): require('/home/xxxxxdo/...') #14 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(244): WPBakeryShortCode->loadTemplate(Array, '[vc_column_text...') #15 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(366): WPBakeryShortCode->content(Array, '[vc_column_text...') #16 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(1317): WPBakeryShortCode->output('', '[vc_column_text...') #17 /path/to/site/wp-includes/shortcodes.php(355): vc_do_shortcode('', '[vc_column_text...', 'vc_column') #18 [internal function]: do_shortcode_tag(Array) #19 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(vcex_s...', 'do_shortcode_ta...', '[vc_column][vc_...') #20 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(240): do_shortcode('[vc_column][vc_...') #21 /path/to/site/wp-content/themes/Total/vc_templates/vc_row.php(170): wpb_js_remove_wpautop('[vc_column][vc_...') #22 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbapath/to/sitekeryshortcode.php(271): require('/home/xxxxxdo/...') #23 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/vc-row.php(40): WPBakeryShortCode->loadTemplate(Array, '[vc_column][vc_...') #24 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(366): WPBakeryShortCode_Vc_Row->content(Array, '[vc_column][vc_...') #25 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(1317): WPBakeryShortCode->output('', '[vc_column][vc_...') #26 /path/to/site/wp-includes/shortcodes.php(355): vc_do_shortcode('', '[vc_column][vc_...', 'vc_row') #27 [internal function]: do_shortcode_tag(Array) #28 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(vcex_s...', 'do_shortcode_ta...', '[vc_row][vc_col...') #29 /path/to/site/wp-includes/class-wp-hook.php(310): do_shortcode('[vc_row][vc_col...') #30 /path/to/site/wp-includes/plugin.php(205): WP_Hook->apply_filters('[vc_row][vc_col...', Array) #31 /path/to/site/wp-content/themes/Total/inc/functions/frontend/wpex-the-content.php(56): apply_filters('wpex_the_conten...', '[vc_row][vc_col...', '') #32 /path/to/site/wp-content/themes/Total/inc/functions/sanitization-functions.php(212): wpex_the_content('[vc_row][vc_col...') #33 /path/to/site/wp-content/themes/Total/inc/theme-builder/post-template.php(98): wpex_sanitize_template_content('[vc_row][vc_col...') #34 /path/to/site/wp-content/themes/Total/inc/theme-builder/render-template.php(79): TotalTheme\Theme_Builder\Post_Template::render_template('[vc_row][vc_col...') #35 /path/to/site/wp-content/themes/Total/inc/theme-builder/theme-builder.php(96): TotalTheme\Theme_Builder\Render_Template->render() #36 /path/to/site/wp-content/themes/Total/inc/theme-builder/functions.php(18): TotalTheme\Theme_Builder->do_location('single') #37 /path/to/site/wp-content/themes/Total/singular.php(30): wpex_theme_do_location('single') #38 /path/to/site/wp-includes/template-loader.php(106): include('/home/xxxxxdo/...') #39 /path/to/site/wp-blog-header.php(19): require_once('/home/xxxxxdo/...') #40 /path/to/site/index.php(17): require('/home/xxxxxdo/...') #41 {main} thrown in /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Output.php on line 162/wp-content/plugins/wordpress-popular-posts/src/Output.php:162 Stack trace: #0 /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Front/Front.php(475): WordPressPopularPosts\Output->get_output() #1 /path/to/site/wp-includes/shortcodes.php(355): WordPressPopularPosts\Front\Front->wpp_shortcode(Array, '', 'wpp') #2 [internal function]: do_shortcode_tag(Array) #3 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(sharif...', 'do_shortcode_ta...', '\n<div class="bo...') #4 /path/to/site/wp-includes/class-wp-hook.php(308): do_shortcode('\n<div class="bo...') #5 /path/to/site/wp-includes/plugin.php(205): WP_Hook->apply_filters('\n<div class="bo...', Array) #6 /path/to/site/wp-content/plugins/total-theme-core/inc/vcex/templates/vcex_post_content.php(142): apply_filters('the_content', '<!-- wp:block {...') #7 /path/to/site/wp-content/plugins/total-theme-core/inc/vcex/shortcode-abstract.php(139): include('/home/xxxxxdo/...') #8 /path/to/site/wp-includes/shortcodes.php(355): TotalThemeCore\Vcex\Shortcode_Abstract::output(Array, '', 'vcex_post_conte...') #9 [internal function]: do_shortcode_tag(Array) #10 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(vcex_s...', 'do_shortcode_ta...', '[vc_column_text...') #11 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(240): do_shortcode('[vc_column_text...') #12 /path/to/site/wp-content/themes/Total/vc_templates/vc_column.php(94): wpb_js_remove_wpautop('[vc_column_text...') #13 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(271): require('/home/xxxxxdo/...') #14 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(244): WPBakeryShortCode->loadTemplate(Array, '[vc_column_text...') #15 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(366): WPBakeryShortCode->content(Array, '[vc_column_text...') #16 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(1317): WPBakeryShortCode->output('', '[vc_column_text...') #17 /path/to/site/wp-includes/shortcodes.php(355): vc_do_shortcode('', '[vc_column_text...', 'vc_column') #18 [internal function]: do_shortcode_tag(Array) #19 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(vcex_s...', 'do_shortcode_ta...', '[vc_column][vc_...') #20 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(240): do_shortcode('[vc_column][vc_...') #21 /path/to/site/wp-content/themes/Total/vc_templates/vc_row.php(170): wpb_js_remove_wpautop('[vc_column][vc_...') #22 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(271): require('/home/xxxxxdo/...') #23 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/vc-row.php(40): WPBakeryShortCode->loadTemplate(Array, '[vc_column][vc_...') #24 /path/to/site/wp-content/plugins/js_composer/include/classes/shortcodes/core/class-wpbakeryshortcode.php(366): WPBakeryShortCode_Vc_Row->content(Array, '[vc_column][vc_...') #25 /path/to/site/wp-content/plugins/js_composer/include/helpers/helpers.php(1317): WPBakeryShortCode->output('', '[vc_column][vc_...') #26 /path/to/site/wp-includes/shortcodes.php(355): vc_do_shortcode('', '[vc_column][vc_...', 'vc_row') #27 [internal function]: do_shortcode_tag(Array) #28 /path/to/site/wp-includes/shortcodes.php(227): preg_replace_callback('/\\[(\\[?)(vcex_s...', 'do_shortcode_ta...', '[vc_row][vc_col...') #29 /path/to/site/wp-includes/class-wp-hook.php(310): do_shortcode('[vc_row][vc_col...') #30 /path/to/site/wp-includes/plugin.php(205): WP_Hook->apply_filters('[vc_row][vc_col...', Array) #31 /path/to/site/wp-content/themes/Total/inc/functions/frontend/wpex-the-content.php(56): apply_filters('wpex_the_conten...', '[vc_row][vc_col...', '') #32 /path/to/site/wp-content/themes/Total/inc/functions/sanitization-functions.php(212): wpex_the_content('[vc_row][vc_col...') #33 /path/to/site/wp-content/themes/Total/inc/theme-builder/post-template.php(98): wpex_sanitize_template_content('[vc_row][vc_col...') #34 /path/to/site/wp-content/themes/Total/inc/theme-builder/render-template.php(79): TotalTheme\Theme_Builder\Post_Template::render_template('[vc_row][vc_col...') #35 /path/to/site/wp-content/themes/Total/inc/theme-builder/theme-builder.php(96): TotalTheme\Theme_Builder\Render_Template->render() #36 /path/to/site/wp-content/themes/Total/inc/theme-builder/functions.php(18): TotalTheme\Theme_Builder->do_location('single') #37 /path/to/site/wp-content/themes/Total/singular.php(30): wpex_theme_do_location('single') #38 /path/to/site/wp-includes/template-loader.php(106): include('/home/xxxxxdo/...') #39 /path/to/site/wp-blog-header.php(19): require_once('/home/xxxxxdo/...') #40 /path/to/site/index.php(17): require('/home/xxxxxdo/...') #41 {main} thrown in /path/to/site/wp-content/plugins/wordpress-popular-posts/src/Output.php on line 162
Hope this helps? Thanks.
Hmm that’s super strange but yeah it is helpful so thanks!
This should fix that fatal error (which I don’t get on my test site so it’s probably server / PHP configuration related?):
#1 From the code above, find this function call:
mb_encode_numericentity(...)
and prepend a
\
symbol right in front of it, like so:\mb_encode_numericentity(...)
It should look something like this:
$html = htmlspecialchars_decode(\mb_encode_numericentity(htmlentities(trim($this->output), ENT_QUOTES, 'UTF-8'), [0x80, 0x10FFFF, 0, ~0], 'UTF-8'));
#2 Click on Update File to save changes.
#3 Report back your results.
Gave it some more thought and if the above change doesn’t fix that fatal error then it probably means that the PHP mbstring extension isn’t installed / enabled for your site (which AFAIK isn’t enabled by default and I should add a check for this in the code).
If you find that indeed said extension isn’t active on your site (you can check via WP Dashboard > Settings > WordPress Popular Posts > Debug, under PHP extensions) then do any of the following:
- Go to your hosting provider’s control panel, find the PHP settings section and enable the mbstring extension.
- Reach out to your hosting provider and ask them to enable the mbstring extension for you.
- Install the extension yourself via command line, like so for example: sudo apt-get install php-mbstring (the actual command will vary according to the OS installed on your server)
Thanks, and sorry for the formatting of that code earlier. I didn’t notice there were no line breaks in it.
I’ve tried your new code, and that didn’t work. And you’re right, mbstring isn’t installed.
This particular host doesn’t let users change all that much, so I’ll have to ask if they can enable it. Hopefully!
Thanks again for all your efforts on this; it’s appreciated.
Paul
sorry for the formatting of that code earlier. I didn’t notice there were no line breaks in it.
Don’t worry about it, it was still helpful as is.
I’ve tried your new code, and that didn’t work. And you’re right, mbstring isn’t installed.
This particular host doesn’t let users change all that much, so I’ll have to ask if they can enable it. Hopefully!
Fair enough, it seems I was right about the mbstring extension being missing on your site then which is still good news. I just updated the
get_output()
function from Output.php to have it check for the availability of mbstring so please grab the updated version and try it out, it should fix the error message you were seeing earlier.I do still recommend enabling the mbstring extension on your site, not having it on will prevent WordPress Popular Posts from cleaning up the HTML output of your popular posts list (as in, for example, fixing broken HTML tags before rendering the list on screen).
Great stuff; it’s working again now!
I’ll get onto the host about mbstring tomorrow.
Thanks again! (And I’ve already left you a review :-))
Terrific. I’ll make sure to include these changes on the next release (which should be out pretty soon) as there’s a good chance this issue is affecting other people as well and you just happened to be the first one to notice ??
Thanks for your assistance with all this, you 100% helped make WordPress Popular Posts a better plugin!
A pleasure. Thanks and all the best!
Oops, forgot to mark as “solved”.
- The topic ‘PHP error after upgrade to 6.2.1: Uncaught ValueError: DOMDocument::loadHTML()’ is closed to new replies.