fix: WP-Admin CSS conflicts and add-to-cart redirect
- Fix CSS conflicts between WP-Admin and SPA (radio buttons, chart text) - Add Tailwind important selector scoped to #woonoow-admin-app - Remove overly aggressive inline SVG styles from Assets.php - Add targeted WordPress admin CSS overrides in index.css - Fix add-to-cart redirect to use woocommerce_add_to_cart_redirect filter - Let WooCommerce handle cart operations natively for proper session management - Remove duplicate tailwind.config.cjs
This commit is contained in:
@@ -5,69 +5,126 @@ namespace WooNooW\Frontend;
|
||||
* Template Override
|
||||
* Overrides WooCommerce templates to use WooNooW SPA
|
||||
*/
|
||||
class TemplateOverride {
|
||||
|
||||
class TemplateOverride
|
||||
{
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public static function init() {
|
||||
public static function init()
|
||||
{
|
||||
// Hook to wp_loaded with priority 10 (BEFORE WooCommerce's priority 20)
|
||||
// This ensures we process add-to-cart before WooCommerce does
|
||||
add_action('wp_loaded', [__CLASS__, 'intercept_add_to_cart'], 10);
|
||||
|
||||
// Use blank template for full-page SPA
|
||||
add_filter('template_include', [__CLASS__, 'use_spa_template'], 999);
|
||||
|
||||
|
||||
// Disable canonical redirects for SPA routes
|
||||
add_filter('redirect_canonical', [__CLASS__, 'disable_canonical_redirect'], 10, 2);
|
||||
|
||||
|
||||
// Override WooCommerce shop page
|
||||
add_filter('woocommerce_show_page_title', '__return_false');
|
||||
|
||||
|
||||
// Replace WooCommerce content with our SPA
|
||||
add_action('woocommerce_before_main_content', [__CLASS__, 'start_spa_wrapper'], 5);
|
||||
add_action('woocommerce_after_main_content', [__CLASS__, 'end_spa_wrapper'], 999);
|
||||
|
||||
|
||||
// Remove WooCommerce default content
|
||||
remove_action('woocommerce_before_shop_loop', 'woocommerce_result_count', 20);
|
||||
remove_action('woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30);
|
||||
remove_action('woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10);
|
||||
remove_action('woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10);
|
||||
|
||||
|
||||
// Override single product template
|
||||
add_filter('woocommerce_locate_template', [__CLASS__, 'override_template'], 10, 3);
|
||||
|
||||
|
||||
// Remove theme header and footer when SPA is active
|
||||
add_action('get_header', [__CLASS__, 'remove_theme_header']);
|
||||
add_action('get_footer', [__CLASS__, 'remove_theme_footer']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable canonical redirects for SPA routes
|
||||
* This prevents WordPress from redirecting /product/slug URLs
|
||||
*/
|
||||
public static function disable_canonical_redirect($redirect_url, $requested_url) {
|
||||
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) {
|
||||
public static function use_spa_template($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';
|
||||
@@ -75,21 +132,23 @@ class TemplateOverride {
|
||||
return $spa_template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Legacy: Check SPA mode settings
|
||||
$settings = get_option('woonoow_customer_spa_settings', []);
|
||||
$mode = isset($settings['mode']) ? $settings['mode'] : 'disabled';
|
||||
|
||||
|
||||
// Mode 1: Disabled - but still check for shortcodes (legacy)
|
||||
if ($mode === 'disabled') {
|
||||
// Check if page has woonoow shortcodes
|
||||
global $post;
|
||||
if ($post && (
|
||||
has_shortcode($post->post_content, 'woonoow_shop') ||
|
||||
has_shortcode($post->post_content, 'woonoow_cart') ||
|
||||
has_shortcode($post->post_content, 'woonoow_checkout') ||
|
||||
has_shortcode($post->post_content, 'woonoow_account')
|
||||
)) {
|
||||
if (
|
||||
$post && (
|
||||
has_shortcode($post->post_content, 'woonoow_shop') ||
|
||||
has_shortcode($post->post_content, 'woonoow_cart') ||
|
||||
has_shortcode($post->post_content, 'woonoow_checkout') ||
|
||||
has_shortcode($post->post_content, 'woonoow_account')
|
||||
)
|
||||
) {
|
||||
// Use blank template for shortcode pages too
|
||||
$spa_template = plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-full-page.php';
|
||||
if (file_exists($spa_template)) {
|
||||
@@ -98,19 +157,19 @@ class TemplateOverride {
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
|
||||
|
||||
// Check if current URL is a SPA route (for direct access)
|
||||
$request_uri = $_SERVER['REQUEST_URI'];
|
||||
$spa_routes = ['/shop', '/product/', '/cart', '/checkout', '/my-account'];
|
||||
$is_spa_route = false;
|
||||
|
||||
|
||||
foreach ($spa_routes as $route) {
|
||||
if (strpos($request_uri, $route) !== false) {
|
||||
$is_spa_route = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If it's a SPA route in full mode, use SPA template
|
||||
if ($mode === 'full' && $is_spa_route) {
|
||||
$spa_template = plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-full-page.php';
|
||||
@@ -120,18 +179,18 @@ class TemplateOverride {
|
||||
return $spa_template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mode 3: Checkout-Only (partial SPA)
|
||||
if ($mode === 'checkout_only') {
|
||||
$checkout_pages = isset($settings['checkoutPages']) ? $settings['checkoutPages'] : [
|
||||
'checkout' => true,
|
||||
'thankyou' => true,
|
||||
'account' => true,
|
||||
'cart' => false,
|
||||
'account' => true,
|
||||
'cart' => false,
|
||||
];
|
||||
|
||||
|
||||
$should_override = false;
|
||||
|
||||
|
||||
if (!empty($checkout_pages['checkout']) && is_checkout() && !is_order_received_page()) {
|
||||
$should_override = true;
|
||||
}
|
||||
@@ -144,17 +203,17 @@ class TemplateOverride {
|
||||
if (!empty($checkout_pages['cart']) && is_cart()) {
|
||||
$should_override = true;
|
||||
}
|
||||
|
||||
|
||||
if ($should_override) {
|
||||
$spa_template = plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-full-page.php';
|
||||
if (file_exists($spa_template)) {
|
||||
return $spa_template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
|
||||
// Mode 2: Full SPA
|
||||
if ($mode === 'full') {
|
||||
// Override all WooCommerce pages
|
||||
@@ -165,23 +224,24 @@ class TemplateOverride {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start SPA wrapper
|
||||
*/
|
||||
public static function 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;
|
||||
@@ -196,58 +256,61 @@ class TemplateOverride {
|
||||
$page_type = 'account';
|
||||
$data_attrs = 'data-page="account"';
|
||||
}
|
||||
|
||||
|
||||
// Output SPA mount point
|
||||
echo '<div id="woonoow-customer-app" ' . $data_attrs . '>';
|
||||
echo '<div class="woonoow-loading">';
|
||||
echo '<p>' . esc_html__('Loading...', 'woonoow') . '</p>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
|
||||
// Hide WooCommerce content
|
||||
echo '<div style="display: none;">';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* End SPA wrapper
|
||||
*/
|
||||
public static function end_spa_wrapper() {
|
||||
public static function end_spa_wrapper()
|
||||
{
|
||||
if (!self::should_use_spa()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Close hidden wrapper
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if we should use SPA
|
||||
*/
|
||||
private static function should_use_spa() {
|
||||
private static function should_use_spa()
|
||||
{
|
||||
// Check if frontend mode is enabled
|
||||
$mode = get_option('woonoow_frontend_mode', 'shortcodes');
|
||||
|
||||
|
||||
if ($mode === 'disabled') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// For full SPA mode, always use SPA
|
||||
if ($mode === 'full_spa') {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// For shortcode mode, check if we're on WooCommerce pages
|
||||
if (is_shop() || is_product() || is_cart() || is_checkout() || is_account_page()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove theme header when SPA is active
|
||||
*/
|
||||
public static function remove_theme_header() {
|
||||
public static function remove_theme_header()
|
||||
{
|
||||
if (self::should_remove_theme_elements()) {
|
||||
remove_all_actions('wp_head');
|
||||
// Re-add essential WordPress head actions
|
||||
@@ -258,69 +321,74 @@ class TemplateOverride {
|
||||
add_action('wp_head', 'wp_site_icon', 99);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove theme footer when SPA is active
|
||||
*/
|
||||
public static function remove_theme_footer() {
|
||||
public static function remove_theme_footer()
|
||||
{
|
||||
if (self::should_remove_theme_elements()) {
|
||||
remove_all_actions('wp_footer');
|
||||
// Re-add essential WordPress footer actions
|
||||
add_action('wp_footer', 'wp_print_footer_scripts', 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if current page is the designated SPA page
|
||||
*/
|
||||
private static function is_spa_page() {
|
||||
private static function is_spa_page()
|
||||
{
|
||||
global $post;
|
||||
if (!$post) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Get SPA page ID 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;
|
||||
|
||||
|
||||
// Check if current page matches the SPA page
|
||||
if ($spa_page_id && $post->ID == $spa_page_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if we should remove theme header/footer
|
||||
*/
|
||||
private static function should_remove_theme_elements() {
|
||||
private static function should_remove_theme_elements()
|
||||
{
|
||||
// Remove for designated SPA pages
|
||||
if (self::is_spa_page()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
$settings = get_option('woonoow_customer_spa_settings', []);
|
||||
$mode = isset($settings['mode']) ? $settings['mode'] : 'disabled';
|
||||
|
||||
|
||||
// Check if we're on a WooCommerce page in full mode
|
||||
if ($mode === 'full') {
|
||||
if (is_shop() || is_product() || is_cart() || is_checkout() || is_account_page() || is_woocommerce()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Also remove for pages with shortcodes (even in disabled mode)
|
||||
global $post;
|
||||
if ($post && (
|
||||
has_shortcode($post->post_content, 'woonoow_shop') ||
|
||||
has_shortcode($post->post_content, 'woonoow_cart') ||
|
||||
has_shortcode($post->post_content, 'woonoow_checkout') ||
|
||||
has_shortcode($post->post_content, 'woonoow_account')
|
||||
)) {
|
||||
if (
|
||||
$post && (
|
||||
has_shortcode($post->post_content, 'woonoow_shop') ||
|
||||
has_shortcode($post->post_content, 'woonoow_cart') ||
|
||||
has_shortcode($post->post_content, 'woonoow_checkout') ||
|
||||
has_shortcode($post->post_content, 'woonoow_account')
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Special check for Shop page (archive)
|
||||
if (function_exists('is_shop') && is_shop()) {
|
||||
$shop_page_id = get_option('woocommerce_shop_page_id');
|
||||
@@ -331,19 +399,20 @@ class TemplateOverride {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Override WooCommerce templates
|
||||
*/
|
||||
public static function override_template($template, $template_name, $template_path) {
|
||||
public static function override_template($template, $template_name, $template_path)
|
||||
{
|
||||
// Only override if SPA is enabled
|
||||
if (!self::should_use_spa()) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
|
||||
// Templates to override
|
||||
$override_templates = [
|
||||
'archive-product.php',
|
||||
@@ -351,7 +420,7 @@ class TemplateOverride {
|
||||
'cart/cart.php',
|
||||
'checkout/form-checkout.php',
|
||||
];
|
||||
|
||||
|
||||
// Check if this template should be overridden
|
||||
foreach ($override_templates as $override) {
|
||||
if (strpos($template_name, $override) !== false) {
|
||||
@@ -359,7 +428,7 @@ class TemplateOverride {
|
||||
return plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-wrapper.php';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user