diff --git a/includes/Admin/Assets.php b/includes/Admin/Assets.php index e3fc648..ef23565 100644 --- a/includes/Admin/Assets.php +++ b/includes/Admin/Assets.php @@ -39,7 +39,7 @@ class Assets { // Attach runtime config (before module loader runs) // If you prefer, keep using self::localize_runtime($handle) wp_localize_script($handle, 'WNW_API', [ - 'root' => esc_url_raw(rest_url('woonoow/v1/')), + 'root' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))), 'nonce' => wp_create_nonce('wp_rest'), 'isDev' => true, 'devServer' => $dev_url, @@ -48,9 +48,19 @@ class Assets { ]); wp_add_inline_script($handle, 'window.WNW_API = window.WNW_API || WNW_API;', 'after'); + // WNW_CONFIG for compatibility with standalone mode code + wp_localize_script($handle, 'WNW_CONFIG', [ + 'restUrl' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))), + 'nonce' => wp_create_nonce('wp_rest'), + 'standaloneMode' => false, + 'wpAdminUrl' => admin_url('admin.php?page=woonoow'), + 'isAuthenticated' => is_user_logged_in(), + ]); + wp_add_inline_script($handle, 'window.WNW_CONFIG = window.WNW_CONFIG || WNW_CONFIG;', 'after'); + // WordPress REST API settings (for media upload compatibility) wp_localize_script($handle, 'wpApiSettings', [ - 'root' => esc_url_raw(rest_url()), + 'root' => untrailingslashit(esc_url_raw(rest_url())), 'nonce' => wp_create_nonce('wp_rest'), ]); wp_add_inline_script($handle, 'window.wpApiSettings = window.wpApiSettings || wpApiSettings;', 'after'); @@ -134,7 +144,7 @@ class Assets { /** Attach runtime config to a handle */ private static function localize_runtime(string $handle): void { wp_localize_script($handle, 'WNW_API', [ - 'root' => esc_url_raw(rest_url('woonoow/v1/')), + 'root' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))), 'nonce' => wp_create_nonce('wp_rest'), 'isDev' => self::is_dev_mode(), 'devServer' => self::dev_server_url(), @@ -142,9 +152,18 @@ class Assets { 'adminUrl' => admin_url('admin.php'), ]); + // WNW_CONFIG for compatibility with standalone mode code + wp_localize_script($handle, 'WNW_CONFIG', [ + 'restUrl' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))), + 'nonce' => wp_create_nonce('wp_rest'), + 'standaloneMode' => false, + 'wpAdminUrl' => admin_url('admin.php?page=woonoow'), + 'isAuthenticated' => is_user_logged_in(), + ]); + // WordPress REST API settings (for media upload compatibility) wp_localize_script($handle, 'wpApiSettings', [ - 'root' => esc_url_raw(rest_url()), + 'root' => untrailingslashit(esc_url_raw(rest_url())), 'nonce' => wp_create_nonce('wp_rest'), ]); diff --git a/includes/Admin/StandaloneAdmin.php b/includes/Admin/StandaloneAdmin.php index 6de652e..a92b246 100644 --- a/includes/Admin/StandaloneAdmin.php +++ b/includes/Admin/StandaloneAdmin.php @@ -57,7 +57,7 @@ class StandaloneAdmin { // Get nonce for REST API $nonce = wp_create_nonce( 'wp_rest' ); - $rest_url = rest_url( 'woonoow/v1' ); + $rest_url = untrailingslashit( rest_url( 'woonoow/v1' ) ); $wp_admin_url = admin_url( 'admin.php?page=woonoow' ); // Get current user data if authenticated @@ -134,6 +134,9 @@ class StandaloneAdmin { // WooCommerce store settings (currency, formatting, etc.) window.WNW_STORE = ; + + // Navigation tree (single source of truth from PHP) + window.WNW_NAV_TREE = ; diff --git a/includes/Core/Bootstrap.php b/includes/Core/Bootstrap.php index 93d4928..c2c8fcb 100644 --- a/includes/Core/Bootstrap.php +++ b/includes/Core/Bootstrap.php @@ -18,6 +18,7 @@ use WooNooW\Api\Routes; use WooNooW\Core\Mail\MailQueue; use WooNooW\Core\Mail\WooEmailOverride; use WooNooW\Core\DataStores\OrderStore; +use WooNooW\Core\MediaUpload; use WooNooW\Branding; class Bootstrap { @@ -28,6 +29,7 @@ class Bootstrap { Assets::init(); StandaloneAdmin::init(); Branding::init(); + MediaUpload::init(); // Addon system (order matters: Registry → Routes → Navigation) AddonRegistry::init(); diff --git a/includes/Core/MediaUpload.php b/includes/Core/MediaUpload.php new file mode 100644 index 0000000..9e556bb --- /dev/null +++ b/includes/Core/MediaUpload.php @@ -0,0 +1,107 @@ +