feat: Add product images support with WP Media Library integration

- Add WP Media Library integration for product and variation images
- Support images array (URLs) conversion to attachment IDs
- Add images array to API responses (Admin & Customer SPA)
- Implement drag-and-drop sortable images in Admin product form
- Add image gallery thumbnails in Customer SPA product page
- Initialize WooCommerce session for guest cart operations
- Fix product variations and attributes display in Customer SPA
- Add variation image field in Admin SPA

Changes:
- includes/Api/ProductsController.php: Handle images array, add to responses
- includes/Frontend/ShopController.php: Add images array for customer SPA
- includes/Frontend/CartController.php: Initialize WC session for guests
- admin-spa/src/lib/wp-media.ts: Add openWPMediaGallery function
- admin-spa/src/routes/Products/partials/tabs/GeneralTab.tsx: WP Media + sortable images
- admin-spa/src/routes/Products/partials/tabs/VariationsTab.tsx: Add variation image field
- customer-spa/src/pages/Product/index.tsx: Add gallery thumbnails display
This commit is contained in:
Dwindi Ramadhana
2025-11-26 16:18:43 +07:00
parent 909bddb23d
commit f397ef850f
69 changed files with 12481 additions and 156 deletions

View File

@@ -0,0 +1,110 @@
<?php
namespace WooNooW\Frontend;
/**
* Shortcodes Manager
* Handles WooNooW customer-facing shortcodes
*/
class Shortcodes {
/**
* Initialize
*/
public static function init() {
add_shortcode('woonoow_shop', [__CLASS__, 'shop_shortcode']);
add_shortcode('woonoow_cart', [__CLASS__, 'cart_shortcode']);
add_shortcode('woonoow_checkout', [__CLASS__, 'checkout_shortcode']);
add_shortcode('woonoow_account', [__CLASS__, 'account_shortcode']);
}
/**
* Shop shortcode
* Usage: [woonoow_shop]
*/
public static function shop_shortcode($atts) {
$atts = shortcode_atts([
'category' => '',
'per_page' => 12,
], $atts);
ob_start();
?>
<div id="woonoow-customer-app" data-page="shop" data-category="<?php echo esc_attr($atts['category']); ?>" data-per-page="<?php echo esc_attr($atts['per_page']); ?>">
<!-- Customer SPA will mount here -->
<div class="woonoow-loading">
<p><?php esc_html_e('Loading shop...', 'woonoow'); ?></p>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* Cart shortcode
* Usage: [woonoow_cart]
*/
public static function cart_shortcode($atts) {
ob_start();
?>
<div id="woonoow-customer-app" data-page="cart">
<!-- Customer SPA will mount here -->
<div class="woonoow-loading">
<p><?php esc_html_e('Loading cart...', 'woonoow'); ?></p>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* Checkout shortcode
* Usage: [woonoow_checkout]
*/
public static function checkout_shortcode($atts) {
// Require user to be logged in for checkout
if (!is_user_logged_in()) {
return '<div class="woonoow-notice">' .
'<p>' . esc_html__('Please log in to proceed to checkout.', 'woonoow') . '</p>' .
'<a href="' . esc_url(wp_login_url(get_permalink())) . '" class="button">' .
esc_html__('Log In', 'woonoow') . '</a>' .
'</div>';
}
ob_start();
?>
<div id="woonoow-customer-app" data-page="checkout">
<!-- Customer SPA will mount here -->
<div class="woonoow-loading">
<p><?php esc_html_e('Loading checkout...', 'woonoow'); ?></p>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* Account shortcode
* Usage: [woonoow_account]
*/
public static function account_shortcode($atts) {
// Require user to be logged in
if (!is_user_logged_in()) {
return '<div class="woonoow-notice">' .
'<p>' . esc_html__('Please log in to view your account.', 'woonoow') . '</p>' .
'<a href="' . esc_url(wp_login_url(get_permalink())) . '" class="button">' .
esc_html__('Log In', 'woonoow') . '</a>' .
'</div>';
}
ob_start();
?>
<div id="woonoow-customer-app" data-page="account">
<!-- Customer SPA will mount here -->
<div class="woonoow-loading">
<p><?php esc_html_e('Loading account...', 'woonoow'); ?></p>
</div>
</div>
<?php
return ob_get_clean();
}
}