I want to make all input
tags on product and cart page with class qty
have type="number"
and readonly="readonly"
attributes through modifying DOM with PHP.
When I limit it to cart and product page, it "only" makes lazy load plugin and Autoptimize plugin stop working for these 2 pages, while other pages are fine. I can't spot any console errors, on admin pages as well.
When I allow it to run for every page, the following happens:
- There are no errors in console on product and cart page.
- Ajax request for Ajax add to cart plugin breaks.
- I get multiple console errors which break layout of many admin pages, moving and hiding portions of content.
These output buffer modifications feel like hacking with resulting errors / incompatibilities. Could it be because of libxml_use_internal_errors(true);
which hides warnings and doesn't actually fix anything?
Dom loadHTML doesn't work properly on a server
This is what I have in my functions.php:
add_action( 'template_redirect', 'acau_activate_buffer', 99999 );
function acau_activate_buffer() {
// cart and product page only, WooCommerce required for below line to work, remove to reproduce issues without WooCommerce
if ( ! is_cart() && ! is_product() ) return;
ob_start();
}
add_action('shutdown', function() {
// cart and product page only, WooCommerce required for below line to work, remove to reproduce issues without WooCommerce
if ( ! is_cart() && ! is_product() ) return;
$final = '';
// Collect output from all previous buffers.
$levels = ob_get_level();
for ($i = 0; $i < $levels; $i++) {
$final .= ob_get_clean();
}
echo apply_filters('acau_output', $final);
}, -99999);
// Filter final output.
add_filter('acau_output', function($output) {
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML(mb_convert_encoding($output, 'HTML-ENTITIES', 'UTF-8'));
foreach ($dom->getElementsByTagName('input') as $node) {
$classes = explode (' ', $node->getAttribute('class') );
if ( in_array ( 'qty', $classes ) ) {
$node->setAttribute('type', 'number');
$node->setAttribute('readonly', 'readonly');
}
}
$newHtml = $dom->saveHtml();
return $newHtml;
});
I've found a solution to my issue, based on what Roland from nextendweb posted on WordPress support forums. He filed a bug report:
https://bugs.php.net/bug.php?id=76563
What he suggests would be in my case:
instead of:
because it isn't working the same as it should.