Что такое хук '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) | Графический интерфейс, много возможностей | Зависимость от сторонних плагинов, нагрузка | Для комплексных кастомизаций с множеством полей |