post_name; // Rewrite /store/anything to serve the SPA page // React Router handles the path after that add_rewrite_rule( '^' . preg_quote($spa_slug, '/') . '/(.*)$', 'index.php?page_id=' . $spa_page_id . '&woonoow_spa_path=$matches[1]', 'top' ); // Register query var for the SPA path add_filter('query_vars', function($vars) { $vars[] = 'woonoow_spa_path'; return $vars; }); } /** * Intercept add-to-cart redirect (NOT the add-to-cart itself) * Let WooCommerce handle the cart operation properly, we just redirect afterward * * This is the proper approach - WooCommerce manages sessions correctly, * we just customize where the redirect goes. */ public static function intercept_add_to_cart() { // Only act if add-to-cart is present if (!isset($_GET['add-to-cart'])) { return; } // Get SPA page from appearance settings $appearance_settings = get_option('woonoow_appearance_settings', []); $spa_page_id = isset($appearance_settings['general']['spa_page']) ? $appearance_settings['general']['spa_page'] : 0; if (!$spa_page_id) { return; // No SPA page configured, let WooCommerce handle everything } // Hook into WooCommerce's redirect filter AFTER it adds to cart // This is the proper way to customize the redirect destination add_filter('woocommerce_add_to_cart_redirect', function ($url) use ($spa_page_id) { // Get redirect parameter from original request $redirect_to = isset($_GET['redirect']) ? sanitize_text_field($_GET['redirect']) : 'cart'; // Build redirect URL with hash route for SPA $redirect_url = get_permalink($spa_page_id); // Determine hash route based on redirect parameter $hash_route = '/cart'; // Default if ($redirect_to === 'checkout') { $hash_route = '/checkout'; } elseif ($redirect_to === 'shop') { $hash_route = '/shop'; } // Return the SPA URL with hash route return trailingslashit($redirect_url) . '#' . $hash_route; }, 999); // Prevent caching add_action('template_redirect', function () { nocache_headers(); }, 1); } /** * Redirect WooCommerce pages to SPA routes * Maps: /shop → /store/, /cart → /store/cart, etc. */ public static function redirect_wc_pages_to_spa() { // Get SPA settings $appearance_settings = get_option('woonoow_appearance_settings', []); $spa_page_id = $appearance_settings['general']['spa_page'] ?? 0; $spa_mode = $appearance_settings['general']['spa_mode'] ?? 'full'; $use_browser_router = $appearance_settings['general']['use_browser_router'] ?? true; // Only redirect when SPA mode is 'full' if ($spa_mode !== 'full') { return; } if (!$spa_page_id) { return; // No SPA page configured } // Already on SPA page, don't redirect global $post; if ($post && $post->ID == $spa_page_id) { return; } $spa_url = trailingslashit(get_permalink($spa_page_id)); // Helper function to build route URL based on router type $build_route = function($path) use ($spa_url, $use_browser_router) { if ($use_browser_router) { // Path format: /store/cart return $spa_url . ltrim($path, '/'); } // Hash format: /store/#/cart return rtrim($spa_url, '/') . '#/' . ltrim($path, '/'); }; // Check which WC page we're on and redirect if (is_shop()) { wp_redirect($build_route('shop'), 302); exit; } if (is_product()) { // Use get_queried_object() which returns the WP_Post, then get slug $product_post = get_queried_object(); if ($product_post && isset($product_post->post_name)) { $slug = $product_post->post_name; wp_redirect($build_route('product/' . $slug), 302); exit; } } if (is_cart()) { wp_redirect($build_route('cart'), 302); exit; } if (is_checkout() && !is_order_received_page()) { wp_redirect($build_route('checkout'), 302); exit; } if (is_account_page()) { wp_redirect($build_route('my-account'), 302); exit; } } /** * Disable canonical redirects for SPA routes * This prevents WordPress from redirecting /product/slug URLs */ public static function disable_canonical_redirect($redirect_url, $requested_url) { $settings = get_option('woonoow_customer_spa_settings', []); $mode = isset($settings['mode']) ? $settings['mode'] : 'disabled'; // Only disable redirects in full SPA mode if ($mode !== 'full') { return $redirect_url; } // Check if this is a SPA route $spa_routes = ['/product/', '/cart', '/checkout', '/my-account']; foreach ($spa_routes as $route) { if (strpos($requested_url, $route) !== false) { // This is a SPA route, disable WordPress redirect return false; } } return $redirect_url; } /** * Use SPA template (blank page) */ public static function use_spa_template($template) { // Check spa_mode from appearance settings FIRST $appearance_settings = get_option('woonoow_appearance_settings', []); $spa_mode = $appearance_settings['general']['spa_mode'] ?? 'full'; // If SPA is disabled, return original template immediately if ($spa_mode === 'disabled') { return $template; } // Check if current page is a designated SPA page if (self::is_spa_page()) { $spa_template = plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-full-page.php'; if (file_exists($spa_template)) { return $spa_template; } } // For spa_mode = 'full', override WooCommerce pages if ($spa_mode === 'full') { // Override all WooCommerce pages if (is_woocommerce() || is_product() || is_cart() || is_checkout() || is_account_page()) { $spa_template = plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-full-page.php'; if (file_exists($spa_template)) { return $spa_template; } } } // For spa_mode = 'checkout_only' if ($spa_mode === 'checkout_only') { if (is_checkout() || is_order_received_page() || is_account_page() || is_cart()) { $spa_template = plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-full-page.php'; if (file_exists($spa_template)) { return $spa_template; } } } return $template; } /** * Start SPA wrapper */ public static function start_spa_wrapper() { // Check if we should use SPA if (!self::should_use_spa()) { return; } // Determine page type $page_type = 'shop'; $data_attrs = 'data-page="shop"'; if (is_product()) { $page_type = 'product'; global $post; $data_attrs = 'data-page="product" data-product-id="' . esc_attr($post->ID) . '"'; } elseif (is_cart()) { $page_type = 'cart'; $data_attrs = 'data-page="cart"'; } elseif (is_checkout()) { $page_type = 'checkout'; $data_attrs = 'data-page="checkout"'; } elseif (is_account_page()) { $page_type = 'account'; $data_attrs = 'data-page="account"'; } // Output SPA mount point echo '
' . esc_html__('Loading...', 'woonoow') . '
'; echo '