## ✅ Issue 1: Single Source of Truth for Navigation **Problem:** Confusing dual nav sources (PHP + TypeScript fallback) **Solution:** Removed static TypeScript fallback tree **Result:** PHP NavigationRegistry is now the ONLY source - More flexible (can check WooCommerce settings, extend via addons) - Easier to maintain - Clear error if backend data missing ## ✅ Issue 2: Logo in All Modes **Already Working:** Header component renders in all modes - Standalone ✅ - WP-Admin normal ✅ - WP-Admin fullscreen ✅ ## ✅ Issue 5: Customer Settings 404 Debug **Added:** Debug logging to track endpoint calls **Note:** Routes are correctly registered - May need WordPress permalinks flush - Check debug.log for errors ## ✅ Issue 6: Dark Mode Logo Support **Implemented:** 1. **Backend:** - Added `store_logo_dark` to branding endpoint - Returns both light and dark logos 2. **Header Component:** - Detects dark mode via MutationObserver - Switches logo based on theme - Falls back to light logo if dark not set 3. **Login Screen:** - Same dark mode detection - Theme-aware logo display - Seamless theme switching 4. **SVG Support:** - Already supported via `accept="image/*"` - Works for all image formats **Result:** Perfect dark/light logo switching everywhere! 🌓 --- ## Files Modified: - `nav/tree.ts` - Removed static fallback - `App.tsx` - Dark logo in header - `Login.tsx` - Dark logo in login - `StoreController.php` - Dark logo in branding endpoint + debug logs - `Store.tsx` - Already has dark logo upload field - `StoreSettingsProvider.php` - Already has dark logo backend ## Testing: 1. Upload dark logo in Store settings 2. Switch theme - logo should change 3. Check customer-settings endpoint in browser console 4. Verify nav items from PHP only
346 lines
11 KiB
PHP
346 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Store REST API Controller
|
|
*
|
|
* Provides REST endpoints for store settings management.
|
|
*
|
|
* @package WooNooW
|
|
*/
|
|
|
|
namespace WooNooW\API;
|
|
|
|
use WooNooW\Compat\StoreSettingsProvider;
|
|
use WooNooW\Compat\CustomerSettingsProvider;
|
|
use WP_REST_Controller;
|
|
use WP_REST_Server;
|
|
use WP_REST_Request;
|
|
use WP_REST_Response;
|
|
use WP_Error;
|
|
|
|
class StoreController extends WP_REST_Controller {
|
|
|
|
/**
|
|
* Namespace
|
|
*/
|
|
protected $namespace = 'woonoow/v1';
|
|
|
|
/**
|
|
* Rest base
|
|
*/
|
|
protected $rest_base = 'store';
|
|
|
|
/**
|
|
* Register routes
|
|
*/
|
|
public function register_routes() {
|
|
// GET /woonoow/v1/store/branding (PUBLIC - for login page)
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/branding', [
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [$this, 'get_branding'],
|
|
'permission_callback' => '__return_true', // Public endpoint
|
|
],
|
|
]);
|
|
|
|
// GET /woonoow/v1/store/settings
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/settings', [
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [$this, 'get_settings'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
|
|
// POST /woonoow/v1/store/settings
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/settings', [
|
|
[
|
|
'methods' => WP_REST_Server::EDITABLE,
|
|
'callback' => [$this, 'save_settings'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
|
|
// GET /woonoow/v1/store/countries
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/countries', [
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [$this, 'get_countries'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
|
|
// GET /woonoow/v1/store/timezones
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/timezones', [
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [$this, 'get_timezones'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
|
|
// GET /woonoow/v1/store/currencies
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/currencies', [
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [$this, 'get_currencies'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
|
|
// GET /woonoow/v1/store/customer-settings
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/customer-settings', [
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [$this, 'get_customer_settings'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
|
|
// POST /woonoow/v1/store/customer-settings
|
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/customer-settings', [
|
|
[
|
|
'methods' => WP_REST_Server::EDITABLE,
|
|
'callback' => [$this, 'save_customer_settings'],
|
|
'permission_callback' => [$this, 'check_permission'],
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get store branding (PUBLIC - for login page)
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response Response object
|
|
*/
|
|
public function get_branding(WP_REST_Request $request) {
|
|
$branding = [
|
|
'store_name' => get_option('woonoow_store_name', '') ?: get_option('blogname', 'WooNooW'),
|
|
'store_logo' => get_option('woonoow_store_logo', ''),
|
|
'store_logo_dark' => get_option('woonoow_store_logo_dark', ''),
|
|
'store_icon' => get_option('woonoow_store_icon', ''),
|
|
'store_tagline' => get_option('woonoow_store_tagline', ''),
|
|
];
|
|
|
|
$response = rest_ensure_response($branding);
|
|
$response->header('Cache-Control', 'max-age=300'); // Cache for 5 minutes
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Get store settings
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function get_settings(WP_REST_Request $request) {
|
|
try {
|
|
$settings = StoreSettingsProvider::get_settings();
|
|
|
|
$response = rest_ensure_response($settings);
|
|
$response->header('Cache-Control', 'max-age=60');
|
|
|
|
return $response;
|
|
} catch (\Exception $e) {
|
|
return new WP_Error(
|
|
'get_settings_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save store settings
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function save_settings(WP_REST_Request $request) {
|
|
$settings = $request->get_json_params();
|
|
|
|
if (empty($settings)) {
|
|
return new WP_Error(
|
|
'missing_settings',
|
|
'No settings provided',
|
|
['status' => 400]
|
|
);
|
|
}
|
|
|
|
try {
|
|
$result = StoreSettingsProvider::save_settings($settings);
|
|
|
|
if (!$result) {
|
|
return new WP_Error(
|
|
'save_failed',
|
|
'Failed to save settings',
|
|
['status' => 500]
|
|
);
|
|
}
|
|
|
|
return rest_ensure_response([
|
|
'success' => true,
|
|
'message' => 'Settings saved successfully',
|
|
'settings' => StoreSettingsProvider::get_settings(),
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return new WP_Error(
|
|
'save_settings_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get countries
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function get_countries(WP_REST_Request $request) {
|
|
try {
|
|
$countries = StoreSettingsProvider::get_countries();
|
|
|
|
$response = rest_ensure_response($countries);
|
|
$response->header('Cache-Control', 'max-age=3600'); // Cache for 1 hour
|
|
|
|
return $response;
|
|
} catch (\Exception $e) {
|
|
return new WP_Error(
|
|
'get_countries_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get timezones
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function get_timezones(WP_REST_Request $request) {
|
|
try {
|
|
$timezones = StoreSettingsProvider::get_timezones();
|
|
|
|
$response = rest_ensure_response($timezones);
|
|
$response->header('Cache-Control', 'max-age=3600'); // Cache for 1 hour
|
|
|
|
return $response;
|
|
} catch (\Exception $e) {
|
|
return new WP_Error(
|
|
'get_timezones_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get currencies
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function get_currencies(WP_REST_Request $request) {
|
|
try {
|
|
$currencies = StoreSettingsProvider::get_currencies();
|
|
|
|
$response = rest_ensure_response($currencies);
|
|
$response->header('Cache-Control', 'max-age=3600'); // Cache for 1 hour
|
|
|
|
return $response;
|
|
} catch (\Exception $e) {
|
|
return new WP_Error(
|
|
'get_currencies_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get customer settings
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function get_customer_settings(WP_REST_Request $request) {
|
|
error_log('WooNooW: get_customer_settings called');
|
|
try {
|
|
$settings = CustomerSettingsProvider::get_settings();
|
|
error_log('WooNooW: Customer settings retrieved: ' . print_r($settings, true));
|
|
|
|
$response = rest_ensure_response($settings);
|
|
$response->header('Cache-Control', 'max-age=60');
|
|
|
|
return $response;
|
|
} catch (\Exception $e) {
|
|
error_log('WooNooW: get_customer_settings exception: ' . $e->getMessage());
|
|
return new WP_Error(
|
|
'get_customer_settings_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save customer settings
|
|
*
|
|
* @param WP_REST_Request $request Request object
|
|
* @return WP_REST_Response|WP_Error Response object or error
|
|
*/
|
|
public function save_customer_settings(WP_REST_Request $request) {
|
|
try {
|
|
$settings = $request->get_json_params();
|
|
|
|
if (empty($settings)) {
|
|
return new WP_Error(
|
|
'invalid_settings',
|
|
__('Invalid settings data', 'woonoow'),
|
|
['status' => 400]
|
|
);
|
|
}
|
|
|
|
$updated = CustomerSettingsProvider::update_settings($settings);
|
|
|
|
if (!$updated) {
|
|
return new WP_Error(
|
|
'update_failed',
|
|
__('Failed to update customer settings', 'woonoow'),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
|
|
// Return updated settings
|
|
$new_settings = CustomerSettingsProvider::get_settings();
|
|
|
|
return new WP_REST_Response([
|
|
'success' => true,
|
|
'message' => __('Customer settings updated successfully', 'woonoow'),
|
|
'settings' => $new_settings,
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return new WP_Error(
|
|
'save_customer_settings_failed',
|
|
$e->getMessage(),
|
|
['status' => 500]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if user has permission
|
|
*
|
|
* @return bool True if user has permission
|
|
*/
|
|
public function check_permission() {
|
|
// Check WooCommerce capability first, fallback to manage_options
|
|
return current_user_can('manage_woocommerce') || current_user_can('manage_options');
|
|
}
|
|
}
|