phpwordpresswoocommercemetadatawoocommerce-memberships

Make specific hidden order item metadata editable in WooCommerce Admin Edit Order


WooCommerce lets you add meta data to each order item. Plugins can do this, or you can manually add the meta data from the edit order screen. When you edit the order item (click the little pencil icon), you can amend existing meta data.

edit a product

On one site we use Teams for WooCommerce Memberships to sell various membership plans. This plugin adds two pieces of meta data to order items:

team_id
_wc_memberships_for_teams_team_id

Once the _wc_memberships_for_teams_team_id has been entered and the product is saved, it can no longer be edited. Other meta keys that begin with an undescore (for example, _test123) can still be edited.

There are times where the client's admin team need to be able to edit the item meta for the team ID, but this is currently not possible. I need to expose the meta key when the admin user clicks the edit button.

I took a look at the WooCommerce template files for the edit order screen and saw that there is a filter hook for the hidden item meta:

woocommerce_hidden_order_itemmeta

Via the print_r call, I can see a whole load of meta keys, including the _wc_memberships_for_teams_team_id one I need:

Array
(
    [0] => _qty
    [1] => _tax_class
    [2] => _product_id
    [3] => _variation_id
    [4] => _line_subtotal
    [5] => _line_subtotal_tax
    [6] => _line_total
    [7] => _line_tax
    [8] => method_id
    [9] => cost
    [10] => _reduced_stock
    [11] => _restock_refunded_items
    [12] => _has_trial
    [13] => _wcs_migrated_recurring_line_total
    [14] => _wcs_migrated_recurring_line_tax
    [15] => _wcs_migrated_recurring_line_subtotal
    [16] => _wcs_migrated_recurring_line_subtotal_tax
    [17] => _wcs_migrated_subscription_period
    [18] => _wcs_migrated_subscription_interval
    [19] => _wcs_migrated_subscription_trial_length
    [20] => _wcs_migrated_subscription_trial_period
    [21] => _wcs_migrated_subscription_length
    [22] => _wcs_migrated_subscription_sign_up_fee
    [23] => _wcs_migrated_subscription_failed_payments
    [24] => _wcs_migrated_subscription_recurring_amount
    [25] => _wcs_migrated_subscription_start_date
    [26] => _wcs_migrated_subscription_trial_expiry_date
    [27] => _wcs_migrated_subscription_expiry_date
    [28] => _wcs_migrated_subscription_end_date
    [29] => _wcs_migrated_subscription_status
    [30] => _wcs_migrated_subscription_completed_payments
    [31] => _wcs_migrated_subscription_suspension_count
    [32] => _switched_subscription_item_id
    [33] => _switched_subscription_new_item_id
    [34] => _switched_subscription_sign_up_fee_prorated
    [35] => _switched_subscription_price_prorated
    [36] => _cart_item_key_subscription_renewal
    [37] => _cart_item_key_subscription_switch
    [38] => _wc_memberships_for_teams_team_id
    [39] => _wc_memberships_for_teams_team_uid
    [40] => _wc_memberships_for_teams_team_renewal
    [41] => _wc_memberships_for_teams_team_seat_change
    [42] => _wc_memberships_for_teams_team_current_seat_count
    [43] => team_owner_takes_seat
    [44] => _synced_sign_up_fee
)

I've tried to access this array and unset the key with a really late priority, but it still won't appear in the fields when trying to edit the product item.

function custom_woocommerce_hidden_order_itemmeta($arr) {
    
    print_r($arr);

    // This is what I want to appear as an editable field
    unset($arr['_wc_memberships_for_teams_team_id']);

    // Uncomment this to test a working field 
    //$arr[] = 'team_name';
    
    return $arr;
}

add_filter('woocommerce_hidden_order_itemmeta', 'custom_woocommerce_hidden_order_itemmeta', 999999, 1);

editing meta keys and values

How can I make it so that the _wc_memberships_for_teams_team_id key is exposed with a pair of key/value fields like the other fields?

Cheers!


Solution

  • In your code attempt, '_wc_memberships_for_teams_team_id' is a value in your array, but not a key, so that's why using unset($arr['_wc_memberships_for_teams_team_id']); doesn't has any effect.

    Try the following instead:

    add_filter( 'woocommerce_hidden_order_itemmeta', 'show_specific_admin_order_item_metadata', 20 );
    function show_specific_admin_order_item_metadata( $hidden_meta ) {
        foreach ( $hidden_meta as $key => $meta_key ) {
            if ( '_wc_memberships_for_teams_team_id' === $meta_key ) {
                unset( $hidden_meta[$key] );
            }
        }
        return $hidden_meta;
    }
    

    It should better work now.

    For info in Teams for WooCommerce Memberships plugin the hidden metakeys are located in src > Orders.php file using woocommerce_hidden_order_itemmeta filter hook as you guessed (without hook priority).

    Related - How to change the displayed meta key:
    Change multiple displayed order item meta keys to a readable name in WooCommerce