Мета
Працювати з товарами і замовленнями лише через CRUD-об'єкти і розуміти, навіщо потрібен шар data store.
Ключові поняття
WC_Data— базовий клас дляWC_Product,WC_Order,WC_Customer,WC_Coupon- Getters / setters:
get_price(),set_regular_price(); зміни застосовуються наsave() - Мета:
get_meta(),update_meta_data(),delete_meta_data()+save() - Data store — клас, що знає, де і як зберігати об'єкт (пости, HPOS, власні таблиці)
wc_get_product(),wc_get_order(),wc_get_products(),wc_get_orders()— точки входу- Хуки
woocommerce_before_{object}_object_save/woocommerce_after_{object}_object_save
Схема
flowchart LR
CODE["Ваш код"] -->|"set_*(), save()"| OBJ["WC_Order / WC_Product"]
OBJ --> DS{"Data store"}
DS -->|HPOS увімкнено| HPOS[("wc_orders ...")]
DS -->|HPOS вимкнено| POSTS[("wp_posts + wp_postmeta")]
DS --> CACHE["Кеш, lookup-таблиці,<br/>хуки, інвалідація"]
Код
Правильно: зміни через CRUD.
<?php
$product = wc_get_product( $product_id );
if ( ! $product ) {
return;
}
$product->set_regular_price( '499' );
$product->set_sale_price( '399' );
$product->update_meta_data( '_supplier_code', 'SUP-1042' );
$product->save(); // оновить lookup-таблицю, кеш і викличе хуки
$order = wc_get_order( $order_id );
$order->update_meta_data( '_erp_id', 'ERP-778' );
$order->add_order_note( 'Синхронізовано з ERP' );
$order->save();
Неправильно: обхід CRUD.
<?php
update_post_meta( $product_id, '_price', 399 ); // lookup-таблиця і кеш застаріли
update_post_meta( $order_id, '_erp_id', 'ERP-778' ); // з HPOS не потрапить у wc_orders_meta
Типові помилки
| Симптом | Причина | Виправлення |
|---|---|---|
| Ціна оновилась у адмінці, але фільтр показує стару | update_post_meta( _price ) в обхід CRUD | set_regular_price() + save() |
| Мета замовлення «зникає» після ввімкнення HPOS | Код пише через update_post_meta() | $order->update_meta_data() + save() |
| Зміни не збереглись | Забули save() | Сетери лише змінюють об'єкт у пам'яті |
| Нескінченний цикл | save() всередині woocommerce_after_product_object_save | Знімати хук перед save() або робити зміни в before_* |
Слабка і сильна відповідь
Питання: Як змінити ціну товару програмно?
Слабка відповідь.
update_post_meta( $id, '_price', 100 ).
Сильна відповідь. Через CRUD:
$product = wc_get_product( $id ); $product->set_regular_price( '100' ); $product->save();.save()проходить через data store: оновлює lookup-таблицю, кеш, викликає хуки. Для варіативного товару ціна задається на кожній варіації.
Чому друга сильніша: Кандидат пояснює, що саме ламається в обхід CRUD, і згадує нюанс з варіаціями.
Практичне завдання
Напишіть WP-CLI eval або невеликий плагін: знайдіть товар за SKU (wc_get_product_id_by_sku()), змініть ціну зі знижкою 10% і додайте мета-поле _last_price_update з датою. Перевірте, що ціна в каталозі з фільтром оновилась.
Питання з інтерв'ю
Клас, який відповідає за збереження і читання конкретного типу об'єкта. CRUD-об'єкт не знає, де лежать дані. Тому HPOS вдалося ввести без зміни публічного API: змінився лише data store замовлень.
Приймає параметри в термінах WooCommerce (price, stock_status, sku, visibility), сам будує запит і повертає об'єкти WC_Product. Код не залежить від того, як дані лежать у таблицях.
Хук woocommerce_after_order_object_save — він спрацьовує незалежно від того, звідки зберегли замовлення: адмінка, REST, checkout, CLI.