feat: implement header/footer visibility controls for checkout and thankyou pages
- Created LayoutWrapper component to conditionally render header/footer based on route - Created MinimalHeader component (logo only) - Created MinimalFooter component (trust badges + policy links) - Created usePageVisibility hook to get visibility settings per page - Wrapped ClassicLayout with LayoutWrapper for conditional rendering - Header/footer visibility now controlled directly in React SPA - Settings: show/minimal/hide for both header and footer - Background color support for checkout and thankyou pages
This commit is contained in:
@@ -11,24 +11,51 @@ use WP_Error;
|
||||
*/
|
||||
class CartController {
|
||||
|
||||
/**
|
||||
* Initialize controller
|
||||
*/
|
||||
public static function init() {
|
||||
// Bypass cookie authentication for cart endpoints to allow guest users
|
||||
add_filter('rest_authentication_errors', function($result) {
|
||||
// If already authenticated or error, return as is
|
||||
if (!empty($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Check if this is a cart endpoint
|
||||
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
|
||||
if (strpos($request_uri, '/woonoow/v1/cart') !== false) {
|
||||
error_log('WooNooW Cart: Bypassing authentication for cart endpoint');
|
||||
return true; // Allow access
|
||||
}
|
||||
|
||||
return $result;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register REST API routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
error_log('WooNooW CartController::register_routes() START');
|
||||
$namespace = 'woonoow/v1';
|
||||
|
||||
// Get cart
|
||||
register_rest_route($namespace, '/cart', [
|
||||
$result = register_rest_route($namespace, '/cart', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_cart'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
error_log('WooNooW CartController: GET /cart registered: ' . ($result ? 'SUCCESS' : 'FAILED'));
|
||||
|
||||
// Add to cart
|
||||
register_rest_route($namespace, '/cart/add', [
|
||||
$result = register_rest_route($namespace, '/cart/add', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'add_to_cart'],
|
||||
'permission_callback' => '__return_true',
|
||||
'permission_callback' => function() {
|
||||
// Allow both logged-in and guest users
|
||||
return true;
|
||||
},
|
||||
'args' => [
|
||||
'product_id' => [
|
||||
'required' => true,
|
||||
@@ -46,12 +73,13 @@ class CartController {
|
||||
],
|
||||
],
|
||||
]);
|
||||
error_log('WooNooW CartController: POST /cart/add registered: ' . ($result ? 'SUCCESS' : 'FAILED'));
|
||||
|
||||
// Update cart item
|
||||
register_rest_route($namespace, '/cart/update', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'update_cart'],
|
||||
'permission_callback' => '__return_true',
|
||||
'permission_callback' => function() { return true; },
|
||||
'args' => [
|
||||
'cart_item_key' => [
|
||||
'required' => true,
|
||||
@@ -68,7 +96,7 @@ class CartController {
|
||||
register_rest_route($namespace, '/cart/remove', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'remove_from_cart'],
|
||||
'permission_callback' => '__return_true',
|
||||
'permission_callback' => function() { return true; },
|
||||
'args' => [
|
||||
'cart_item_key' => [
|
||||
'required' => true,
|
||||
@@ -81,7 +109,7 @@ class CartController {
|
||||
register_rest_route($namespace, '/cart/apply-coupon', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'apply_coupon'],
|
||||
'permission_callback' => '__return_true',
|
||||
'permission_callback' => function() { return true; },
|
||||
'args' => [
|
||||
'coupon_code' => [
|
||||
'required' => true,
|
||||
@@ -94,7 +122,7 @@ class CartController {
|
||||
register_rest_route($namespace, '/cart/remove-coupon', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'remove_coupon'],
|
||||
'permission_callback' => '__return_true',
|
||||
'permission_callback' => function() { return true; },
|
||||
'args' => [
|
||||
'coupon_code' => [
|
||||
'required' => true,
|
||||
@@ -123,28 +151,119 @@ class CartController {
|
||||
$quantity = $request->get_param('quantity');
|
||||
$variation_id = $request->get_param('variation_id');
|
||||
|
||||
// Initialize WooCommerce session for guest users
|
||||
if (!WC()->session->has_session()) {
|
||||
WC()->session->set_customer_session_cookie(true);
|
||||
error_log("WooNooW Cart: Adding product {$product_id} (variation: {$variation_id}) qty: {$quantity}");
|
||||
|
||||
// Check if WooCommerce is available
|
||||
if (!function_exists('WC')) {
|
||||
error_log('WooNooW Cart Error: WooCommerce not loaded');
|
||||
return new WP_Error('wc_not_loaded', 'WooCommerce is not loaded', ['status' => 500]);
|
||||
}
|
||||
|
||||
// Initialize WooCommerce session and cart for REST API requests
|
||||
// WooCommerce doesn't auto-initialize these for REST API calls
|
||||
if (!WC()->session) {
|
||||
error_log('WooNooW Cart: Initializing WC session for REST API');
|
||||
WC()->initialize_session();
|
||||
}
|
||||
|
||||
if (!WC()->cart) {
|
||||
return new WP_Error('cart_error', 'Cart not initialized', ['status' => 500]);
|
||||
error_log('WooNooW Cart: Initializing WC cart for REST API');
|
||||
WC()->initialize_cart();
|
||||
}
|
||||
|
||||
// Set session cookie for guest users
|
||||
if (!WC()->session->has_session()) {
|
||||
WC()->session->set_customer_session_cookie(true);
|
||||
error_log('WooNooW Cart: Session cookie set for guest user');
|
||||
}
|
||||
|
||||
error_log('WooNooW Cart: WC Session and Cart initialized successfully');
|
||||
|
||||
// Validate product
|
||||
$product = wc_get_product($product_id);
|
||||
if (!$product) {
|
||||
error_log("WooNooW Cart Error: Product {$product_id} not found");
|
||||
return new WP_Error('invalid_product', 'Product not found', ['status' => 404]);
|
||||
}
|
||||
|
||||
// Add to cart
|
||||
$cart_item_key = WC()->cart->add_to_cart($product_id, $quantity, $variation_id);
|
||||
error_log("WooNooW Cart: Product validated - {$product->get_name()} (Type: {$product->get_type()})");
|
||||
|
||||
// For variable products, validate the variation and get attributes
|
||||
$variation_attributes = [];
|
||||
if ($variation_id > 0) {
|
||||
$variation = wc_get_product($variation_id);
|
||||
if (!$variation) {
|
||||
error_log("WooNooW Cart Error: Variation {$variation_id} not found");
|
||||
return new WP_Error('invalid_variation', "Variation {$variation_id} not found", ['status' => 404]);
|
||||
}
|
||||
|
||||
if ($variation->get_parent_id() != $product_id) {
|
||||
error_log("WooNooW Cart Error: Variation {$variation_id} does not belong to product {$product_id}");
|
||||
return new WP_Error('invalid_variation', "Variation does not belong to this product", ['status' => 400]);
|
||||
}
|
||||
|
||||
if (!$variation->is_purchasable() || !$variation->is_in_stock()) {
|
||||
error_log("WooNooW Cart Error: Variation {$variation_id} is not purchasable or out of stock");
|
||||
return new WP_Error('variation_not_available', "This variation is not available for purchase", ['status' => 400]);
|
||||
}
|
||||
|
||||
// Get variation attributes from post meta
|
||||
// WooCommerce stores variation attributes as post meta with 'attribute_' prefix
|
||||
$variation_attributes = [];
|
||||
|
||||
// Get parent product to know which attributes to look for
|
||||
$parent_product = wc_get_product($product_id);
|
||||
$parent_attributes = $parent_product->get_attributes();
|
||||
|
||||
error_log("WooNooW Cart: Parent product attributes: " . print_r(array_keys($parent_attributes), true));
|
||||
|
||||
// For each parent attribute, get the value from variation post meta
|
||||
foreach ($parent_attributes as $attribute) {
|
||||
if ($attribute->get_variation()) {
|
||||
$attribute_name = $attribute->get_name();
|
||||
$meta_key = 'attribute_' . $attribute_name;
|
||||
|
||||
// Get the value from post meta
|
||||
$attribute_value = get_post_meta($variation_id, $meta_key, true);
|
||||
|
||||
error_log("WooNooW Cart: Checking attribute {$attribute_name} (meta key: {$meta_key}): {$attribute_value}");
|
||||
|
||||
if (!empty($attribute_value)) {
|
||||
// WooCommerce expects lowercase attribute names
|
||||
$wc_attribute_key = 'attribute_' . strtolower($attribute_name);
|
||||
$variation_attributes[$wc_attribute_key] = $attribute_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_log("WooNooW Cart: Variation validated - {$variation->get_name()}");
|
||||
error_log("WooNooW Cart: Variation attributes extracted: " . print_r($variation_attributes, true));
|
||||
}
|
||||
|
||||
// Clear any existing notices before adding to cart
|
||||
wc_clear_notices();
|
||||
|
||||
// Add to cart with variation attributes
|
||||
error_log("WooNooW Cart: Calling WC()->cart->add_to_cart({$product_id}, {$quantity}, {$variation_id}, attributes)");
|
||||
$cart_item_key = WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation_attributes);
|
||||
|
||||
if (!$cart_item_key) {
|
||||
return new WP_Error('add_to_cart_failed', 'Failed to add product to cart', ['status' => 400]);
|
||||
// Get WooCommerce notices to provide better error message
|
||||
$notices = wc_get_notices('error');
|
||||
$error_messages = [];
|
||||
foreach ($notices as $notice) {
|
||||
$error_messages[] = is_array($notice) ? $notice['notice'] : $notice;
|
||||
}
|
||||
$error_message = !empty($error_messages) ? implode(', ', $error_messages) : 'Failed to add product to cart';
|
||||
wc_clear_notices(); // Clear notices after reading
|
||||
|
||||
error_log("WooNooW Cart Error: add_to_cart returned false - {$error_message}");
|
||||
error_log("WooNooW Cart Error: All WC notices: " . print_r($notices, true));
|
||||
return new WP_Error('add_to_cart_failed', $error_message, ['status' => 400]);
|
||||
}
|
||||
|
||||
error_log("WooNooW Cart: Product added successfully - Key: {$cart_item_key}");
|
||||
|
||||
return new WP_REST_Response([
|
||||
'message' => 'Product added to cart',
|
||||
'cart_item_key' => $cart_item_key,
|
||||
|
||||
Reference in New Issue
Block a user