- Add WP Media Library integration for product and variation images - Support images array (URLs) conversion to attachment IDs - Add images array to API responses (Admin & Customer SPA) - Implement drag-and-drop sortable images in Admin product form - Add image gallery thumbnails in Customer SPA product page - Initialize WooCommerce session for guest cart operations - Fix product variations and attributes display in Customer SPA - Add variation image field in Admin SPA Changes: - includes/Api/ProductsController.php: Handle images array, add to responses - includes/Frontend/ShopController.php: Add images array for customer SPA - includes/Frontend/CartController.php: Initialize WC session for guests - admin-spa/src/lib/wp-media.ts: Add openWPMediaGallery function - admin-spa/src/routes/Products/partials/tabs/GeneralTab.tsx: WP Media + sortable images - admin-spa/src/routes/Products/partials/tabs/VariationsTab.tsx: Add variation image field - customer-spa/src/pages/Product/index.tsx: Add gallery thumbnails display
248 lines
8.2 KiB
PHP
248 lines
8.2 KiB
PHP
<?php
|
|
namespace WooNooW\Frontend;
|
|
|
|
/**
|
|
* Template Override
|
|
* Overrides WooCommerce templates to use WooNooW SPA
|
|
*/
|
|
class TemplateOverride {
|
|
|
|
/**
|
|
* Initialize
|
|
*/
|
|
public static function init() {
|
|
// 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);
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
$settings = get_option('woonoow_customer_spa_settings', []);
|
|
$mode = isset($settings['mode']) ? $settings['mode'] : 'disabled';
|
|
|
|
// Mode 1: Disabled
|
|
if ($mode === 'disabled') {
|
|
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';
|
|
if (file_exists($spa_template)) {
|
|
// Set status to 200 to prevent 404
|
|
status_header(200);
|
|
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,
|
|
];
|
|
|
|
$should_override = false;
|
|
|
|
if (!empty($checkout_pages['checkout']) && is_checkout() && !is_order_received_page()) {
|
|
$should_override = true;
|
|
}
|
|
if (!empty($checkout_pages['thankyou']) && is_order_received_page()) {
|
|
$should_override = true;
|
|
}
|
|
if (!empty($checkout_pages['account']) && is_account_page()) {
|
|
$should_override = true;
|
|
}
|
|
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
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
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 '<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() {
|
|
if (!self::should_use_spa()) {
|
|
return;
|
|
}
|
|
|
|
// Close hidden wrapper
|
|
echo '</div>';
|
|
}
|
|
|
|
/**
|
|
* Check if we 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;
|
|
}
|
|
|
|
/**
|
|
* Override WooCommerce templates
|
|
*/
|
|
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',
|
|
'single-product.php',
|
|
'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) {
|
|
// Return empty template (SPA will handle rendering)
|
|
return plugin_dir_path(dirname(dirname(__FILE__))) . 'templates/spa-wrapper.php';
|
|
}
|
|
}
|
|
|
|
return $template;
|
|
}
|
|
}
|