fix: Critical fixes for shipping and meta field registration

Issue 1: Shipping recalculation on order edit (FIXED)
- Problem: OrderForm recalculated shipping on every edit
- Expected: Shipping should be fixed unless address changes
- Solution: Use existing order.totals.shipping in edit mode
- Create mode: Still calculates from shipping method

Issue 2: Meta fields not appearing without data (DOCUMENTED)
- Problem: Private meta fields dont appear if no data exists yet
- Example: Admin cannot input tracking number on first time
- Root cause: Fields only exposed if data exists in database
- Solution: Plugins MUST register fields via MetaFieldsRegistry
- Registration makes field available even when empty

Updated METABOX_COMPAT.md:
- Changed optional to REQUIRED for field registration
- Added critical warning section
- Explained private vs public meta behavior
- Private meta: MUST register to appear
- Public meta: Auto-exposed, no registration needed

The Flow (Corrected):
1. Plugin registers field -> Field appears in UI (even empty)
2. Admin inputs data -> Saved to database
3. Data visible in both admins

Without Registration:
- Private meta (_field): Not exposed, not editable
- Public meta (field): Auto-exposed, auto-editable

Why Private Meta Requires Registration:
- Security: Hidden by default
- Privacy: Prevents exposing sensitive data
- Control: Plugins explicitly declare visibility

Files Changed:
- OrderForm.tsx: Use existing shipping total in edit mode
- METABOX_COMPAT.md: Critical documentation updates

Result:
- Shipping no longer recalculates on edit
- Clear documentation on field registration requirement
- Developers know they MUST register private meta fields
This commit is contained in:
dwindown
2025-11-20 12:53:55 +07:00
parent dd8df3ae80
commit afb54b962e
2 changed files with 44 additions and 6 deletions

View File

@@ -604,7 +604,7 @@ update_post_meta($order_id, '_tracking_number', '1234567890');
update_post_meta($order_id, '_tracking_provider', 'JNE');
```
**Plugin registers fields for WooNooW (optional, for better UX):**
**Plugin registers fields for WooNooW (REQUIRED for UI display):**
```php
// In plugin's main file or init hook
add_action('woonoow/register_meta_fields', function() {
@@ -649,7 +649,7 @@ update_field('custom_field', 'value', $product_id);
// Stored as: update_post_meta($product_id, 'custom_field', 'value');
```
**Register for WooNooW (optional):**
**Register for WooNooW (REQUIRED for UI display):**
```php
add_action('woonoow/register_meta_fields', function() {
\WooNooW\Compat\MetaFieldsRegistry::register_product_field('custom_field', [
@@ -666,7 +666,7 @@ add_action('woonoow/register_meta_fields', function() {
- ✅ Synced with ACF
- ✅ Works with both admins
### Example 3: Custom Plugin (No Registration)
### Example 3: Public Meta (Auto-Exposed, No Registration Needed)
**Plugin stores data:**
```php
@@ -793,10 +793,41 @@ MetaFieldsRegistry::register_order_field('_field_name', [
**For Plugin Developers:**
1. ✅ Continue using standard WP/WooCommerce meta storage
2.Optionally register fields for better UX
3.No special integration needed
2.**MUST register private meta fields** (starting with `_`) for UI display
3.Public meta (no `_`) auto-exposed, no registration needed
4. ✅ Works with both classic and WooNooW admin
**⚠️ CRITICAL: Private Meta Field Registration**
Private meta fields (starting with `_`) **MUST be registered** to appear in WooNooW UI:
**Why?**
- Security: Private meta is hidden by default
- Privacy: Prevents exposing sensitive data
- Control: Plugins explicitly declare what should be visible
**The Flow:**
1. Plugin registers field → Field appears in UI (even if empty)
2. Admin inputs data → Saved to database
3. Data visible in both admins
**Without Registration:**
- Private meta: ❌ Not exposed, not editable
- Public meta: ✅ Auto-exposed, auto-editable
**Example:**
```php
// This field will NOT appear without registration
update_post_meta($order_id, '_tracking_number', '123');
// Register it to make it appear
add_action('woonoow/register_meta_fields', function() {
MetaFieldsRegistry::register_order_field('_tracking_number', [...]);
});
// Now admin can see and edit it, even when empty!
```
**For WooNooW Core:**
1. ✅ Zero addon dependencies
2. ✅ Provides mechanism, not integration

View File

@@ -314,11 +314,18 @@ export default function OrderForm({
);
// Calculate shipping cost
// In edit mode: use existing order shipping total (fixed unless address changes)
// In create mode: calculate from selected shipping method
const shippingCost = React.useMemo(() => {
if (mode === 'edit' && initial?.totals?.shipping !== undefined) {
// Use existing shipping total from order
return Number(initial.totals.shipping) || 0;
}
// Create mode: calculate from shipping method
if (!shippingMethod) return 0;
const method = shippings.find(s => s.id === shippingMethod);
return method ? Number(method.cost) || 0 : 0;
}, [shippingMethod, shippings]);
}, [mode, initial?.totals?.shipping, shippingMethod, shippings]);
// Calculate discount from validated coupons
const couponDiscount = React.useMemo(() => {