'GET', 'callback' => [__CLASS__, 'get_settings'], 'permission_callback' => '__return_true', ]); // Save general settings register_rest_route(self::API_NAMESPACE, '/appearance/general', [ 'methods' => 'POST', 'callback' => [__CLASS__, 'save_general'], 'permission_callback' => [__CLASS__, 'check_permission'], ]); // Save header settings register_rest_route(self::API_NAMESPACE, '/appearance/header', [ 'methods' => 'POST', 'callback' => [__CLASS__, 'save_header'], 'permission_callback' => [__CLASS__, 'check_permission'], ]); // Save footer settings register_rest_route(self::API_NAMESPACE, '/appearance/footer', [ 'methods' => 'POST', 'callback' => [__CLASS__, 'save_footer'], 'permission_callback' => [__CLASS__, 'check_permission'], ]); // Save page-specific settings register_rest_route(self::API_NAMESPACE, '/appearance/pages/(?P[a-zA-Z0-9_-]+)', [ 'methods' => 'POST', 'callback' => [__CLASS__, 'save_page_settings'], 'permission_callback' => [__CLASS__, 'check_permission'], 'args' => [ 'page' => [ 'required' => true, 'type' => 'string', 'enum' => ['shop', 'product', 'cart', 'checkout', 'thankyou', 'account'], ], ], ]); } public static function check_permission() { return current_user_can('manage_woocommerce'); } /** * Get all appearance settings */ public static function get_settings(WP_REST_Request $request) { $settings = get_option(self::OPTION_KEY, self::get_default_settings()); return new WP_REST_Response([ 'success' => true, 'data' => $settings, ], 200); } /** * Save general settings */ public static function save_general(WP_REST_Request $request) { $settings = get_option(self::OPTION_KEY, self::get_default_settings()); $general_data = [ 'spa_mode' => sanitize_text_field($request->get_param('spaMode')), 'toast_position' => sanitize_text_field($request->get_param('toastPosition') ?? 'top-right'), 'typography' => [ 'mode' => sanitize_text_field($request->get_param('typography')['mode'] ?? 'predefined'), 'predefined_pair' => sanitize_text_field($request->get_param('typography')['predefined_pair'] ?? 'modern'), 'custom' => [ 'heading' => sanitize_text_field($request->get_param('typography')['custom']['heading'] ?? ''), 'body' => sanitize_text_field($request->get_param('typography')['custom']['body'] ?? ''), ], 'scale' => floatval($request->get_param('typography')['scale'] ?? 1.0), ], 'colors' => [ 'primary' => sanitize_hex_color($request->get_param('colors')['primary'] ?? '#1a1a1a'), 'secondary' => sanitize_hex_color($request->get_param('colors')['secondary'] ?? '#6b7280'), 'accent' => sanitize_hex_color($request->get_param('colors')['accent'] ?? '#3b82f6'), 'text' => sanitize_hex_color($request->get_param('colors')['text'] ?? '#111827'), 'background' => sanitize_hex_color($request->get_param('colors')['background'] ?? '#ffffff'), ], ]; $settings['general'] = $general_data; update_option(self::OPTION_KEY, $settings); return new WP_REST_Response([ 'success' => true, 'message' => 'General settings saved successfully', 'data' => $general_data, ], 200); } /** * Save header settings */ public static function save_header(WP_REST_Request $request) { $settings = get_option(self::OPTION_KEY, self::get_default_settings()); $header_data = [ 'style' => sanitize_text_field($request->get_param('style')), 'sticky' => (bool) $request->get_param('sticky'), 'height' => sanitize_text_field($request->get_param('height')), 'mobile_menu' => sanitize_text_field($request->get_param('mobileMenu')), 'mobile_logo' => sanitize_text_field($request->get_param('mobileLogo')), 'logo_width' => sanitize_text_field($request->get_param('logoWidth') ?? 'auto'), 'logo_height' => sanitize_text_field($request->get_param('logoHeight') ?? '40px'), 'elements' => [ 'logo' => (bool) ($request->get_param('elements')['logo'] ?? true), 'navigation' => (bool) ($request->get_param('elements')['navigation'] ?? true), 'search' => (bool) ($request->get_param('elements')['search'] ?? true), 'account' => (bool) ($request->get_param('elements')['account'] ?? true), 'cart' => (bool) ($request->get_param('elements')['cart'] ?? true), 'wishlist' => (bool) ($request->get_param('elements')['wishlist'] ?? false), ], ]; $settings['header'] = $header_data; update_option(self::OPTION_KEY, $settings); return new WP_REST_Response([ 'success' => true, 'message' => 'Header settings saved successfully', 'data' => $header_data, ], 200); } /** * Save footer settings */ public static function save_footer(WP_REST_Request $request) { $settings = get_option(self::OPTION_KEY, self::get_default_settings()); $social_links = $request->get_param('socialLinks') ?? []; $sanitized_links = []; foreach ($social_links as $link) { $sanitized_links[] = [ 'id' => sanitize_text_field($link['id'] ?? ''), 'platform' => sanitize_text_field($link['platform'] ?? ''), 'url' => esc_url_raw($link['url'] ?? ''), ]; } // Sanitize contact data $contact_data = $request->get_param('contactData'); $sanitized_contact = [ 'email' => sanitize_email($contact_data['email'] ?? ''), 'phone' => sanitize_text_field($contact_data['phone'] ?? ''), 'address' => sanitize_textarea_field($contact_data['address'] ?? ''), 'show_email' => (bool) ($contact_data['show_email'] ?? true), 'show_phone' => (bool) ($contact_data['show_phone'] ?? true), 'show_address' => (bool) ($contact_data['show_address'] ?? true), ]; // Sanitize labels $labels = $request->get_param('labels'); $sanitized_labels = [ 'contact_title' => sanitize_text_field($labels['contact_title'] ?? 'Contact'), 'menu_title' => sanitize_text_field($labels['menu_title'] ?? 'Quick Links'), 'social_title' => sanitize_text_field($labels['social_title'] ?? 'Follow Us'), 'newsletter_title' => sanitize_text_field($labels['newsletter_title'] ?? 'Newsletter'), 'newsletter_description' => sanitize_text_field($labels['newsletter_description'] ?? 'Subscribe to get updates'), ]; // Sanitize custom sections $sections = $request->get_param('sections') ?? []; $sanitized_sections = []; foreach ($sections as $section) { $sanitized_sections[] = [ 'id' => sanitize_text_field($section['id']), 'title' => sanitize_text_field($section['title']), 'type' => sanitize_text_field($section['type']), 'content' => wp_kses_post($section['content'] ?? ''), 'visible' => (bool) ($section['visible'] ?? true), ]; } $footer_data = [ 'columns' => sanitize_text_field($request->get_param('columns')), 'style' => sanitize_text_field($request->get_param('style')), 'copyright_text' => wp_kses_post($request->get_param('copyrightText')), 'elements' => [ 'newsletter' => (bool) ($request->get_param('elements')['newsletter'] ?? true), 'social' => (bool) ($request->get_param('elements')['social'] ?? true), 'payment' => (bool) ($request->get_param('elements')['payment'] ?? true), 'copyright' => (bool) ($request->get_param('elements')['copyright'] ?? true), 'menu' => (bool) ($request->get_param('elements')['menu'] ?? true), 'contact' => (bool) ($request->get_param('elements')['contact'] ?? true), ], 'social_links' => $sanitized_links, 'contact_data' => $sanitized_contact, 'labels' => $sanitized_labels, 'sections' => $sanitized_sections, ]; $settings['footer'] = $footer_data; update_option(self::OPTION_KEY, $settings); return new WP_REST_Response([ 'success' => true, 'message' => 'Footer settings saved successfully', 'data' => $footer_data, ], 200); } /** * Save page-specific settings */ public static function save_page_settings(WP_REST_Request $request) { $settings = get_option(self::OPTION_KEY, self::get_default_settings()); $page = $request->get_param('page'); // Get all parameters from request $page_data = $request->get_json_params(); // Sanitize based on page type $sanitized_data = self::sanitize_page_data($page, $page_data); $settings['pages'][$page] = $sanitized_data; update_option(self::OPTION_KEY, $settings); return new WP_REST_Response([ 'success' => true, 'message' => ucfirst($page) . ' page settings saved successfully', 'data' => $sanitized_data, ], 200); } /** * Sanitize page-specific data */ private static function sanitize_page_data($page, $data) { $sanitized = []; switch ($page) { case 'shop': $sanitized = [ 'layout' => [ 'grid_columns' => sanitize_text_field($data['layout']['grid_columns'] ?? '3'), 'grid_style' => sanitize_text_field($data['layout']['grid_style'] ?? 'standard'), 'card_style' => sanitize_text_field($data['layout']['card_style'] ?? 'card'), 'aspect_ratio' => sanitize_text_field($data['layout']['aspect_ratio'] ?? 'square'), 'card_text_align' => sanitize_text_field($data['layout']['card_text_align'] ?? 'left'), ], 'elements' => [ 'category_filter' => (bool) ($data['elements']['category_filter'] ?? true), 'search_bar' => (bool) ($data['elements']['search_bar'] ?? true), 'sort_dropdown' => (bool) ($data['elements']['sort_dropdown'] ?? true), 'sale_badges' => (bool) ($data['elements']['sale_badges'] ?? true), 'quick_view' => (bool) ($data['elements']['quick_view'] ?? false), ], 'sale_badge' => [ 'color' => sanitize_hex_color($data['sale_badge']['color'] ?? '#ef4444'), ], 'add_to_cart' => [ 'position' => sanitize_text_field($data['add_to_cart']['position'] ?? 'below'), 'style' => sanitize_text_field($data['add_to_cart']['style'] ?? 'solid'), 'show_icon' => (bool) ($data['add_to_cart']['show_icon'] ?? true), ], ]; break; case 'product': $sanitized = [ 'layout' => [ 'image_position' => sanitize_text_field($data['layout']['image_position'] ?? 'left'), 'gallery_style' => sanitize_text_field($data['layout']['gallery_style'] ?? 'thumbnails'), 'sticky_add_to_cart' => (bool) ($data['layout']['sticky_add_to_cart'] ?? false), ], 'elements' => [ 'breadcrumbs' => (bool) ($data['elements']['breadcrumbs'] ?? true), 'related_products' => (bool) ($data['elements']['related_products'] ?? true), 'reviews' => (bool) ($data['elements']['reviews'] ?? true), 'share_buttons' => (bool) ($data['elements']['share_buttons'] ?? false), 'product_meta' => (bool) ($data['elements']['product_meta'] ?? true), ], 'related_products' => [ 'title' => sanitize_text_field($data['related_products']['title'] ?? 'You May Also Like'), ], 'reviews' => [ 'placement' => sanitize_text_field($data['reviews']['placement'] ?? 'product_page'), 'hide_if_empty' => (bool) ($data['reviews']['hide_if_empty'] ?? true), ], ]; break; case 'cart': $sanitized = [ 'layout' => [ 'style' => sanitize_text_field($data['layout']['style'] ?? 'fullwidth'), 'summary_position' => sanitize_text_field($data['layout']['summary_position'] ?? 'right'), ], 'elements' => [ 'product_images' => (bool) ($data['elements']['product_images'] ?? true), 'continue_shopping_button' => (bool) ($data['elements']['continue_shopping_button'] ?? true), 'coupon_field' => (bool) ($data['elements']['coupon_field'] ?? true), 'shipping_calculator' => (bool) ($data['elements']['shipping_calculator'] ?? false), ], ]; break; case 'checkout': $sanitized = [ 'layout' => [ 'style' => sanitize_text_field($data['layout']['style'] ?? 'two-column'), 'order_summary' => sanitize_text_field($data['layout']['order_summary'] ?? 'sidebar'), 'header_visibility' => sanitize_text_field($data['layout']['header_visibility'] ?? 'minimal'), 'footer_visibility' => sanitize_text_field($data['layout']['footer_visibility'] ?? 'minimal'), 'background_color' => sanitize_hex_color($data['layout']['background_color'] ?? '#f9fafb'), ], 'elements' => [ 'order_notes' => (bool) ($data['elements']['order_notes'] ?? true), 'coupon_field' => (bool) ($data['elements']['coupon_field'] ?? true), 'shipping_options' => (bool) ($data['elements']['shipping_options'] ?? true), 'payment_icons' => (bool) ($data['elements']['payment_icons'] ?? true), ], ]; break; case 'thankyou': $sanitized = [ 'template' => sanitize_text_field($data['template'] ?? 'basic'), 'header_visibility' => sanitize_text_field($data['header_visibility'] ?? 'show'), 'footer_visibility' => sanitize_text_field($data['footer_visibility'] ?? 'minimal'), 'background_color' => sanitize_hex_color($data['background_color'] ?? '#f9fafb'), 'custom_message' => wp_kses_post($data['custom_message'] ?? ''), 'elements' => [ 'order_details' => (bool) ($data['elements']['order_details'] ?? true), 'continue_shopping_button' => (bool) ($data['elements']['continue_shopping_button'] ?? true), 'related_products' => (bool) ($data['elements']['related_products'] ?? false), ], ]; break; case 'account': $sanitized = [ 'layout' => [ 'navigation_style' => sanitize_text_field($data['layout']['navigation_style'] ?? 'sidebar'), ], 'elements' => [ 'dashboard' => (bool) ($data['elements']['dashboard'] ?? true), 'orders' => (bool) ($data['elements']['orders'] ?? true), 'downloads' => (bool) ($data['elements']['downloads'] ?? false), 'addresses' => (bool) ($data['elements']['addresses'] ?? true), 'account_details' => (bool) ($data['elements']['account_details'] ?? true), ], ]; break; } return $sanitized; } /** * Get default settings structure */ public static function get_default_settings() { return [ 'general' => [ 'spa_mode' => 'full', 'toast_position' => 'top-right', 'typography' => [ 'mode' => 'predefined', 'predefined_pair' => 'modern', 'custom' => [ 'heading' => '', 'body' => '', ], 'scale' => 1.0, ], 'colors' => [ 'primary' => '#1a1a1a', 'secondary' => '#6b7280', 'accent' => '#3b82f6', 'text' => '#111827', 'background' => '#ffffff', ], ], 'header' => [ 'style' => 'classic', 'sticky' => true, 'height' => 'normal', 'mobile_menu' => 'hamburger', 'mobile_logo' => 'left', 'elements' => [ 'logo' => true, 'navigation' => true, 'search' => true, 'account' => true, 'cart' => true, 'wishlist' => false, ], ], 'footer' => [ 'columns' => '4', 'style' => 'detailed', 'copyright_text' => '© 2024 WooNooW. All rights reserved.', 'elements' => [ 'newsletter' => true, 'social' => true, 'payment' => true, 'copyright' => true, 'menu' => true, 'contact' => true, ], 'social_links' => [], ], 'pages' => [ 'shop' => [ 'layout' => [ 'grid_columns' => '3', 'card_style' => 'card', 'aspect_ratio' => 'square', ], 'elements' => [ 'category_filter' => true, 'search_bar' => true, 'sort_dropdown' => true, 'sale_badges' => true, 'quick_view' => false, ], 'add_to_cart' => [ 'position' => 'below', 'style' => 'solid', 'show_icon' => true, ], ], 'product' => [], 'cart' => [], 'checkout' => [], 'thankyou' => [], 'account' => [], ], ]; } }