php 如何使用 WooCommerce 检索cart_item_data?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25188365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:43:00  来源:igfitidea点击:

How to retrieve cart_item_data with WooCommerce?

phpwordpresswoocommercecart

提问by Radley Sustaire

During the add_to_cartfunction, there is a filter to add "cart item data". The filter is woocommerce_add_cart_item_data. I expected to store my custom plugin data in this, so that the data is stored relative to the item and multiple products can be added with different data.

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

This all seemed to work, but I am not able to retrieve the data. I can't figure it out. The data is there, I can see it in a serialized string, but I can't pull it out.

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

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>';

The first dump of WC()has a property: session->_data->cart->(serialized data). The _data property is protected, though, but I can see my custom field inside the serialized data.

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

The $cart_item is an array with product_idand some other data, but it does not include my custom data :(

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

Finally, using the get_item_data()method I thought I had it all figured out. I passed in the cart item object, and... an empty string. Same if I pass the key, rather than the cart item itself.

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

How am I supposed to access the cart item data?

我应该如何访问购物车项目数据?



Here is the "Add cart item data" function, which works (or at least seems to work):

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

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 );

回答by Stefan

I was in the same situation today and stumbled over this question after some research. After some reverse engineering I found the problem and want to provide a solution for other which may also stumble over this question.

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

The problem is that the data gets sanitized when the cart items get restored from the session. So the extra cart item data IS stored into the session but on the next request it does not get restored.

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

There is a filter "woocommerce_get_cart_item_from_session". As first parameter you get the sanitized cart item (without extra data) and as second all data which got stored into the session (including extra data).

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

The solution is to hook in there and also restore your custom cart item data.

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

Example Code:

示例代码:

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 );

To also show the data at the cart/checkout page you can use the following code:

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

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 );

The final thing now is to save the data when the order is made:

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

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 );

You dont have to do anything else the show the data inside the backend, all order item meta data gets display automatically.

您无需执行任何其他操作即可在后端显示数据,所有订单项元数据都会自动显示。

回答by Radley Sustaire

I could not get the default cart item data to work, unfortunately. I feel it may not be properly implemented, or may even be deprecated, as there is a lack of support and documentation.

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

Instead, I used a cart session variable to accomplish the same thing. It's simply an array where each key is the cart_item_key. The value of each array is yet another array, containing a key-value pair of custom fields. So it's essentially the same thing as the built-in cart item data, except stored as cart session data instead.

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

Here is a Gist containing some utility functions to make it easy:

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

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

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



Or if you want to build it yourself, the magic is in WC()->session. Here are the two key functions for this to work:

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

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

These are the action hooks you will need:

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

<<<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