Диагностика задачи: зачем ограничивать количество покупок товара
В интернет-магазинах на WooCommerce иногда возникает необходимость ограничить количество покупок определённого товара одним пользователем. Это могут быть лимиты на акции, дефицитный товар, или правила оптовых закупок. По умолчанию WooCommerce не предоставляет встроенных средств для установки таких ограничений, поэтому нужно реализовать кастомное решение.
Пошаговое решение: добавляем ограничение на количество покупок товара
1. Определяем товар и лимит
Для примера ограничим покупку товара с ID 123 до 3 штук для каждого пользователя. Мы будем проверять, сколько уже куплено товаров этого ID, и не позволять добавить в корзину больше.
2. Используем хук woocommerce_add_to_cart_validation для проверки покупки
Этот хук позволяет перехватить добавление товара в корзину и отменить его с сообщением об ошибке, если условие не выполнено.
add_filter('woocommerce_add_to_cart_validation', 'limit_product_purchase_quantity', 10, 3);
function limit_product_purchase_quantity($passed, $product_id, $quantity) {
$limit_product_id = 123; // ID товара
$max_quantity = 3; // максимум на покупателя
if ($product_id == $limit_product_id && is_user_logged_in()) {
$user_id = get_current_user_id();
// Получаем общее количество купленного товара
$total_bought = 0;
$orders = wc_get_orders(array(
'customer_id' => $user_id,
'status' => array('completed', 'processing'),
'limit' => -1
));
foreach ($orders as $order) {
foreach ($order->get_items() as $item) {
if ($item->get_product_id() == $limit_product_id) {
$total_bought += $item->get_quantity();
}
}
}
// Количество в корзине
$cart_quantity = 0;
foreach (WC()->cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] == $limit_product_id) {
$cart_quantity += $cart_item['quantity'];
}
}
// Проверяем лимит
if (($total_bought + $cart_quantity + $quantity) > $max_quantity) {
wc_add_notice(sprintf('Вы можете купить не более %d единиц этого товара.', $max_quantity), 'error');
return false;
}
}
return $passed;
}
3. Дополнительно: показываем предупреждение на странице товара
Чтобы пользователь видел ограничение заранее, добавим уведомление на страницу товара с ID 123.
add_action('woocommerce_single_product_summary', 'show_purchase_limit_notice', 20);
function show_purchase_limit_notice() {
global $product;
if ($product->get_id() == 123) {
echo '<p class="woocommerce-info">Максимальное количество для покупки: 3 шт.</p>';
}
}
Проверка результата после внедрения
- Авторизуйтесь под пользователем, который уже купил 2 единицы товара с ID 123;
- Попробуйте добавить в корзину 2 единицы того же товара;
- Убедитесь, что появилось сообщение об ошибке и добавить нельзя;
- Повторите тест с новым пользователем без покупок — добавление до 3 единиц разрешено;
- Проверьте, что уведомление на странице товара отображается корректно.
Частые ошибки и как их исправить
- Не учитываются все заказы пользователя: Проверьте, что статусы
completedиprocessingвключены в выборку. Если нужны другие статусы — добавьте их в массив. - Лимит игнорируется при изменении количества в корзине: Учтите, что проверка должна учитывать уже добавленные товары в корзине. В коде мы суммируем
$cart_quantity. - Ограничение не работает для гостей: В коде проверка
is_user_logged_in()исключает гостей. Если нужно ограничивать гостей — потребуется хранить данные по IP или куки, что менее надежно. - Код не работает при AJAX-добавлении в корзину: Проверьте, что хук применяется и сообщения об ошибках выводятся корректно в AJAX.
Практические советы по безопасности и производительности
- Запрос заказов для подсчёта купленного количества может быть ресурсоёмким на больших магазинах. Для оптимизации можно кэшировать результат с помощью
set_transientна 5-10 минут, сбрасывая кэш при создании новых заказов. - Для более гибкого управления лимитами можно создавать пользовательские поля товара и считать лимит динамически.
- Избегайте прямых SQL-запросов, используйте API WooCommerce для совместимости и безопасности.
- Всегда проверяйте, что пользователь авторизован перед выборкой заказов, чтобы не раскрывать данные чужих пользователей.
Сравнение вариантов реализации ограничения
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Код на woocommerce_add_to_cart_validation | Проверка при добавлении товара в корзину | Гибко, без плагинов, легко кастомизировать | Нагрузка при большом количестве заказов, требует кэширования |
| Плагин с ограничениями покупок | Готовое решение с настройками | Простота установки, поддержка | Может быть платным, избыточный функционал |
| Ограничение на уровне темы | Отображение предупреждений и блокировка UI | Хорошо для UX | Не предотвращает обход через прямые запросы |