wpmake.ru wordpress WPMake

Использование хука WooCommerce 'woocommerce_before_add_to_cart_button' для добавления дополнительных полей на страницу товара

Что такое хук 'woocommerce_before_add_to_cart_button' и зачем он нужен

Хук woocommerce_before_add_to_cart_button — это action-хук, который выполняется непосредственно перед кнопкой «Добавить в корзину» на странице товара WooCommerce. Он позволяет вывести любой дополнительный HTML или PHP-код, например, дополнительные поля для сбора информации от пользователя или подсказки.

Этот хук полезен, если нужно расширить стандартный функционал страницы продукта без создания отдельного шаблона.

Диагностика: как понять, что хук сработал

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

add_action('woocommerce_before_add_to_cart_button', function() {
    echo '<p>Хук сработал!</p>';
});

Зайдите на страницу любого продукта в WooCommerce — перед кнопкой «Добавить в корзину» должен появиться текст «Хук сработал!». Если текста нет, проверьте, что шаблон товара не переопределён и использует стандартные хуки WooCommerce.

Пошаговое решение: добавляем поле "Номер для гравировки" на страницу товара

1. Добавление поля через хук

add_action('woocommerce_before_add_to_cart_button', 'add_custom_gravirovka_field');
function add_custom_gravirovka_field() {
    echo '<div class="gravirovka-field">';
    echo '<label for="gravirovka_number">Номер для гравировки (макс. 10 символов):</label>';
    echo '<input type="text" id="gravirovka_number" name="gravirovka_number" maxlength="10" pattern="[A-Za-z0-9]+" />';
    echo '</div>';
}

2. Валидация поля при добавлении в корзину

Для проверки введённого значения используйте фильтр woocommerce_add_to_cart_validation:

add_filter('woocommerce_add_to_cart_validation', 'validate_gravirovka_field', 10, 3);
function validate_gravirovka_field($passed, $product_id, $quantity) {
    if (isset($_POST['gravirovka_number'])) {
        $value = sanitize_text_field($_POST['gravirovka_number']);
        if (strlen($value) > 10 || !preg_match('/^[A-Za-z0-9]+$/', $value)) {
            wc_add_notice('Номер для гравировки должен содержать не более 10 буквенно-цифровых символов.', 'error');
            return false;
        }
    } else {
        wc_add_notice('Пожалуйста, укажите номер для гравировки.', 'error');
        return false;
    }
    return $passed;
}

3. Сохранение данных в мета корзины

Чтобы сохранить введённое значение вместе с товаром в корзине, используйте хук woocommerce_add_cart_item_data:

add_filter('woocommerce_add_cart_item_data', 'save_gravirovka_field_cart', 10, 2);
function save_gravirovka_field_cart($cart_item_data, $product_id) {
    if (!empty($_POST['gravirovka_number'])) {
        $cart_item_data['gravirovka_number'] = sanitize_text_field($_POST['gravirovka_number']);
        // Чтобы не объединять с другими товарами без гравировки
        $cart_item_data['unique_key'] = md5(microtime().rand());
    }
    return $cart_item_data;
}

4. Отображение данных в корзине и заказе

Добавьте вывод дополнительного поля в корзине и заказе с помощью фильтров:

add_filter('woocommerce_get_item_data', 'display_gravirovka_cart', 10, 2);
function display_gravirovka_cart($item_data, $cart_item) {
    if (!empty($cart_item['gravirovka_number'])) {
        $item_data[] = array(
            'key'   => 'Номер для гравировки',
            'value' => wc_clean($cart_item['gravirovka_number'])
        );
    }
    return $item_data;
}
add_action('woocommerce_checkout_create_order_line_item', 'add_gravirovka_to_order_items', 10, 4);
function add_gravirovka_to_order_items($item, $cart_item_key, $values, $order) {
    if (!empty($values['gravirovka_number'])) {
        $item->add_meta_data('Номер для гравировки', $values['gravirovka_number']);
    }
}

Проверка результата после внедрения

  • На странице товара появилось поле «Номер для гравировки» перед кнопкой «Добавить в корзину».
  • При добавлении товара без заполнения или с некорректным значением выводится ошибка.
  • В корзине рядом с товаром отображается введённый номер гравировки.
  • В оформленном заказе в админке и письмах присутствует мета-информация по гравировке.

Частые ошибки и их исправление

  • Поле не отображается: проверьте, что шаблон товара не переопределён и содержит вызов do_action('woocommerce_before_add_to_cart_button').
  • Данные не сохраняются в корзине: убедитесь, что используете уникальный ключ unique_key в woocommerce_add_cart_item_data для предотвращения объединения товаров.
  • Валидация не срабатывает: проверьте правильность обработки $_POST и добавление ошибок через wc_add_notice с типом 'error'.
  • Данные не видны в заказе: проверьте, что используете хук woocommerce_checkout_create_order_line_item и добавляете мета-данные через $item->add_meta_data().

Практические советы по безопасности и производительности

  • Обязательно используйте sanitize_text_field для очистки пользовательского ввода.
  • Добавляйте атрибуты maxlength и pattern в HTML-поле для базовой фронтенд-валидации.
  • Не храните чувствительные данные в пользовательских полях без шифрования.
  • Минимизируйте количество дополнительных запросов и операций в хуках, чтобы не замедлять загрузку страницы товара.

Сравнение вариантов реализации

СпособПлюсыМинусыКогда использовать
Добавление поля через хук woocommerce_before_add_to_cart_buttonПростота, быстрое внедрение, совместимость с большинством темОграничено областью вывода, зависит от шаблонаДля простых дополнительных полей на странице товара
Переопределение шаблона single-product/add-to-cart/simple.phpПолный контроль над формой и выводомТребует поддержки при обновлениях WooCommerce, сложнее в реализацииЕсли нужна глубокая кастомизация формы товара
Использование плагинов для кастомных полей товара (например, Advanced Custom Fields)Графический интерфейс, много возможностейЗависимость от сторонних плагинов, нагрузкаДля комплексных кастомизаций с множеством полей
×
WPRemark
Внимание Внимание Внимание Внимание
-15%

на WPRemark плагин WordPress

Прокачай свой сайт! ⋙