Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Данные позиции корзины

Иногда покупатель уточняет товар перед покупкой: текст гравировки, дату доставки, подарочную упаковку. Такие данные проходят путь из четырёх шагов: поле на странице товара, сохранение в позиции корзины, показ в корзине, запись в позицию заказа. На каждый шаг — свой хук.

Код урока пишется в 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 обязателен.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.