Description
Since 4.2.12 (PR #1132, "process page HTML outside PHP's output-buffer display handler"), Groovy Menu's header menu no longer appears on the front end. Rolling back to 4.2.11 fixes it. So does adding add_filter( 'optml_capture_at_shutdown', '__return_false' ); on 4.2.12.
Cause: Groovy Menu's Divi auto-integration starts its own output buffer on init (priority 0). On shutdown (priority 0) it runs ob_get_clean() and inserts the menu HTML after <body>. In 4.2.12, Optml_Manager::close_buffer() is hooked to shutdown at PHP_INT_MIN (inc/manager.php:428) and flushes every buffer above Optimole's own:
while ( ob_get_level() > self::$ob_level ) { if ( ! @ob_end_flush() ) { break; } }
That flushes Groovy Menu's buffer before Groovy's shutdown callback runs. Groovy then gets Optimole's empty buffer, finds no <body>, and the fully generated menu HTML (~40 KB) is thrown away.
Expected: the Groovy Menu is inserted into the page, as it was on 4.2.11.
Actual: the menu markup is missing on every page. Only Groovy Menu's inline JS settings are printed.
Step-by-step reproduction instructions
- Install the Divi theme and Groovy Menu (premium) and enable Groovy Menu's auto-integration for Divi. Assign a menu to the "Groovy menu Primary" location.
- Install Optimole 4.2.12 (or 4.2.13), connect it, and leave image replacement enabled.
- Load any front-end page with page caching bypassed.
- The Groovy Menu markup (
.gm-navbar, .gm-preset-id-* wrapper) is missing from the HTML.
- Roll back to Optimole 4.2.11, or add
add_filter( 'optml_capture_at_shutdown', '__return_false' );, and reload: the menu appears.
Screenshots, screen recording, code snippet or Help Scout ticket
Buffer stack traced on an uncached render (PHP CLI, same page):
- After the template finishes, ob_level=5:
Optml_Manager::handle_buffer_fallback → default output handler (Groovy Menu) → SiteGround_Optimizer\Parser\Parser::run → hefo_callback → wp_finalize_template_enhancement_output_buffer
- At
shutdown priority -1, ob_level=1: only Optml_Manager::handle_buffer_fallback remains
- Groovy's
groovy_menu_final_output filter receives a string of length 0
Same render with optml_capture_at_shutdown → false: Groovy receives the full page (~188 KB) and the menu is inserted.
On a live site the menu disappeared the morning after the auto-update to 4.2.12. It came back after rolling back to 4.2.11.
Possible directions:
- Run the flush/capture later in
shutdown (after default-priority callbacks) instead of at PHP_INT_MIN.
- If other buffers are still open above Optimole's, fall back to the pre-4.2.12 behaviour instead of force-flushing them.
- At minimum, document
optml_capture_at_shutdown as a supported compatibility switch.
Environment info
WordPress 7.1, PHP 8.2.33, Optimole 4.2.12/4.2.13 (last working: 4.2.11), Divi 4.27.7, Groovy Menu 2.6.5, WP Rocket 3.23.x, SiteGround Optimizer 7.8.x, Header and Footer 3.3.6
Is the issue you are reporting a regression
Yes, this is a regression.
Description
Since 4.2.12 (PR #1132, "process page HTML outside PHP's output-buffer display handler"), Groovy Menu's header menu no longer appears on the front end. Rolling back to 4.2.11 fixes it. So does adding
add_filter( 'optml_capture_at_shutdown', '__return_false' );on 4.2.12.Cause: Groovy Menu's Divi auto-integration starts its own output buffer on
init(priority 0). Onshutdown(priority 0) it runsob_get_clean()and inserts the menu HTML after<body>. In 4.2.12,Optml_Manager::close_buffer()is hooked toshutdownatPHP_INT_MIN(inc/manager.php:428) and flushes every buffer above Optimole's own:That flushes Groovy Menu's buffer before Groovy's shutdown callback runs. Groovy then gets Optimole's empty buffer, finds no
<body>, and the fully generated menu HTML (~40 KB) is thrown away.Expected: the Groovy Menu is inserted into the page, as it was on 4.2.11.
Actual: the menu markup is missing on every page. Only Groovy Menu's inline JS settings are printed.
Step-by-step reproduction instructions
.gm-navbar,.gm-preset-id-*wrapper) is missing from the HTML.add_filter( 'optml_capture_at_shutdown', '__return_false' );, and reload: the menu appears.Screenshots, screen recording, code snippet or Help Scout ticket
Buffer stack traced on an uncached render (PHP CLI, same page):
Optml_Manager::handle_buffer_fallback → default output handler (Groovy Menu) → SiteGround_Optimizer\Parser\Parser::run → hefo_callback → wp_finalize_template_enhancement_output_buffer
shutdownpriority -1, ob_level=1: only Optml_Manager::handle_buffer_fallback remainsgroovy_menu_final_outputfilter receives a string of length 0Same render with
optml_capture_at_shutdown→ false: Groovy receives the full page (~188 KB) and the menu is inserted.On a live site the menu disappeared the morning after the auto-update to 4.2.12. It came back after rolling back to 4.2.11.
Possible directions:
shutdown(after default-priority callbacks) instead of at PHP_INT_MIN.optml_capture_at_shutdownas a supported compatibility switch.Environment info
WordPress 7.1, PHP 8.2.33, Optimole 4.2.12/4.2.13 (last working: 4.2.11), Divi 4.27.7, Groovy Menu 2.6.5, WP Rocket 3.23.x, SiteGround Optimizer 7.8.x, Header and Footer 3.3.6
Is the issue you are reporting a regression
Yes, this is a regression.