# optimole-wp/trunk/inc/compatibilities/groovy_menu.php

Optimole – Optimize Images | Convert WebP &amp; AVIF | CDN &amp; Lazy Load | Image Optimization, version trunk. 69 lines.

- Page: https://pluginprobe.com/plugins/optimole-wp/trunk/code/inc/compatibilities/groovy_menu.php
- Raw: https://pluginprobe.com/plugins/optimole-wp/trunk/raw/inc/compatibilities/groovy_menu.php
- Modified: 2026-09-21T12:01:16+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/optimole-wp/trunk/code/inc/compatibilities/groovy_menu.php#L10-L20`.

```php
<?php
/**
 * Class Optml_groovy_menu.
 *
 * @reason Groovy Menu's auto-integration opens its own output buffer on `init`
 * and, on `shutdown` at priority 0, calls ob_get_clean() on whichever buffer is
 * on top to insert the menu markup after <body>.
 *
 * This only matters with the `optml_capture_at_shutdown` opt-in, where we capture
 * and process our buffer at `shutdown` (PHP_INT_MIN) and re-arm an empty one, so
 * Groovy Menu would receive an empty string and drop the menu. In that mode we
 * apply Groovy Menu's final-output filter to the page we capture, before image
 * replacement, and unhook its own shutdown step at that moment. In the default
 * in-handler mode our capture never runs and Groovy Menu keeps its own step.
 */
class Optml_groovy_menu extends Optml_compatibility {
	/**
	 * Groovy Menu's shutdown callback that grabs the top output buffer.
	 */
	const GROOVY_SHUTDOWN_CALLBACK = 'groovy_menu_pre_shutdown';

	/**
	 * Groovy Menu's filter that inserts the menu markup into the page HTML.
	 */
	const GROOVY_OUTPUT_FILTER = 'groovy_menu_final_output';

	/**
	 * Should we load the integration logic.
	 *
	 * @return bool Should we load.
	 */
	public function should_load() {
		return function_exists( self::GROOVY_SHUTDOWN_CALLBACK )
			&& has_action( 'shutdown', self::GROOVY_SHUTDOWN_CALLBACK ) !== false;
	}

	/**
	 * Register integration details.
	 *
	 * @return void
	 */
	public function register() {
		add_filter( 'optml_captured_page_html', [ $this, 'insert_menu' ] );
	}

	/**
	 * Insert the Groovy Menu markup into the captured page and take over its shutdown step.
	 *
	 * @param string $html The captured page HTML, before image replacement.
	 *
	 * @return string
	 */
	public function insert_menu( $html ) {
		$priority = has_action( 'shutdown', self::GROOVY_SHUTDOWN_CALLBACK );
		if ( $priority === false ) {
			return $html;
		}
		// Our capture ran, so Groovy Menu must not ob_get_clean() the re-armed empty buffer afterwards.
		remove_action( 'shutdown', self::GROOVY_SHUTDOWN_CALLBACK, $priority );

		// Same guard as Groovy Menu's own shutdown callback.
		if ( ! defined( 'GROOVY_MENU_SCRIPTS_INIT' ) ) {
			return $html;
		}

		return apply_filters( self::GROOVY_OUTPUT_FILTER, $html ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Groovy Menu's own filter.
	}
}

```
