Как получить данные о товарах в корзине с помощью 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>';

Первый дамп из 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 );
Author: Radley Sustaire, 2014-08-07

2 answers

Сегодня я был в такой же ситуации и наткнулся на этот вопрос после некоторых исследований. После некоторого обратного проектирования я обнаружил проблему и хочу предложить решение для других, которые также могут столкнуться с этим вопросом.

Проблема в том, что данные очищаются, когда элементы корзины восстанавливаются из сеанса. Таким образом, дополнительные данные о товарах корзины сохраняются в сеансе, но при следующем запросе они не восстанавливаются.

Есть фильтр "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 );

Вам не нужно делать ничего другого, чтобы отобразить данные внутри серверной части, все метаданные элемента заказа отображаются автоматически.

 39
Author: Stefan, 2015-09-09 12:07:51

К сожалению, я не смог заставить данные о товарах в корзине по умолчанию работать. Я чувствую, что это может быть реализовано неправильно или даже устарело, так как отсутствует поддержка и документация.

Вместо этого я использовал переменную сеанса cart для выполнения того же самого. Это просто массив, где каждый ключ является cart_item_key. Значение каждого массива является еще одним массивом, содержащим пару пользовательских полей "ключ-значение". Таким образом, это по сути то же самое, что и встроенные данные о товарах в корзине, за исключением вместо этого они хранятся в виде данных сеанса корзины.

Вот суть, содержащая некоторые полезные функции для упрощения:

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

Вот крючки действий, которые вам понадобятся:

<<<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
 5
Author: Radley Sustaire, 2015-08-07 19:01:10