如何使用 WooCommerce 检索 cart_item_data?

Posted

技术标签:

【中文标题】如何使用 WooCommerce 检索 cart_item_data?【英文标题】:How to retrieve cart_item_data with WooCommerce? 【发布时间】:2014-10-01 00:57:49 【问题描述】:

add_to_cart 函数中,有一个过滤器可以添加“购物车项目数据”。过滤器是woocommerce_add_cart_item_data。我希望将我的自定义插件数据存储在其中,以便数据相对于项目存储,并且可以使用不同的数据添加多个产品。

这一切似乎都有效,但我无法检索数据。我想不通。 数据在那里,我可以在序列化的字符串中看到它,但拉不出来。

echo '<pre>';
var_dump( WC() );

foreach( WC()->cart->get_cart() as $cart_item ) 
  var_dump( $cart_item );
  var_dump( WC()->cart->get_item_data( $cart_item ) );

echo '</pre>';

WC() 的第一个转储有一个属性:session-&gt;_data-&gt;cart-&gt;(serialized data)。虽然 _data 属性受到保护,但我可以在序列化数据中看到我的自定义字段。

$cart_item 是一个包含product_id 和其他一些数据的数组,但它不包含我的自定义数据:(

最后,使用get_item_data() 方法,我想我已经弄清楚了。我传入了购物车项目对象,并且......一个空字符串。如果我传递密钥而不是购物车项目本身,则相同。

我应该如何访问购物车商品数据?


这是“添加购物车商品数据”功能,它有效(或至少似乎有效):

function save_class_menu_selection( $cart_item_data, $product_id, $variation_id ) 
  if ( !product_is_class( $product_id ) ) return $cart_item_data;

  // Save the date, or give a fatal warning. Date is required.
  if ( !empty($_REQUEST['class-date']) ) 
    $cart_item_data['class-date'] = stripslashes($_REQUEST['class-date']);
    return $cart_item_data;
  else
    wp_die('<h2>Invalid Class Date Selected</h2><p>You tried to add a class to your cart, but the date selected was invalid. Please try again.</p>');
    exit;
  

add_filter( 'woocommerce_add_cart_item_data', 'save_class_menu_selection', 10, 3 );

【问题讨论】:

【参考方案1】:

我今天也遇到了同样的情况,经过一番研究,我偶然发现了这个问题。 经过一些逆向工程后,我发现了问题并希望为其他可能会遇到这个问题的人提供解决方案。

问题在于,当购物车商品从会话中恢复时,数据会被清理。因此,额外的购物车商品数据会存储到会话中,但在下一次请求时不会恢复。

有一个过滤器“woocommerce_get_cart_item_from_session”。作为第一个参数,您将获得经过清理的购物车项目(没有额外数据),作为第二个参数,您将获得存储到会话中的所有数据(包括额外数据)。

解决方案是挂在那里并恢复您的自定义购物车项目数据。

示例代码:

add_filter( 'woocommerce_add_cart_item_data', function ( $cartItemData, $productId, $variationId ) 
    $cartItemData['myCustomData'] = 'someCustomValue';

    return $cartItemData;
, 10, 3 );

add_filter( 'woocommerce_get_cart_item_from_session', function ( $cartItemData, $cartItemSessionData, $cartItemKey ) 
    if ( isset( $cartItemSessionData['myCustomData'] ) ) 
        $cartItemData['myCustomData'] = $cartItemSessionData['myCustomData'];
    

    return $cartItemData;
, 10, 3 );

要在购物车/结帐页面上也显示数据,您可以使用以下代码:

add_filter( 'woocommerce_get_item_data', function ( $data, $cartItem ) 
    if ( isset( $cartItem['myCustomData'] ) ) 
        $data[] = array(
            'name' => 'My custom data',
            'value' => $cartItem['myCustomData']
        );
    

    return $data;
, 10, 2 );

现在最后一件事是在下订单时保存数据:

add_action( 'woocommerce_add_order_item_meta', function ( $itemId, $values, $key ) 
    if ( isset( $values['myCustomData'] ) ) 
        wc_add_order_item_meta( $itemId, 'myCustomData', $values['myCustomData'] );
    
, 10, 3 );

您无需在后台显示数据,所有订单商品元数据都会自动显示。

【讨论】:

感谢 Stefan。听起来这与 WordPress 中的“查询变量”非常相似。也就是说,通过 POST/GET 传递的任何数据都不会注册为 query_var,除非您明确告诉 WordPress 这样做。您知道将购物车数据转换为订单时是否保存了此会话数据? (例如,付款时) 数据不会自动保存,但我已经在我的答案中添加了一些代码示例来说明如何执行此操作。 我将把它作为公认的答案,因为我的解决方案是一种解决方法。这看起来更正确地实现了。不过,我自己并没有实际测试过。 这个答案非常有帮助!感谢您花时间发帖。您能否阐明如何在客户付款电子邮件中显示此自定义数据? 这真的很有帮助。现在我想弄清楚如何根据自定义值更改商品价格。有人有兴趣帮忙吗?【参考方案2】:

很遗憾,我无法让默认购物车商品数据正常工作。我觉得它可能没有正确实施,甚至可能被弃用,因为缺乏支持和文档。

相反,我使用购物车会话变量来完成同样的事情。它只是一个数组,其中每个键都是cart_item_key。每个数组的值是另一个数组,包含自定义字段的键值对。因此,它与内置购物车商品数据基本相同,只是存储为购物车会话数据。

这是一个包含一些实用功能的要点:

https://gist.github.com/RadGH/e3444fc661554a0f8c6f


或者如果你想自己构建它,魔法就在WC()-&gt;session。以下是实现此功能的两个关键功能:

WC()->session->get('_my_cart_item_data');
WC()->session->set('_my_cart_item_data', $cart_item_data_array);

这些是你需要的动作钩子:

<<<EXAMPLES
action: woocommerce_add_to_cart
desc: When an item is added to the cart. 
args: $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data

action: woocommerce_add_order_item_meta
desc: When a cart item is converted to an order item, save metadata to the order item
      using the function "wc_add_order_item_meta( $item_id, $key, $value )"
args: item_id, $values, $cart_item_key

【讨论】:

以上是关于如何使用 WooCommerce 检索 cart_item_data?的主要内容,如果未能解决你的问题,请参考以下文章

Woocommerce 订阅自定义费用添加到经常性总额中

Woocommerce WC_Cart->fees 和 WC_Cart::get_checkout_url 已弃用

Woocommerce - added_to_cart 触发器

将 Zen Cart 订单转移到 Woocommerce

WooCommerce 使用 add_to_cart 添加产品

获取woocommerce购物车总量