fix: licensing table creation, consistent meta keys, checkout virtual detection

1. License table auto-creation:
   - Added ensure_tables() check on plugins_loaded
   - Tables created automatically if missing

2. Consistent licensing meta keys:
   - ProductsController now uses _woonoow_licensing_enabled
   - Matches LicensingModule and LicenseManager

3. Checkout virtual-only detection:
   - Added needs_shipping to Cart interface
   - Checkout uses cart.needs_shipping from WooCommerce API
   - Fallback to item-level virtual/downloadable check

4. Login redirect for logged-in users added previously
This commit is contained in:
Dwindi Ramadhana
2026-01-07 22:15:51 +07:00
parent f334e018fa
commit 2cc20ff760
5 changed files with 32 additions and 10 deletions

View File

@@ -20,6 +20,7 @@ export interface Cart {
tax: number; tax: number;
shipping: number; shipping: number;
total: number; total: number;
needs_shipping?: boolean;
coupon?: { coupon?: {
code: string; code: string;
discount: number; discount: number;

View File

@@ -41,11 +41,17 @@ export default function Checkout() {
const [discountTotal, setDiscountTotal] = useState(0); const [discountTotal, setDiscountTotal] = useState(0);
const user = (window as any).woonoowCustomer?.user; const user = (window as any).woonoowCustomer?.user;
// Check if cart contains only virtual/downloadable products // Check if cart needs shipping (virtual-only carts don't need shipping)
// Use cart.needs_shipping from WooCommerce API, fallback to item-level check
const isVirtualOnly = React.useMemo(() => { const isVirtualOnly = React.useMemo(() => {
// Prefer the needs_shipping flag from the cart API ( WooCommerce calculates this properly)
if (typeof cart.needs_shipping === 'boolean') {
return !cart.needs_shipping;
}
// Fallback: check individual items if needs_shipping not available
if (cart.items.length === 0) return false; if (cart.items.length === 0) return false;
return cart.items.every(item => item.virtual || item.downloadable); return cart.items.every(item => item.virtual || item.downloadable);
}, [cart.items]); }, [cart.items, cart.needs_shipping]);
// Calculate totals // Calculate totals
const subtotal = cart.items.reduce((sum, item) => sum + (item.price * item.quantity), 0); const subtotal = cart.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);

View File

@@ -415,13 +415,13 @@ class ProductsController {
// Licensing meta // Licensing meta
if (isset($data['licensing_enabled'])) { if (isset($data['licensing_enabled'])) {
update_post_meta($product->get_id(), '_licensing_enabled', $data['licensing_enabled'] ? 'yes' : 'no'); update_post_meta($product->get_id(), '_woonoow_licensing_enabled', $data['licensing_enabled'] ? 'yes' : 'no');
} }
if (isset($data['license_activation_limit'])) { if (isset($data['license_activation_limit'])) {
update_post_meta($product->get_id(), '_license_activation_limit', self::sanitize_number($data['license_activation_limit'])); update_post_meta($product->get_id(), '_woonoow_license_activation_limit', self::sanitize_number($data['license_activation_limit']));
} }
if (isset($data['license_duration_days'])) { if (isset($data['license_duration_days'])) {
update_post_meta($product->get_id(), '_license_duration_days', self::sanitize_number($data['license_duration_days'])); update_post_meta($product->get_id(), '_woonoow_license_expiry_days', self::sanitize_number($data['license_duration_days']));
} }
// Handle variations for variable products // Handle variations for variable products
@@ -559,13 +559,13 @@ class ProductsController {
// Licensing meta // Licensing meta
if (isset($data['licensing_enabled'])) { if (isset($data['licensing_enabled'])) {
update_post_meta($product->get_id(), '_licensing_enabled', $data['licensing_enabled'] ? 'yes' : 'no'); update_post_meta($product->get_id(), '_woonoow_licensing_enabled', $data['licensing_enabled'] ? 'yes' : 'no');
} }
if (isset($data['license_activation_limit'])) { if (isset($data['license_activation_limit'])) {
update_post_meta($product->get_id(), '_license_activation_limit', self::sanitize_number($data['license_activation_limit'])); update_post_meta($product->get_id(), '_woonoow_license_activation_limit', self::sanitize_number($data['license_activation_limit']));
} }
if (isset($data['license_duration_days'])) { if (isset($data['license_duration_days'])) {
update_post_meta($product->get_id(), '_license_duration_days', self::sanitize_number($data['license_duration_days'])); update_post_meta($product->get_id(), '_woonoow_license_expiry_days', self::sanitize_number($data['license_duration_days']));
} }
// Allow plugins to perform additional updates (Level 1 compatibility) // Allow plugins to perform additional updates (Level 1 compatibility)
@@ -761,7 +761,7 @@ class ProductsController {
} }
// Licensing fields // Licensing fields
$data['licensing_enabled'] = get_post_meta($product->get_id(), '_licensing_enabled', true) === 'yes'; $data['licensing_enabled'] = get_post_meta($product->get_id(), '_woonoow_licensing_enabled', true) === 'yes';
$data['license_activation_limit'] = get_post_meta($product->get_id(), '_license_activation_limit', true) ?: ''; $data['license_activation_limit'] = get_post_meta($product->get_id(), '_license_activation_limit', true) ?: '';
$data['license_duration_days'] = get_post_meta($product->get_id(), '_license_duration_days', true) ?: ''; $data['license_duration_days'] = get_post_meta($product->get_id(), '_license_duration_days', true) ?: '';

View File

@@ -96,7 +96,7 @@ class LicenseManager {
if (!$product) continue; if (!$product) continue;
// Check if product has licensing enabled // Check if product has licensing enabled
$licensing_enabled = get_post_meta($product_id, '_licensing_enabled', true); $licensing_enabled = get_post_meta($product_id, '_woonoow_licensing_enabled', true);
if ($licensing_enabled !== 'yes') continue; if ($licensing_enabled !== 'yes') continue;
// Check if license already exists for this order item // Check if license already exists for this order item

View File

@@ -37,10 +37,25 @@ class LicensingModule {
*/ */
public static function maybe_init_manager() { public static function maybe_init_manager() {
if (ModuleRegistry::is_enabled('licensing')) { if (ModuleRegistry::is_enabled('licensing')) {
// Ensure tables exist
self::ensure_tables();
LicenseManager::init(); LicenseManager::init();
} }
} }
/**
* Ensure database tables exist
*/
private static function ensure_tables() {
global $wpdb;
$table = $wpdb->prefix . 'woonoow_licenses';
// Check if table exists
if ($wpdb->get_var("SHOW TABLES LIKE '$table'") !== $table) {
LicenseManager::create_tables();
}
}
/** /**
* Handle module enable * Handle module enable
*/ */