Woocommerce: какой хук заменить устаревший woocommerce_add_order_item_meta

Необходимо добавить настраиваемую мета для элементов заказа. Погуглил, и в большинстве статей говорится об использовании хука "woocommerce_add_order_item_meta". Этот хук устарел в последней версии 2.3.7. Кто-нибудь, подскажите, пожалуйста, какой хук использовать вместо этого.

http://docs.woothemes.com/wc-apidocs/function-woocommerce_add_order_item_meta.html


person user3339988    schedule 16.04.2015    source источник


Ответы (8)


Если вы посмотрите на wc-deprecated-functions.php, вы увидите

/**
 * @deprecated
 */
function woocommerce_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = false ) {
    return wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique );
}

По сути, функция была переименована в wc_add_order_item_meta(), поэтому, если вам нужна функция, используйте ее. Обработчик действия не был переименован и остается в class-wc-checkout.php как:

// Allow plugins to add order item meta
do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key );
person helgatheviking    schedule 16.04.2015
comment
Хук устарел, поэтому этот ответ неверен. - person Tofandel; 25.06.2019
comment
Это был правильный ответ в 2015 году. :) Но похоже, что у @LoicTheAztec уже есть обновленный и правильный ответ, поэтому всем следует полагаться на него: stackoverflow.com/a/49419394/383847 - person helgatheviking; 26.06.2019

2017/2018 ПРАВИЛЬНЫЙ ПУТЬ (с использованием новых методов установки и получения CRUD)

По теме: Заменить крючок woocommerce_add_order_item_meta в Woocommerce 3.4

Начиная с woocommerce 3, который улучшил многие вещи, внося кардинальные изменения, обработчик действий woocommerce_add_order_item_meta по-прежнему отлично работает даже в woocommerce версии 3.3+.

Эта ловушка активируется WC_Checkout методами класса и связанными функциями в процессе оформления заказа, а не в WC_Order классе, где данные корзины больше не доступны.

Теперь, когда Woocommmerce 3 представила новые методы установки и получения CRUD, будет использоваться аналогичный перехватчик замены woocommerce_checkout_create_order_line_item, который имеет те же полезные аргументы, что и данные корзины.

woocommerce_new_order_item действительно НЕ удобно, поскольку данные корзины недоступны.

Посмотрим, как работать с woocommerce_checkout_create_order_line_item. У него есть 4 доступных аргумента:

  • $item - это экземпляр WC_Order_Item_Product нового представленного класса
  • $cart_item_key - уникальный хэш-ключ корзины.
  • $values - это элемент корзины
  • $order экземпляр объекта WC_Order (это очень полезный дополнительный аргумент в некоторых конкретных случаях)

В этой ловушке мы заменим старые рабочие функции wc_add_order_item_meta () новым методом WC_Data update_meta_data(), который будет использоваться с аргументом $item.

Пример:

## --- New way --- ##
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_checkout_create_order_line_item', 20, 4 );
function custom_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
    // Get a product custom field value
    $custom_field_value = get_post_meta( $item->get_product_id(), '_meta_key', true );
    // Update order item meta
    if ( ! empty( $custom_field_value ) ){
        $item->update_meta_data( 'meta_key1', $custom_field_value );
    }
    // … … Or … …

    // Get cart item custom data and update order item meta
    if( isset( $values['custom_data'] ) ) {
        $item->update_meta_data( 'meta_key2', $values['custom_data'] );
    }
}

Наконец, мы можем сделать то же самое старым способом, используя хук woocommerce_add_order_item_meta, поскольку он имеет почти те же полезные аргументы:

## --- Old way --- ##
add_action( 'woocommerce_add_order_item_meta', 'custom_add_order_item_meta', 20, 3 );
function custom_add_order_item_meta( $item_id, $values, $cart_item_key ) {
    // Get a product custom field value
    $custom_field_value = get_post_meta( $values['data']->get_id(), '_meta_key', true );
    // Update order item meta
    if ( ! empty( $custom_field_value ) ){
        wc_add_order_item_meta( $item_id, 'meta_key1', $custom_field_value );
    }
    // … … Or … …

    // Get cart item custom data and update order item meta
    if( isset( $values['custom_data'] ) ) {
        wc_add_order_item_meta( $item_id, 'meta_key2', $values['custom_data'] );
    }
}

Заключение: woocommerce_checkout_create_order_line_item - это подходящая замена для использования с WooCommerce 3+ и новыми методами установки и получения CRUD.

person LoicTheAztec    schedule 22.03.2018
comment
Работает нормально, спасибо. Однако некоторые параметры доступны не полностью. У параметра $order нет идентификатора, например, и, очевидно, у нас также не может быть $item_id - person Pablo S G Pacheco; 30.01.2019
comment
@PabloSGPacheco К сожалению, доступны все параметры: чтобы получить идентификатор заказа, просто используйте $order_id = $order->get_id();, а для идентификатора товара просто используйте $item_id = $item->get_id(); - person LoicTheAztec; 30.01.2019
comment
@LoicTheAztec Спасибо за отзыв, но в обоих случаях я получаю ноль. И, возможно, в этом есть смысл. При срабатывании woocommerce_checkout_create_order_line_item ордер еще не создан. Я прав? - person Pablo S G Pacheco; 31.01.2019
comment
@PabloSGPacheco Заказ еще не сохранен в базе данных, так как метод _ 1_ save() используется позже в конце _ 3_ create_order(). - person LoicTheAztec; 31.01.2019
comment
@LoicTheAztec Спасибо, это означает, что у нас не может быть ни идентификатора заказа, ни идентификатора товара, верно? - person Pablo S G Pacheco; 01.02.2019
comment
@PabloSGPacheco Я не уверен, вам нужно попробовать это, например, используя хук woocommerce_checkout_create_order и попытаться сохранить значение $order->get_id() в качестве пользовательских метаданных, чтобы увидеть, получите ли вы целое число, отличное от нуля ... - person LoicTheAztec; 01.02.2019

Кажется, что ловушка теперь также устарела с версии 3.0.4. Я получаю это уведомление:

The The "woocommerce_add_order_item_meta" hook uses out of date data structures and function is deprecated since version 3.0.4. Replace with woocommerce_new_order_item.

Я заменил имя действия «woocommerce_add_order_item_meta» на «woocommerce_new_order_item» в операторе add_action в нарушающем плагине, и уведомление об устаревании исчезает. Проблема в том, что некоторые параметры теперь появляются внутри массива legacy_values. Я использую плагин YITH WooCommerce Product Add Ons, и метаданные продукта, которые должны быть прикреплены к заказу, не принимаются плагином и, следовательно, не сохраняются вместе с заказом. Так что, пока это не будет исправлено в плагине, вам придется жить с уведомлением об устаревании.

person Christer Fernstrom    schedule 25.04.2017
comment
Извините, но woocommerce_new_order_item не заменяйте woocommerce_add_order_item_meta… так это ответ? или вопрос?… Пожалуйста, в обоих случаях вы должны обновить это что-то правильное и протестированное… или удалить, если нет. Спасибо - person LoicTheAztec; 04.05.2017
comment
Хорошо, чтобы было ясно. Ловушка устарела, и вы получите совет в сообщении об устаревании, чтобы использовать другую ловушку. Но, как говорит @LoicTheAztec, этот хук не идеальная замена, потому что параметры выглядят иначе. Итак: не следуйте советам в сообщении об устаревании (если у вас нет полного контроля над кодом). Я всегда стараюсь избавиться от всех уведомлений, но в этом случае мне придется смириться с этим - person Christer Fernstrom; 05.05.2017

Я знаю, что на это был дан ответ, и уже есть принятый ответ. Я просто хотел дать другой способ справиться с этим, не получая фактического сообщения об устаревании (см. ссылка);

add_action('woocommerce_new_order_item', 'saveMetaData', 10, 3); // or use just 2 instead of 3; if you don't need order id

/**
 * Add meta to order item
 *
 * @param int $itemId
 * @param WC_Order_Item_Product|WC_Order_Item_Shipping $item
 * @param int @orderId
*/
function saveMetaData($itemId, $item, $orderId)
{
    if (!isItemValid($item))
    {
        return;
    }

    wc_add_order_item_meta($itemId, 'my_custom_data', $item->legacy_values['my_custom_data']);
}

/**
 * @param WC_Order_Item_Product|WC_Order_Item_Shipping $item
 *
 * @return bool
*/
function isItemValid($item)
{
    return (
        $item instanceof WC_Order_Item_Product &&
        isset($item->legacy_values) &&
        isset($item->legacy_values['my_custom_data']) &&
        !empty($item->legacy_values['my_custom_data'])
    );
}
person Ilgıt Yıldırım    schedule 11.06.2017

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

Дополнительные сведения см. В разделе настройка полей оформления заказа .

person rnevius    schedule 16.04.2015
comment
Прости за это. У меня есть услуга настраиваемого типа сообщения, и когда клиент заполняет форму услуги, я должен добавить продукт (план) в корзину и передать идентификатор услуги этому продукту. который я завершил, теперь хочу передать этот идентификатор для мета-элемента заказа. В корзине будут и другие товары ... - person user3339988; 16.04.2015

Нет, похоже, что ловушка также устарела: Ошибка PHP: ловушка "woocommerce_add_order_item_meta" использует устаревшие структуры данных, а функция устарела, начиная с версии 3.1.2. Замените на woocommerce_new_order_item.

Я также не могу найти его здесь: https://docs.woocommerce.com/wc-apidocs/hook-docs.html

person tperschon    schedule 10.10.2017

Я хотел добавить к ответу Ilgıt Yıldırım: в моем случае мои пользовательские значения не существовали в массиве item-> legacy_values. Чтобы исправить это, я использовал ловушку woocommerce_checkout_create_order_line_item, чтобы добавить пользовательские значения к элементу перед вызовом ловушки woocommerce_new_order_item. Вот пример этого:

add_action ('woocommerce_checkout_create_order_line_item', 'save_values_in_item', PHP_INT_MAX, 4);

функция save_values_in_item ($ item, $ cart_item_key, $ values, $ order) {

                $item->myCustomValues = $values;

}

// ТО вызвать новую ловушку: add_action ('woocommerce_new_order_item', 'add_product_input_fields_to_order_item_meta_wc3', PHP_INT_MAX, 3);

function add_product_input_fields_to_order_item_meta_wc3 ($ item_id, $ item, $ order_id) {

            if ( isset( $item->myCustomValues ) ) 
            {
                  //iterate through array and place desired values into the meta data using the wc_add_order_item_meta function
            }

}

person sc8704    schedule 20.03.2018

Чтобы прояснить ситуацию, эта функция устарела, но крючок все еще в порядке

person Pablo S G Pacheco    schedule 03.07.2015