1. Updated PROJECT_SOP.md: ✅ Added mobile card linkable pattern with full example ✅ Added submenu mobile hiding rules and behavior matrix ✅ Documented stopPropagation pattern for checkboxes ✅ Added ChevronRight icon requirement ✅ Documented active:scale animation for tap feedback ✅ Added spacing rules (space-y-3 for cards) 2. Created CUSTOMER_DATA_FLOW_ANALYSIS.md: ✅ Comprehensive analysis of customer data flow ✅ Documented 2 customer types: Guest vs Site Member ✅ Identified validation issues in OrdersController ✅ Found weak ! empty() checks allowing bad data ✅ Documented inconsistent validation between controllers ✅ Created action items for fixes ✅ Added test cases for all scenarios Key Findings: ❌ OrdersController uses ! empty() - allows 'Indonesia' string ❌ No phone number sanitization in order creation ❌ No validation that phone is actually a phone number ✅ CustomersController has better validation (isset + sanitize) Next: Investigate source of 'Indonesia' value and implement fixes
8.4 KiB
Customer Data Flow Analysis
Issue Report
Problem: Customer billing_phone shows "Indonesia" instead of phone number
Source: Customer created via Order module
Impact: Incorrect customer data stored in database
Data Flow Investigation
A. Customer as Guest (Not Site Member)
1. Order Creation Flow
File: OrdersController.php → create_order() method
Steps:
- Order form submits billing data including
phone - Data flows through
$billing['phone']parameter - Order billing is set via
$order->set_billing_phone($billing['phone']) - No WC_Customer object created - guest orders only store data in order meta
Code Location: Lines 780-1120
// Guest customer - data only in order
$order->set_billing_first_name($billing['first_name'] ?? '');
$order->set_billing_last_name($billing['last_name'] ?? '');
$order->set_billing_email($billing['email'] ?? '');
$order->set_billing_phone($billing['phone'] ?? ''); // ← Data here
// ... more fields
Issue: Guest customers don't have WC_Customer records, so viewing them in Customer module will fail or show incorrect data.
B. Customer as Site Member
1. Existing Member - Order Creation
File: OrdersController.php → Lines 1020-1064
Flow:
- User exists, found by email
- Upgrade subscriber to customer role (if needed)
- Create
WC_Customerobject - Update customer data from order billing/shipping
- Save customer
- Link order to customer
Code:
if ($user) {
// Upgrade role if needed
if (in_array('subscriber', (array) $user->roles, true)) {
$user->set_role('customer');
}
// Update customer billing & shipping data
$customer = new \WC_Customer($user->ID);
// Update billing address
if (! empty($billing['first_name'])) $customer->set_billing_first_name($billing['first_name']);
if (! empty($billing['last_name'])) $customer->set_billing_last_name($billing['last_name']);
if (! empty($billing['email'])) $customer->set_billing_email($billing['email']);
if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']); // ← HERE
// ... more fields
$customer->save();
}
Validation: Uses ! empty() check
Problem: If $billing['phone'] contains "Indonesia" (non-empty string), it will be saved!
2. New Member - Auto-Registration
File: OrdersController.php → Lines 1065-1118
Flow:
- User doesn't exist
- Auto-register setting is ON
- Create WordPress user
- Create
WC_Customerobject - Set billing/shipping from order data
- Save customer
- Send welcome email
Code:
elseif ($register_member) {
// Create user
$user_id = wp_insert_user($userdata);
if (!is_wp_error($user_id)) {
$customer = new \WC_Customer($user_id);
// Billing address
if (! empty($billing['first_name'])) $customer->set_billing_first_name($billing['first_name']);
// ...
if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']); // ← HERE
// ...
$customer->save();
}
}
Same Issue: ! empty() check allows "Indonesia" to be saved.
C. Customer Module Direct Edit
File: CustomersController.php → update_customer() method (Lines 232-310)
Flow:
- Receive customer data via PUT request
- Update WordPress user meta
- Update
WC_Customerbilling/shipping - Save customer
Code:
$customer = new WC_Customer($id);
// Billing address
if (!empty($data['billing'])) {
$billing = $data['billing'];
if (isset($billing['first_name'])) $customer->set_billing_first_name(...);
// ...
if (isset($billing['phone'])) $customer->set_billing_phone(sanitize_text_field($billing['phone']));
// ...
}
$customer->save();
Validation: Uses isset() check (better than ! empty())
Sanitization: Uses sanitize_text_field() ✅
Root Cause Analysis
Possible Sources of "Indonesia" Value
-
Frontend Default Value
- Check
OrderForm.tsxfor default country/phone values - Check if "Indonesia" is being set as placeholder or default
- Check
-
Backend Fallback
- Check if WooCommerce has default country settings
- Check if there's a fallback to country name instead of phone
-
Data Validation Issue
! empty()check allows ANY non-empty string- No validation that phone is actually a phone number
- No sanitization before saving
-
Virtual Products Case
- When cart has only virtual products, address fields are hidden
- Phone field might still be submitted with wrong value
Issues Found
1. ❌ Weak Validation in OrdersController
Problem:
if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']);
! empty()allows "Indonesia", "test", "abc", etc.- No phone number format validation
- No sanitization
Should Be:
if (isset($billing['phone']) && $billing['phone'] !== '') {
$customer->set_billing_phone(sanitize_text_field($billing['phone']));
}
2. ❌ No Data Sanitization in Order Creation
Problem:
- Direct assignment without sanitization
- Allows any string value
- No format validation
Should Add:
sanitize_text_field()for all text fields- Phone number format validation
- Empty string handling
3. ❌ Inconsistent Validation Between Controllers
OrdersController:
- Uses
! empty()check - No sanitization
CustomersController:
- Uses
isset()check ✅ - Has
sanitize_text_field()✅
Should: Use same validation pattern everywhere
4. ❌ Virtual Products Address Handling
Current Behavior:
- Frontend hides address fields for virtual products
- But phone field is ALWAYS shown
- Backend might receive wrong data
Check:
- OrderForm.tsx line 1023:
setBPhone(data.billing.phone || ''); - Does this fallback to something else?
Action Items
1. Fix OrdersController Validation
File: OrdersController.php
Lines: 1039-1047, 1088-1096
Change:
// OLD (Lines 1042)
if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']);
// NEW
if (isset($billing['phone']) && trim($billing['phone']) !== '') {
$customer->set_billing_phone(sanitize_text_field($billing['phone']));
}
Apply to:
- Existing member update (lines 1039-1047)
- New member creation (lines 1088-1096)
2. Add Phone Number Validation
Create Helper Function:
private static function sanitize_phone($phone) {
if (empty($phone)) {
return '';
}
// Remove non-numeric characters except + and spaces
$phone = preg_replace('/[^0-9+\s-]/', '', $phone);
// Trim whitespace
$phone = trim($phone);
// If result is empty or just symbols, return empty
if (empty($phone) || preg_match('/^[+\s-]+$/', $phone)) {
return '';
}
return $phone;
}
3. Check Frontend Data Source
File: OrderForm.tsx
Line: ~1023
Check:
- Where does
data.billing.phonecome from? - Is there a default value being set?
- Is "Indonesia" coming from country field?
4. Test Cases
A. Guest Customer:
- Create order with phone = "08123456789"
- Check order billing_phone
- Verify no WC_Customer created
B. Existing Member:
- Create order with existing customer
- Phone = "08123456789"
- Check WC_Customer billing_phone updated
- Create another order with same customer
- Phone = "08198765432"
- Verify WC_Customer phone updated to new value
C. New Member (Auto-register):
- Create order with new email
- Auto-register ON
- Phone = "08123456789"
- Verify WC_Customer created with correct phone
D. Virtual Products:
- Create order with only virtual products
- Verify phone field behavior
- Check what value is submitted
Expected Behavior
Order Creation with Existing Member
- Order billing data should update WC_Customer data
- Phone should be validated and sanitized
- Empty phone should clear WC_Customer phone (not set to country name)
Order Creation with New Member
- WC_Customer should be created with correct data
- Phone should be validated and sanitized
- No fallback to country name
Virtual Products
- Phone field should still work correctly
- No address fields needed
- Phone should not default to country name
Next Steps
- ✅ Update PROJECT_SOP.md with mobile UX patterns
- 🔄 Find source of "Indonesia" value
- ⏳ Fix validation in OrdersController
- ⏳ Add phone sanitization helper
- ⏳ Test all scenarios
- ⏳ Document fix in commit message