Fix Groovy Menu markup missing since the shutdown capture (4.2.12) - #1150
Merged
Merged
Conversation
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>
Collaborator
pirate-bot
approved these changes
Sep 17, 2026
Collaborator
There was a problem hiding this comment.
🟢 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-basecheckout 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
shutdownpriority 0 at plugin load, beforeafter_setup_theme, soshould_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
Collaborator
|
🎉 This PR is included in version 4.2.14 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_outputfilter 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_htmlfilter 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 atshutdownpriority 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 3QA
Install Divi and Groovy Menu (premium). Go to
WP Admin → Groovy Menu → Integrationand turn on auto-integration for the theme. Go toWP Admin → Appearance → Menus → Manage Locationsand assign a menu to Groovy menu Primary.Expect: on Optimole 4.2.13 the front end has no
.gm-navbarelement.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-navbarelement is present once, and its images use the Optimole CDN domain.Add the legacy switch to an mu-plugin and reload the same page:
Expect: the
.gm-navbarelement is still present once.Related: #1149