Хук подписок WooCommerce: получение элементов заказа

WooCommerce 3.0 сломал мое приложение, и я не могу понять, как это исправить сейчас.

У меня есть действие, когда подписка добавляется / изменяется здесь:

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

Это больше не работает, и все кажется защищенным? Как я могу обновить это для работы с 3.0?

add_action( 'woocommerce_subscription_status_changed', 'update_subscription', 10, 3 );
function update_subscription( $id, $old_status, $new_status ) {

    $sitelink_db            = new SSLA_DB_Sitelink();
    $order                  = new WC_Order( $id );
    $items                  = $order->get_items();
    $subscription_type  = '';
    $user_id                = $order->get_user_id();
    $sitelink_domain        = get_post_meta( $order->id, 'ssla_sitelink_url', true );

    foreach ($items as $item) {

        if( "SiteLink Subscription" === $item['name'] ) {
            $subscription_type = $item['brand'];
        }

    }

    $customer_data = array(
        'user_id'               => $user_id,
        'subscription_type'     => $subscription_type,
        'domain_referrer'       => $sitelink_domain,
        'active_subscription'   => $new_status,
        'date_modified'         => date( 'Y-m-d H:i:s' ),
        );

    $sitelink_db->add( $customer_data );

}

В основном мне нужно получить это имя варианта подписки для хранения в моей БД, а также это настраиваемое мета-поле, которое я создал. Что тоже больше не работает


person thatryan    schedule 20.04.2017    source источник
comment
Предполагается, что массивы обратно совместимы, но теперь get_items() возвращает массив из WC_Order_Item объектов, поэтому вам нужно использовать методы получения для получения информации. Я думаю, что по умолчанию он получает товары из заказа, так что класс, вероятно, WC_Order_Item_Product, который расширяет WC_Order_Item. Взгляните на методы получения здесь и здесь   -  person helgatheviking    schedule 20.04.2017
comment
Я не припомню, чтобы brand когда-либо был ключом массива элементов заказа, так что это могло быть частью проблемы. Вам следует включить WP_DEBUG_LOG, чтобы вы могли видеть, что происходит.   -  person helgatheviking    schedule 20.04.2017
comment
Бренд - это индивидуальный вариант, который у меня есть в переменном продукте.   -  person thatryan    schedule 20.04.2017
comment
обновлен с полной функцией   -  person thatryan    schedule 20.04.2017
comment
Да, в целом функция намного лучше. $item теперь WC_Order_Item_Product объект, и, если я предполагаю, никогда не поддерживал фирменный ключ. Итак, бренд - это атрибут вариации?   -  person helgatheviking    schedule 20.04.2017


Ответы (1)


Вот мое лучшее предположение. Тестировать невозможно, так как у меня нет такой же настройки, как у вас.

Несколько заметок:

  1. Объект $subscription передается ловушке woocommerce_subscription_status_changed, так что давайте воспользуемся им.
  2. $order->id следует заменить на $order->get_id() в WC3.0, но мы собираемся использовать объект $subscription (класс заказа подписки расширяет класс заказа, поэтому он похож).
  3. геттеры должны использоваться для объекта WC_Order_Item_Product, который возвращается при прохождении через get_items(), поэтому $item['name'] становится $item->get_name()

Вот полный блок кода:

add_action( 'woocommerce_subscription_status_changed', 'update_subscription', 10, 4 );
function update_subscription( $subscription_id, $old_status, $new_status, $subscription ) {

    $match_this_id = 99; // Change this to the product ID of your special subscription

    $sitelink_db            = new SSLA_DB_Sitelink();

    $items                  = $subscription->get_items();
    $subscription_type  = '';
    $user_id                = $subscription->get_user_id();
    $sitelink_domain        = $subscription->get_meta( 'ssla_sitelink_url' );

    foreach ($items as $item) {

        if( $match_this_id === $item->get_product_id() ) {
            $product = $item->get_product();
            if( $product->is_type( 'variation' ) ){
                $subscription_type = $product->get_attribute( 'brand' );
            }
        }

    }

    $customer_data = array(
        'user_id'               => $user_id,
        'subscription_type'     => $subscription_type,
        'domain_referrer'       => $sitelink_domain,
        'active_subscription'   => $new_status,
        'date_modified'         => date( 'Y-m-d H:i:s' ),
        );

    $sitelink_db->add( $customer_data );

}
person helgatheviking    schedule 20.04.2017
comment
Спасибо, это действительно полезно для понимания необходимого другого подхода. Как узнать, какие методы доступны, например, где вы использовали get_name (), может быть, есть get_title ()? Похоже, что выбор вариантов теперь сделан частью имени, поэтому это ненадежно. - person thatryan; 21.04.2017
comment
В этом случае я бы предложил использовать $item->get_product_id() и используя идентификатор продукта в качестве условного. Вы знаете, какие методы доступны, читая документацию и / или сам код, который, я признаю, намного менее прозрачен, чем возможность var_dump() переменной. - person helgatheviking; 21.04.2017
comment
Спасибо, я использовал идентификатор продукта! Я нашел это, но да, документы для меня жесткие, хех. - person thatryan; 21.04.2017
comment
Привет, @helgatheviking. Есть шанс, что ты ответишь на мой другой вопрос о том, почему я не могу понять мету сейчас в версии 3.0? stackoverflow.com/questions/43532208/ :) большое спасибо. - person thatryan; 21.04.2017