Данные позиции корзины
Иногда покупатель уточняет товар перед покупкой: текст гравировки, дату доставки, подарочную упаковку. Такие данные проходят путь из четырёх шагов: поле на странице товара, сохранение в позиции корзины, показ в корзине, запись в позицию заказа. На каждый шаг — свой хук.
Код урока пишется в includes/cart.php.
Шаг 1. Поле на странице товара
// wp-content/plugins/acme-shop/includes/cart.php
add_action('woocommerce_before_add_to_cart_button', function () {
echo '<p class="acme-engraving">
<label for="acme_engraving">Гравировка (до 20 символов)</label>
<input type="text" id="acme_engraving" name="acme_engraving" maxlength="20">
</p>';
});Хук срабатывает внутри формы покупки, поэтому поле отправится вместе с нажатием «В корзину». Откройте страницу товара — над кнопкой появилось текстовое поле.
Шаг 2. Сохранение в позиции
// wp-content/plugins/acme-shop/includes/cart.php
add_filter('woocommerce_add_cart_item_data', function (array $data, int $productId): array {
$text = sanitize_text_field(wp_unslash($_POST['acme_engraving'] ?? ''));
if ($text !== '') {
$data['acme_engraving'] = mb_substr($text, 0, 20);
}
return $data;
}, 10, 2);Фильтр получает массив собственных данных позиции и возвращает его дополненным. sanitize_text_field() убирает из ввода теги и лишние пробелы. Товары с разной надписью лягут в корзину отдельными позициями: данные участвуют в ключе позиции.
Шаг 3. Показ в корзине
// wp-content/plugins/acme-shop/includes/cart.php
add_filter('woocommerce_get_item_data', function (array $rows, array $item): array {
if (isset($item['acme_engraving'])) {
$rows[] = [
'key' => 'Гравировка',
'value' => $item['acme_engraving'],
];
}
return $rows;
}, 10, 2);Введите «Анне» в поле, нажмите «В корзину» и откройте /cart/: под названием товара появится строка «Гравировка: Анне». Та же строка видна на странице оформления заказа.
Шаг 4. Запись в заказ
Корзина исчезает после оформления, поэтому данные переносят в позицию заказа:
// wp-content/plugins/acme-shop/includes/cart.php
add_action('woocommerce_checkout_create_order_line_item', function (WC_Order_Item_Product $item, string $cartItemKey, array $values) {
if (isset($values['acme_engraving'])) {
$item->add_meta_data('Гравировка', $values['acme_engraving']);
}
}, 10, 3);Третий аргумент $values — та самая позиция корзины с вашими данными. Оформите заказ: надпись видна в письме покупателю, на странице «Заказ принят» и в панели в «WooCommerce → Заказы» под названием товара.
Чтение из заказа
foreach ($order->get_items() as $item) {
$text = $item->get_meta('Гравировка');
}Ключ метаданных без подчёркивания в начале показывается покупателю и менеджеру как подпись. Ключ с подчёркиванием, например _acme_engraving_font, скрыт — так хранят служебные значения.
Доплата за гравировку
Данные позиции доступны и при расчёте цены:
// wp-content/plugins/acme-shop/includes/cart.php
add_action('woocommerce_before_calculate_totals', function (WC_Cart $cart) {
foreach ($cart->get_cart() as $item) {
if (isset($item['acme_engraving'])) {
$item['data']->set_price((float) $item['data']->get_regular_price() + 2);
}
}
});Кружка с гравировкой станет на 2 € дороже.
Частая ошибка
Делают только первые три шага. В корзине надпись видна, заказ оформлен — а в заказе её нет, и мастер не знает, что гравировать. Данные корзины не попадают в заказ сами: четвёртый шаг с woocommerce_checkout_create_order_line_item обязателен.