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:
@@ -225,9 +225,8 @@ class CheckoutController {
|
||||
// Totals
|
||||
$order->calculate_totals();
|
||||
|
||||
// Mirror Woo hooks so extensions still work
|
||||
// Mirror Woo hooks so extensions still work (but not thankyou which outputs HTML)
|
||||
do_action('woocommerce_checkout_create_order', $order->get_id(), $order);
|
||||
do_action('woocommerce_thankyou', $order->get_id());
|
||||
|
||||
$order->save();
|
||||
|
||||
|
||||
196
includes/Api/NewsletterController.php
Normal file
196
includes/Api/NewsletterController.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
namespace WooNooW\API;
|
||||
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Response;
|
||||
use WP_Error;
|
||||
|
||||
class NewsletterController {
|
||||
const API_NAMESPACE = 'woonoow/v1';
|
||||
|
||||
public static function register_routes() {
|
||||
register_rest_route(self::API_NAMESPACE, '/newsletter/subscribe', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'subscribe'],
|
||||
'permission_callback' => '__return_true',
|
||||
'args' => [
|
||||
'email' => [
|
||||
'required' => true,
|
||||
'type' => 'string',
|
||||
'validate_callback' => function($param) {
|
||||
return is_email($param);
|
||||
},
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
register_rest_route(self::API_NAMESPACE, '/newsletter/subscribers', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_subscribers'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_options');
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route(self::API_NAMESPACE, '/newsletter/subscribers/(?P<email>[^/]+)', [
|
||||
'methods' => 'DELETE',
|
||||
'callback' => [__CLASS__, 'delete_subscriber'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_options');
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route(self::API_NAMESPACE, '/newsletter/template/(?P<template>[^/]+)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_template'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_options');
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route(self::API_NAMESPACE, '/newsletter/template/(?P<template>[^/]+)', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'save_template'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_options');
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
public static function get_template(WP_REST_Request $request) {
|
||||
$template = $request->get_param('template');
|
||||
$option_key = "woonoow_newsletter_{$template}_template";
|
||||
|
||||
$data = get_option($option_key, [
|
||||
'subject' => $template === 'welcome' ? 'Welcome to {site_name} Newsletter!' : 'Confirm your newsletter subscription',
|
||||
'content' => $template === 'welcome'
|
||||
? "Thank you for subscribing to our newsletter!\n\nYou'll receive updates about our latest products and offers.\n\nBest regards,\n{site_name}"
|
||||
: "Please confirm your newsletter subscription by clicking the link below:\n\n{confirmation_url}\n\nBest regards,\n{site_name}",
|
||||
]);
|
||||
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'subject' => $data['subject'] ?? '',
|
||||
'content' => $data['content'] ?? '',
|
||||
], 200);
|
||||
}
|
||||
|
||||
public static function save_template(WP_REST_Request $request) {
|
||||
$template = $request->get_param('template');
|
||||
$subject = sanitize_text_field($request->get_param('subject'));
|
||||
$content = wp_kses_post($request->get_param('content'));
|
||||
|
||||
$option_key = "woonoow_newsletter_{$template}_template";
|
||||
|
||||
update_option($option_key, [
|
||||
'subject' => $subject,
|
||||
'content' => $content,
|
||||
]);
|
||||
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'message' => 'Template saved successfully',
|
||||
], 200);
|
||||
}
|
||||
|
||||
public static function delete_subscriber(WP_REST_Request $request) {
|
||||
$email = urldecode($request->get_param('email'));
|
||||
$subscribers = get_option('woonoow_newsletter_subscribers', []);
|
||||
|
||||
$subscribers = array_filter($subscribers, function($sub) use ($email) {
|
||||
return isset($sub['email']) && $sub['email'] !== $email;
|
||||
});
|
||||
|
||||
update_option('woonoow_newsletter_subscribers', array_values($subscribers));
|
||||
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'message' => 'Subscriber removed successfully',
|
||||
], 200);
|
||||
}
|
||||
|
||||
public static function subscribe(WP_REST_Request $request) {
|
||||
$email = sanitize_email($request->get_param('email'));
|
||||
|
||||
if (!is_email($email)) {
|
||||
return new WP_Error('invalid_email', 'Invalid email address', ['status' => 400]);
|
||||
}
|
||||
|
||||
// Get existing subscribers (now stored as objects with metadata)
|
||||
$subscribers = get_option('woonoow_newsletter_subscribers', []);
|
||||
|
||||
// Check if already subscribed
|
||||
$existing = array_filter($subscribers, function($sub) use ($email) {
|
||||
return isset($sub['email']) && $sub['email'] === $email;
|
||||
});
|
||||
|
||||
if (!empty($existing)) {
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'message' => 'You are already subscribed to our newsletter!',
|
||||
], 200);
|
||||
}
|
||||
|
||||
// Check if email belongs to a WP user
|
||||
$user = get_user_by('email', $email);
|
||||
$user_id = $user ? $user->ID : null;
|
||||
|
||||
// Add new subscriber with metadata
|
||||
$subscribers[] = [
|
||||
'email' => $email,
|
||||
'user_id' => $user_id,
|
||||
'status' => 'active',
|
||||
'subscribed_at' => current_time('mysql'),
|
||||
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
|
||||
];
|
||||
|
||||
update_option('woonoow_newsletter_subscribers', $subscribers);
|
||||
|
||||
// Trigger notification events
|
||||
do_action('woonoow_newsletter_subscribed', $email, $user_id);
|
||||
|
||||
// Trigger notification system events (uses email builder)
|
||||
do_action('woonoow/notification/event', 'newsletter_welcome', 'customer', [
|
||||
'email' => $email,
|
||||
'user_id' => $user_id,
|
||||
'subscribed_at' => current_time('mysql'),
|
||||
]);
|
||||
|
||||
do_action('woonoow/notification/event', 'newsletter_subscribed_admin', 'staff', [
|
||||
'email' => $email,
|
||||
'user_id' => $user_id,
|
||||
'subscribed_at' => current_time('mysql'),
|
||||
]);
|
||||
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'message' => 'Successfully subscribed! Check your email for confirmation.',
|
||||
], 200);
|
||||
}
|
||||
|
||||
private static function send_welcome_email($email) {
|
||||
$site_name = get_bloginfo('name');
|
||||
$template = get_option('woonoow_newsletter_welcome_template', '');
|
||||
|
||||
if (empty($template)) {
|
||||
$template = "Thank you for subscribing to our newsletter!\n\nYou'll receive updates about our latest products and offers.\n\nBest regards,\n{site_name}";
|
||||
}
|
||||
|
||||
$subject = sprintf('Welcome to %s Newsletter!', $site_name);
|
||||
$message = str_replace('{site_name}', $site_name, $template);
|
||||
|
||||
wp_mail($email, $subject, $message);
|
||||
}
|
||||
|
||||
public static function get_subscribers(WP_REST_Request $request) {
|
||||
$subscribers = get_option('woonoow_newsletter_subscribers', []);
|
||||
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'subscribers' => $subscribers,
|
||||
'count' => count($subscribers),
|
||||
],
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
@@ -317,14 +317,14 @@ class ProductsController {
|
||||
}
|
||||
|
||||
// Virtual and downloadable
|
||||
if (!empty($data['virtual'])) {
|
||||
$product->set_virtual(true);
|
||||
if (isset($data['virtual'])) {
|
||||
$product->set_virtual((bool) $data['virtual']);
|
||||
}
|
||||
if (!empty($data['downloadable'])) {
|
||||
$product->set_downloadable(true);
|
||||
if (isset($data['downloadable'])) {
|
||||
$product->set_downloadable((bool) $data['downloadable']);
|
||||
}
|
||||
if (!empty($data['featured'])) {
|
||||
$product->set_featured(true);
|
||||
if (isset($data['featured'])) {
|
||||
$product->set_featured((bool) $data['featured']);
|
||||
}
|
||||
|
||||
// Categories
|
||||
@@ -418,6 +418,17 @@ class ProductsController {
|
||||
if (isset($data['width'])) $product->set_width(self::sanitize_number($data['width']));
|
||||
if (isset($data['height'])) $product->set_height(self::sanitize_number($data['height']));
|
||||
|
||||
// Virtual and downloadable
|
||||
if (isset($data['virtual'])) {
|
||||
$product->set_virtual((bool) $data['virtual']);
|
||||
}
|
||||
if (isset($data['downloadable'])) {
|
||||
$product->set_downloadable((bool) $data['downloadable']);
|
||||
}
|
||||
if (isset($data['featured'])) {
|
||||
$product->set_featured((bool) $data['featured']);
|
||||
}
|
||||
|
||||
// Categories
|
||||
if (isset($data['categories'])) {
|
||||
$product->set_category_ids($data['categories']);
|
||||
|
||||
@@ -20,17 +20,23 @@ use WooNooW\Api\ActivityLogController;
|
||||
use WooNooW\Api\ProductsController;
|
||||
use WooNooW\Api\CouponsController;
|
||||
use WooNooW\Api\CustomersController;
|
||||
use WooNooW\Api\NewsletterController;
|
||||
use WooNooW\Frontend\ShopController;
|
||||
use WooNooW\Frontend\CartController as FrontendCartController;
|
||||
use WooNooW\Frontend\AccountController;
|
||||
use WooNooW\Frontend\HookBridge;
|
||||
use WooNooW\Api\Controllers\SettingsController;
|
||||
use WooNooW\Api\Controllers\CartController as ApiCartController;
|
||||
use WooNooW\Admin\AppearanceController;
|
||||
|
||||
class Routes {
|
||||
public static function init() {
|
||||
// Initialize controllers (register action hooks)
|
||||
OrdersController::init();
|
||||
AppearanceController::init();
|
||||
|
||||
// Initialize CartController auth bypass (must be before rest_api_init)
|
||||
FrontendCartController::init();
|
||||
|
||||
// Log ALL REST API requests to debug routing
|
||||
add_filter('rest_pre_dispatch', function($result, $server, $request) {
|
||||
@@ -76,9 +82,9 @@ class Routes {
|
||||
$settings_controller = new SettingsController();
|
||||
$settings_controller->register_routes();
|
||||
|
||||
// Cart controller (API)
|
||||
$api_cart_controller = new ApiCartController();
|
||||
$api_cart_controller->register_routes();
|
||||
// Cart controller (API) - DISABLED: Using Frontend CartController instead to avoid route conflicts
|
||||
// $api_cart_controller = new ApiCartController();
|
||||
// $api_cart_controller->register_routes();
|
||||
|
||||
// Payments controller
|
||||
$payments_controller = new PaymentsController();
|
||||
@@ -131,6 +137,9 @@ class Routes {
|
||||
// Customers controller
|
||||
CustomersController::register_routes();
|
||||
|
||||
// Newsletter controller
|
||||
NewsletterController::register_routes();
|
||||
|
||||
// Frontend controllers (customer-facing)
|
||||
error_log('WooNooW Routes: Registering Frontend controllers');
|
||||
ShopController::register_routes();
|
||||
|
||||
Reference in New Issue
Block a user