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

@@ -371,8 +371,16 @@ class ProductsController {
$product->set_gallery_image_ids($data['gallery_image_ids']);
}
// Update custom meta fields (Level 1 compatibility)
if (isset($data['meta']) && is_array($data['meta'])) {
self::update_product_meta_data($product, $data['meta']);
}
$product->save();
// Allow plugins to perform additional updates (Level 1 compatibility)
do_action('woonoow/product_updated', $product, $data, $request);
// Handle variations for variable products
if ($product->is_type('variable')) {
if (isset($data['attributes'])) {
@@ -565,6 +573,12 @@ class ProductsController {
$data['variations'] = self::get_product_variations($product);
}
// Expose meta data (Level 1 compatibility)
$data['meta'] = self::get_product_meta_data($product);
// Allow plugins to modify response (Level 1 compatibility)
$data = apply_filters('woonoow/product_api_data', $data, $product);
return $data;
}
@@ -697,4 +711,89 @@ class ProductsController {
}
}
}
/**
* Get product meta data for API exposure (Level 1 compatibility)
* Filters out internal meta unless explicitly allowed
*
* @param \WC_Product $product
* @return array
*/
private static function get_product_meta_data($product) {
$meta_data = [];
foreach ($product->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/product_allowed_private_meta', [
// Common custom fields
'_custom_field',
// Allow plugins to add their meta via filter
], $product);
if (in_array($key, $allowed_private, true)) {
$meta_data[$key] = $value;
}
}
return $meta_data;
}
/**
* Update product meta data from API (Level 1 compatibility)
*
* @param \WC_Product $product
* @param array $meta_updates
*/
private static function update_product_meta_data($product, $meta_updates) {
// Get allowed updatable meta keys
$allowed = apply_filters('woonoow/product_updatable_meta', [
// Common custom fields
'_custom_field',
// Allow plugins to add their meta via filter
], $product);
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) {
$product->update_meta_data($key, $value);
continue;
}
// Private meta - check if allowed
if (in_array($key, $allowed, true)) {
$product->update_meta_data($key, $value);
}
}
}
}