Intereting Posts

Как получить cart_item_data с помощью 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 ); 

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

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

Существует фильтр «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 ); 

Чтобы также показать данные на странице cart / checkout, вы можете использовать следующий код:

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

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

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

Вместо этого я использовал переменную сеанса тележки, чтобы выполнить одно и то же. Это просто массив, где каждый ключ – 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); 

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

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