在 WooCommerce 中将自定义元数据添加并保存到费用中
Add and save custom meta data to fees in WooCommerce
我正在使用 WC()->cart->add_fee()
方法向 WC 添加自定义费用。
我的问题是我也想向该费用项目添加元数据。最好同时添加实际费用。
显然 WC_Order_Item_Fee
对象仅在订单创建时生成,因此似乎无法将特定于 FeeItem 的元数据添加到自定义费用中。
当然我可以将这个元数据保存到会话中,但是因为 add_fee 没有 return 任何标识符,我不知道哪个自定义费用实际上是哪个。
有解决这个问题的想法吗?
这是我用来添加费用的代码:
add_filter('woocommerce_cart_calculate_fees', function (){
foreach( FeeChecker::getFees() as $fee )
{
$cart->add_fee("Added fee: ". $fee, 10 , true, $tax_class);
}
}
Note: In your code the $cart
argument is missing from the hooked function and it's an action hook, but not a filter hook.
WC_Cart
方法 add_fee()
不允许添加自定义元数据,因此您需要在 add_to_cart 事件之前或 WC_Session
中添加它。
您可以在提交订单时使用以下代码示例将自定义元数据添加到 WC_Order_Item_Fee
(使用 WC_Session 在此处设置和获取自定义元数据):
// Add a custom cart fee
add_action( 'woocommerce_cart_calculate_fees', 'adding_cart_fees', 10, 1 );
function adding_cart_fees( $cart ){
$cart->add_fee(__("Added fee"), 10, true, '');
}
// Set Fee custom meta data in WC_Session
add_action( 'woocommerce_calculate_totals', 'calculate_totals_for_fees_meta_data', 10, 1 );
function calculate_totals_for_fees_meta_data( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fees_meta = WC()->session->get('fees_meta');
$update = false;
// Loop through applied fees
foreach( $cart->get_fees() as $fee_key => $fee ) {
// Set the fee in the fee custom meta data array
if( ! isset($fees_meta[$fee_key]) ){
$fees_meta[$fee_key] = 'some value';
$update = true;
}
}
// If any fee meta data doesn't exist yet, we update the WC_Session custom meta data array
if ( $update ) {
WC()->session->set('fees_meta', $fees_meta);
}
}
// Save fee custom meta data to WC_Order_Item_Fee.
add_action( 'woocommerce_checkout_create_order_fee_item', 'save_custom_met_data_to_fee_order_items', 10, 4 );
function save_custom_met_data_to_fee_order_items( $item, $fee_key, $fee, $order ) {
// Get fee meta data from WC_Session
$fees_meta = WC()->session->get('fees_meta');
// If fee custom meta data exist, save it to fee order item
if ( isset($fees_meta[$fee_key]) ) {
$item->update_meta_data( 'custom_key', $fees_meta[$fee_key] );
}
}
// Remove Fee meta data from WC_Session.
add_action( 'woocommerce_checkout_create_order', 'remove_fee_custom_met_data_from_wc_session', 10, 2 );
function remove_fee_custom_met_data_from_wc_session( $order, $data ) {
$fees_meta = WC()->session->__unset('fees_meta');
}
代码进入您的活动子主题(或活动主题)的 function.php 文件。已测试并有效。
The custom meta data is saved to WC_Order_Item_Fee and you can get it using something like:
// Get an instance of the WC_Order Object (if needed)
$order = wc_get_order( $order_id );
// loop through fee order items
foreach ( $order->get_items('fee') as $fee_key => $item ) {
// Get the fee custom meta data
$fee_custom_meta = $item->get_meta('custom_key');
if ( $fee_custom_meta ) {
// Display the custom meta data value
echo '<p>' . $fee_custom_meta . '</p>';
}
}
我好像忽略了WC_Cart->fees_api
在那里我有方法实际上 returns 创建的费用所以我知道 woocommerce_checkout_create_order_fee_item
操作中的确切费用
编辑:此代码最初主要由 LoicTheAztec 完成。我对其进行了编辑以适合我的特定用例,并将其 post 编辑为解决方案。不幸的是,他删除了他的 post,这可能对其他人有益。
// Add cod fee
add_action('woocommerce_cart_calculate_fees', function ( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
//Make sure it's the right payment method
if( WC()->session->chosen_payment_method == "cod"){
$tax_class = '';
$amount = 5;
$session_data = [];
foreach( $cart->get_shipping_packages() as $package)
{
$fee = $cart->fees_api()->add_fee(
array(
'name' => "Additional cost: ".$package['custom_data'],
'amount' => (float) $amount,
'taxable' => true,
'tax_class' => $tax_class,
)
);
$session_data [ $fee->id ] = $package['custom_data'];
}
WC()->session->set('COD_fee_meta', $session_data);
}
}, 10, 2);
// Save fee custom meta data to WC_Order_Item_Fee.
add_action( 'woocommerce_checkout_create_order_fee_item', function ( $item, $fee_key, $fee, $order ) {
// Get fee meta data from WC_Session
$fees_meta = WC()->session->get('COD_fee_meta');
// If fee custom meta data exist, save it to fee order item
if ( isset($fees_meta[$fee_key]) ) {
$item->update_meta_data( '_custom_data', $fees_meta[$fee_key] );
}
}, 10, 4 );
// Remove Fee meta data from WC_Session.
add_action( 'woocommerce_checkout_create_order', function ( $order, $data ) {
WC()->session->__unset('COD_fee_meta');
}, 10, 2 );
一种有点老套的方法是使用费用项的 ID 字段 link 将数据存储在其他地方。
$args = array(
'id' => $data_id,
'name' => $name,
'amount' => (float) $amount,
'taxable' => false,
'tax_class' => '',
);
$cart->fees_api()->add_fee( $args );
稍后您可以使用挂钩 woocommerce_checkout_create_order_fee_item
获取数据并填充订单商品费用。就我而言:
add_action( 'woocommerce_checkout_create_order_fee_item', array( $this, 'create_order_fee_item' ), 20, 4 );
public function create_order_fee_item( $item, $fee_key, $fee, $order ) {
$item->add_meta_data( 'product_id', $fee_key, true );
}
我正在使用 WC()->cart->add_fee()
方法向 WC 添加自定义费用。
我的问题是我也想向该费用项目添加元数据。最好同时添加实际费用。
显然 WC_Order_Item_Fee
对象仅在订单创建时生成,因此似乎无法将特定于 FeeItem 的元数据添加到自定义费用中。
当然我可以将这个元数据保存到会话中,但是因为 add_fee 没有 return 任何标识符,我不知道哪个自定义费用实际上是哪个。
有解决这个问题的想法吗?
这是我用来添加费用的代码:
add_filter('woocommerce_cart_calculate_fees', function (){
foreach( FeeChecker::getFees() as $fee )
{
$cart->add_fee("Added fee: ". $fee, 10 , true, $tax_class);
}
}
Note: In your code the
$cart
argument is missing from the hooked function and it's an action hook, but not a filter hook.
WC_Cart
方法 add_fee()
不允许添加自定义元数据,因此您需要在 add_to_cart 事件之前或 WC_Session
中添加它。
您可以在提交订单时使用以下代码示例将自定义元数据添加到 WC_Order_Item_Fee
(使用 WC_Session 在此处设置和获取自定义元数据):
// Add a custom cart fee
add_action( 'woocommerce_cart_calculate_fees', 'adding_cart_fees', 10, 1 );
function adding_cart_fees( $cart ){
$cart->add_fee(__("Added fee"), 10, true, '');
}
// Set Fee custom meta data in WC_Session
add_action( 'woocommerce_calculate_totals', 'calculate_totals_for_fees_meta_data', 10, 1 );
function calculate_totals_for_fees_meta_data( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fees_meta = WC()->session->get('fees_meta');
$update = false;
// Loop through applied fees
foreach( $cart->get_fees() as $fee_key => $fee ) {
// Set the fee in the fee custom meta data array
if( ! isset($fees_meta[$fee_key]) ){
$fees_meta[$fee_key] = 'some value';
$update = true;
}
}
// If any fee meta data doesn't exist yet, we update the WC_Session custom meta data array
if ( $update ) {
WC()->session->set('fees_meta', $fees_meta);
}
}
// Save fee custom meta data to WC_Order_Item_Fee.
add_action( 'woocommerce_checkout_create_order_fee_item', 'save_custom_met_data_to_fee_order_items', 10, 4 );
function save_custom_met_data_to_fee_order_items( $item, $fee_key, $fee, $order ) {
// Get fee meta data from WC_Session
$fees_meta = WC()->session->get('fees_meta');
// If fee custom meta data exist, save it to fee order item
if ( isset($fees_meta[$fee_key]) ) {
$item->update_meta_data( 'custom_key', $fees_meta[$fee_key] );
}
}
// Remove Fee meta data from WC_Session.
add_action( 'woocommerce_checkout_create_order', 'remove_fee_custom_met_data_from_wc_session', 10, 2 );
function remove_fee_custom_met_data_from_wc_session( $order, $data ) {
$fees_meta = WC()->session->__unset('fees_meta');
}
代码进入您的活动子主题(或活动主题)的 function.php 文件。已测试并有效。
The custom meta data is saved to WC_Order_Item_Fee and you can get it using something like:
// Get an instance of the WC_Order Object (if needed)
$order = wc_get_order( $order_id );
// loop through fee order items
foreach ( $order->get_items('fee') as $fee_key => $item ) {
// Get the fee custom meta data
$fee_custom_meta = $item->get_meta('custom_key');
if ( $fee_custom_meta ) {
// Display the custom meta data value
echo '<p>' . $fee_custom_meta . '</p>';
}
}
我好像忽略了WC_Cart->fees_api
在那里我有方法实际上 returns 创建的费用所以我知道 woocommerce_checkout_create_order_fee_item
操作中的确切费用
编辑:此代码最初主要由 LoicTheAztec 完成。我对其进行了编辑以适合我的特定用例,并将其 post 编辑为解决方案。不幸的是,他删除了他的 post,这可能对其他人有益。
// Add cod fee
add_action('woocommerce_cart_calculate_fees', function ( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
//Make sure it's the right payment method
if( WC()->session->chosen_payment_method == "cod"){
$tax_class = '';
$amount = 5;
$session_data = [];
foreach( $cart->get_shipping_packages() as $package)
{
$fee = $cart->fees_api()->add_fee(
array(
'name' => "Additional cost: ".$package['custom_data'],
'amount' => (float) $amount,
'taxable' => true,
'tax_class' => $tax_class,
)
);
$session_data [ $fee->id ] = $package['custom_data'];
}
WC()->session->set('COD_fee_meta', $session_data);
}
}, 10, 2);
// Save fee custom meta data to WC_Order_Item_Fee.
add_action( 'woocommerce_checkout_create_order_fee_item', function ( $item, $fee_key, $fee, $order ) {
// Get fee meta data from WC_Session
$fees_meta = WC()->session->get('COD_fee_meta');
// If fee custom meta data exist, save it to fee order item
if ( isset($fees_meta[$fee_key]) ) {
$item->update_meta_data( '_custom_data', $fees_meta[$fee_key] );
}
}, 10, 4 );
// Remove Fee meta data from WC_Session.
add_action( 'woocommerce_checkout_create_order', function ( $order, $data ) {
WC()->session->__unset('COD_fee_meta');
}, 10, 2 );
一种有点老套的方法是使用费用项的 ID 字段 link 将数据存储在其他地方。
$args = array(
'id' => $data_id,
'name' => $name,
'amount' => (float) $amount,
'taxable' => false,
'tax_class' => '',
);
$cart->fees_api()->add_fee( $args );
稍后您可以使用挂钩 woocommerce_checkout_create_order_fee_item
获取数据并填充订单商品费用。就我而言:
add_action( 'woocommerce_checkout_create_order_fee_item', array( $this, 'create_order_fee_item' ), 20, 4 );
public function create_order_fee_item( $item, $fee_key, $fee, $order ) {
$item->add_meta_data( 'product_id', $fee_key, true );
}