feat: Phase 1 - Backend API meta compatibility (Level 1)

**Implemented: Backend API Enhancement for Level 1 Compatibility**

Following IMPLEMENTATION_PLAN_META_COMPAT.md Phase 1

**OrdersController.php:**
 Added get_order_meta_data() - Expose meta in API responses
 Added update_order_meta_data() - Update meta from API
 Modified show() - Include meta in response
 Modified update() - Handle meta updates
 Added filter: woonoow/order_allowed_private_meta
 Added filter: woonoow/order_updatable_meta
 Added filter: woonoow/order_api_data
 Added action: woonoow/order_updated

**ProductsController.php:**
 Added get_product_meta_data() - Expose meta in API responses
 Added update_product_meta_data() - Update meta from API
 Modified format_product_full() - Include meta in response
 Modified update_product() - Handle meta updates
 Added filter: woonoow/product_allowed_private_meta
 Added filter: woonoow/product_updatable_meta
 Added filter: woonoow/product_api_data
 Added action: woonoow/product_updated

**Meta Filtering Logic:**
- Skip internal WooCommerce meta (_wc_*)
- Skip WooNooW internal meta (_woonoow_*)
- Public meta (no underscore) - always expose
- Private meta (starts with _) - check allowed list
- Plugins can add to allowed list via filters

**Default Allowed Meta (Orders):**
- _tracking_number
- _tracking_provider
- _tracking_url
- _shipment_tracking_items
- _wc_shipment_tracking_items
- _transaction_id
- _payment_method_title

**How It Works:**
1. Plugin stores: update_post_meta($order_id, '_tracking_number', '123')
2. WooNooW API exposes: GET /orders/123 returns meta._tracking_number
3. Frontend can read/write via API
4. Plugin works WITHOUT any extra effort

**Next Steps:**
- Phase 2: Frontend components (MetaFields, useMetaFields)
- Phase 3: PHP MetaFieldsRegistry system
- Testing with popular plugins

**Status:** Backend API ready for Level 1 compatibility! 🎉
This commit is contained in:
dwindown
2025-11-20 12:22:01 +07:00
parent cb91d0841c
commit e53b8320e4
2 changed files with 206 additions and 0 deletions

View File

@@ -522,8 +522,12 @@ class OrdersController {
'notes' => $notes,
'coupons' => $coupon_codes,
'customer_note' => $order->get_customer_note(),
'meta' => self::get_order_meta_data( $order ),
];
// Allow plugins to modify response (Level 1 compatibility)
$data = apply_filters( 'woonoow/order_api_data', $data, $order, $req );
return new WP_REST_Response( $data, 200 );
}
@@ -682,6 +686,11 @@ class OrdersController {
}
}
// Update custom meta fields (Level 1 compatibility)
if ( isset( $p['meta'] ) && is_array( $p['meta'] ) ) {
self::update_order_meta_data( $order, $p['meta'] );
}
// SOLUTION: Block WooCommerce analytics tracking (pixel.wp.com) during save
// This was causing 30s timeout on every order status change
add_filter( 'pre_http_request', function( $preempt, $args, $url ) {
@@ -694,6 +703,9 @@ class OrdersController {
$order->save();
// Allow plugins to perform additional updates (Level 1 compatibility)
do_action( 'woonoow/order_updated', $order, $p, $req );
// Clean up
remove_all_filters( 'pre_http_request' );
@@ -2172,4 +2184,99 @@ class OrdersController {
'expiry_date' => $coupon->get_date_expires() ? $coupon->get_date_expires()->date( 'Y-m-d' ) : null,
], 200 );
}
/**
* Get order meta data for API exposure (Level 1 compatibility)
* Filters out internal meta unless explicitly allowed
*
* @param \WC_Order $order
* @return array
*/
private static function get_order_meta_data( $order ) {
$meta_data = [];
foreach ( $order->get_meta_data() as $meta ) {
$key = $meta->key;
$value = $meta->value;
// Skip internal WooCommerce meta (starts with _wc_)
if ( strpos( $key, '_wc_' ) === 0 ) {
continue;
}
// Skip WooNooW internal meta
if ( strpos( $key, '_woonoow_' ) === 0 ) {
continue;
}
// Public meta (no underscore) - always expose
if ( strpos( $key, '_' ) !== 0 ) {
$meta_data[ $key ] = $value;
continue;
}
// Private meta (starts with _) - check if allowed
$allowed_private = apply_filters( 'woonoow/order_allowed_private_meta', [
// Common shipping tracking fields
'_tracking_number',
'_tracking_provider',
'_tracking_url',
'_shipment_tracking_items',
'_wc_shipment_tracking_items',
// Payment gateway meta
'_transaction_id',
'_payment_method_title',
// Allow plugins to add their meta via filter
], $order );
if ( in_array( $key, $allowed_private, true ) ) {
$meta_data[ $key ] = $value;
}
}
return $meta_data;
}
/**
* Update order meta data from API (Level 1 compatibility)
*
* @param \WC_Order $order
* @param array $meta_updates
*/
private static function update_order_meta_data( $order, $meta_updates ) {
// Get allowed updatable meta keys
$allowed = apply_filters( 'woonoow/order_updatable_meta', [
// Common shipping tracking fields
'_tracking_number',
'_tracking_provider',
'_tracking_url',
// Allow plugins to add their meta via filter
], $order );
foreach ( $meta_updates as $key => $value ) {
// Skip internal WooCommerce meta
if ( strpos( $key, '_wc_' ) === 0 ) {
continue;
}
// Skip WooNooW internal meta
if ( strpos( $key, '_woonoow_' ) === 0 ) {
continue;
}
// Public meta (no underscore) - always allow
if ( strpos( $key, '_' ) !== 0 ) {
$order->update_meta_data( $key, $value );
continue;
}
// Private meta - check if allowed
if ( in_array( $key, $allowed, true ) ) {
$order->update_meta_data( $key, $value );
}
}
}
}