( $initial_level + 1 ) ? (string) ob_get_clean() : ''; // Discard our stray-notices buffer (level N+1). if ( ob_get_level() > $initial_level ) { ob_end_clean(); } // Open a fresh, clean buffer at the level WP expects for its ob_get_clean(). ob_start(); // Restore any output WP produced during dispatch (almost always empty). if ( '' !== $wp_dispatch ) { echo $wp_dispatch; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } return false; // Let WP echo the JSON body and collect it via ob_get_clean(). } /** * Discard all output buffered above DISCO_OB_LEVEL. * Call this in AJAX handlers before wp_send_json_* to strip stray debug output. */ public static function clean(): void { if ( ! defined( 'DISCO_OB_LEVEL' ) ) { return; } while ( ob_get_level() > DISCO_OB_LEVEL ) { ob_end_clean(); } } private static function is_api_request(): bool { return self::is_ajax_request() || self::is_rest_request(); } private static function is_ajax_request(): bool { return defined( 'DOING_AJAX' ) && DOING_AJAX; } private static function is_rest_request(): bool { if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { return true; } if ( empty( $_SERVER['REQUEST_URI'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput return false; } // REST_REQUEST is not defined yet at plugin-file load time, so we inspect // the URI directly. rest_get_url_prefix() respects custom REST base slugs. $request_uri = wp_unslash( $_SERVER['REQUEST_URI'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $rest_prefix = function_exists( 'rest_get_url_prefix' ) ? rest_get_url_prefix() : 'wp-json'; return false !== strpos( $request_uri, '/' . $rest_prefix . '/' ); } }