如何使用WooCommerce检索cart_item_data?

Rad*_*ire 18 php wordpress cart woocommerce

在该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>';
Run Code Online (Sandbox Code Playgroud)

第一个转储WC()有一个属性:session->_data->cart->(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 );
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 42

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

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

有一个过滤器"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 );
Run Code Online (Sandbox Code Playgroud)

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

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 );
Run Code Online (Sandbox Code Playgroud)

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

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 );
Run Code Online (Sandbox Code Playgroud)

你不必做任何事情,在后端显示数据,所有订单项元数据都会自动显示.


Rad*_*ire 5

不幸的是,我无法使用默认的购物车项目数据。我觉得它可能没有正确实施,甚至可能被弃用,因为缺乏支持和文档。

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

这是一个包含一些实用功能的 Gist 以使其变得容易:

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


或者,如果您想自己构建它,那么神奇就在WC()->session. 这是使其工作的两个关键功能:

WC()->session->get('_my_cart_item_data');
WC()->session->set('_my_cart_item_data', $cart_item_data_array);
Run Code Online (Sandbox Code Playgroud)

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

<<<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
Run Code Online (Sandbox Code Playgroud)