Skip to content

Fix Groovy Menu markup missing since the shutdown capture (4.2.12) - #1150

Merged
pirate-bot merged 1 commit into
developmentfrom
fix/groovy-menu-buffer
Sep 18, 2026
Merged

pirate-bot merged 1 commit into
developmentfrom
fix/groovy-menu-buffer

Conversation

@selul

@selul selul commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Groovy Menu's header markup disappears from the front end on Optimole 4.2.12 and 4.2.13. Optimole now inserts the menu into the page it captures at shutdown, so the menu shows and its images get optimized.

Note

The bug was added in d6cc7b5 on version 4.2.12.

Reported in #1149 and in HelpScout conversation 3451076687.

What changed

  • Groovy Menu compatibility (new) — loads when Groovy Menu's auto-integration hooked its shutdown step. It applies the groovy_menu_final_output filter to the captured page before image replacement, and unhooks Groovy Menu's own shutdown callback at that moment. Before → the menu markup was dropped. After → the menu is inserted and its logo is served from the CDN.

  • Manager — new optml_captured_page_html filter runs once per request on the page captured at shutdown, outside PHP's display-handler context. Late output re-captured at the end of shutdown is not filtered.

Note

Groovy Menu's auto-integration calls ob_get_clean() on whichever buffer is on top at shutdown priority 0. Since 4.2.12 that buffer is our empty re-armed one, so it finds no <body>. The compatibility takes over only when our capture runs. In legacy mode (optml_capture_at_shutdown → false) and when third-party code flushes our buffer early, Groovy Menu keeps its own shutdown step, as before.

Menu insertion at shutdown

flowchart LR
    A["shutdown PHP_INT_MIN:<br/>close_buffer()"] --> B{"Changed:<br/>capture ran?"}:::changed
    B -- yes --> C["New:<br/>optml_captured_page_html"]:::added
    C --> D["New:<br/>Groovy Menu inserts menu,<br/>own shutdown step unhooked"]:::added
    D --> E["replace_content()"] --> F["Page with menu,<br/>images optimized"]
    B -- no --> G["shutdown 0:<br/>Groovy Menu ob_get_clean()"] --> H["Page with menu"]

    classDef added fill:#1a7f37,color:#fff,stroke:#116329,stroke-width:3px
    classDef changed fill:#9a6700,color:#fff,stroke:#5c3d00,stroke-width:3px,stroke-dasharray:6 3
Loading

QA

  1. Install Divi and Groovy Menu (premium). Go to WP Admin → Groovy Menu → Integration and turn on auto-integration for the theme. Go to WP Admin → Appearance → Menus → Manage Locations and assign a menu to Groovy menu Primary.

    Expect: on Optimole 4.2.13 the front end has no .gm-navbar element.

  2. Install this branch, connect Optimole, and keep Image replacement on at WP Admin → Media → Optimole → Settings → General. Load any front-end page with page caching bypassed and view the source.

    Expect: the .gm-navbar element is present once, and its images use the Optimole CDN domain.

  3. Add the legacy switch to an mu-plugin and reload the same page:

    add_filter( 'optml_capture_at_shutdown', '__return_false' );

    Expect: the .gm-navbar element is still present once.

Related: #1149

Groovy Menu's auto-integration grabs the top output buffer at shutdown
priority 0. Since 4.2.12 our capture at PHP_INT_MIN leaves it an empty
re-armed buffer, so the menu markup was dropped. Apply its final-output
filter to the captured page before image replacement and take over its
shutdown step only when our capture runs.

Fixes #1149

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@pirate-bot

Copy link
Copy Markdown
Collaborator

Plugin build for b16784d is ready 🛎️!

@pirate-bot pirate-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The new compatibility inserts the Groovy Menu markup into the captured page, and the shipped tests fail without the change.

Validation details
  • Files reviewed: 3/3 changed files.
  • vendor/bin/phpunit --filter 'Test_Groovy_Menu::' on HEAD (PHP 8.3.33, WP test lib 7.1.0): OK (5 tests, 20 assertions).
  • The same tests on a pr-base checkout with only the new class copied: 2 failures, Failed asserting that 0 is false.
  • Test_Buffer:: on HEAD: OK (10 tests, 25 assertions).
  • Groovy Menu free 1.4.5 source registers shutdown priority 0 at plugin load, before after_setup_theme, so should_load() sees it.
  • Security pass: no new trust boundary. The filter only lets server-side code change HTML it already emits.
Untested areas
  • Groovy Menu premium source was not available. Hook timing was inferred from the free 1.4.5 plugin.
  • No end-to-end run with Divi and Groovy Menu premium.
  • Full PHPUnit suite, phpcs and phpstan are left to CI.

🤖 Automated review · run code-review-agent_6aabfc1d9719a4.89705420.


🤖 Review agent — review posted ✅ on b16784d5 · approved · 0 findings · 10 min

Run code-review-agent_6aabfc1d9719a4.89705420 · trail

@pirate-bot

Copy link
Copy Markdown
Collaborator

🎉 This PR is included in version 4.2.14 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@pirate-bot pirate-bot added the released Indicate that an issue has been resolved and released in a particular version of the product. label Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released Indicate that an issue has been resolved and released in a particular version of the product.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants