is_404 = false; $wp_query->queried_object = $contextPost; $wp_query->queried_object_id = $contextId; } /** * On Yatra pages, fire wanderland_mikado_action_before_main_content from inside * wanderland_mikado_action_after_wrapper_inner. * * Header types that remap the header hook (header-bottom, header-bottom-centered, * header-bottom-minimal) attach wanderland_mikado_get_header to * wanderland_mikado_action_before_main_content. Yatra templates only call * get_header() → wanderland/header.php → wanderland_mikado_action_after_wrapper_inner, * never the before_main_content action. This bridge ensures those header types * still render their output. * * The static flag guarantees this bridge fires at most once per request, so the * header is never duplicated even if the action fires more than once. * * Hooked: wanderland_mikado_action_after_wrapper_inner, priority 5 */ public static function maybeFireBeforeMainContent(): void { // Hard guard: fire at most once per request. if (self::$beforeMainContentFired) { return; } if (!self::isWanderlandActive()) { return; } if (!self::isYatraRoutedRequest()) { return; } self::$beforeMainContentFired = true; do_action('wanderland_mikado_action_before_main_content'); } // ------------------------------------------------------------------------- // Internal helpers // ------------------------------------------------------------------------- /** * Returns true when the Wanderland theme (or a child theme of it) is active. * * Uses get_template() which returns the PARENT theme slug even for child themes. * This is checked lazily (inside callbacks) so it works correctly regardless of * whether the theme was loaded before or after register() ran. */ private static function isWanderlandActive(): bool { return get_template() === 'wanderland'; } /** * Detect whether the current request is a Yatra-routed page. * Relies only on registered WP query vars, which are available from `wp` onwards. */ private static function isYatraRoutedRequest(): bool { $yatraQueryVars = [ 'yatra_page', 'yatra_booking_confirmation', 'yatra_remaining_checkout', 'yatra_verify_email', ]; foreach ($yatraQueryVars as $var) { if ((string) get_query_var($var, '') !== '') { return true; } } return false; } /** * Find the best WordPress page ID to use as the request context. * * The chosen page must NOT have a per-page header-type override so Wanderland * falls back to the global header option — which is what should apply to Yatra pages. * * Selection order (first non-zero result wins): * 1. Static front page (page_on_front) — present on most sites, rarely has a * per-page header override. * 2. Posts page (page_for_posts). * 3. The first published WP page (by ID ascending) without mkdf_header_type_meta set. */ private static function resolveContextPageId(): int { // 1. Static front page $id = (int) get_option('page_on_front', 0); if ($id > 0) { return $id; } // 2. Posts page $id = (int) get_option('page_for_posts', 0); if ($id > 0) { return $id; } // 3. Any published page without a per-page header override $pages = get_posts([ 'post_type' => 'page', 'post_status' => 'publish', 'posts_per_page' => 1, 'orderby' => 'ID', 'order' => 'ASC', 'meta_query' => [ [ 'key' => 'mkdf_header_type_meta', 'compare' => 'NOT EXISTS', ], ], 'no_found_rows' => true, ]); if (!empty($pages) && $pages[0] instanceof \WP_Post) { return $pages[0]->ID; } return 0; } }