Skip to content

4.2.12 regression: close_buffer() at shutdown PHP_INT_MIN flushes other plugins' buffers, breaks Groovy Menu #1149

Description

@mr305fireball

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

  1. 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.
  2. Install Optimole 4.2.12 (or 4.2.13), connect it, and leave image replacement enabled.
  3. Load any front-end page with page caching bypassed.
  4. The Groovy Menu markup (.gm-navbar, .gm-preset-id-* wrapper) is missing from the HTML.
  5. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugThis label could be used to identify issues that are caused by a defect in the product.regressionIssue represents a change in behavior from a previous version that is not intended or desired..

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions