Диагностика задачи: зачем удалять товар после первого заказа
В WooCommerce иногда возникает необходимость автоматически удалять товар из каталога сразу после того, как он был куплен впервые. Чаще всего это связано с ограниченными тиражами, эксклюзивными предложениями или акционными товарами, которые должны быть доступны ровно одному покупателю.
Стандартных настроек WooCommerce для такой логики нет, поэтому требуется кастомизация через хук, который сработает после успешного оформления заказа.
Пошаговое решение: автоматическое удаление товара после первого заказа
1. Подключение функции к хуку завершения заказа
Для начала добавим обработчик на событие woocommerce_order_status_completed, которое срабатывает при смене статуса заказа на «завершён».
add_action('woocommerce_order_status_completed', 'wp7_remove_products_after_first_order', 10, 1);2. Логика проверки и удаления товара
В функции получаем заказ, перебираем все товары внутри, проверяем, был ли товар заказан ранее кем-то (по заказам с предыдущими статусами), и если это первый заказ с этим товаром — удаляем товар из каталога.
function wp7_remove_products_after_first_order($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
if (!$product_id) continue;
// Проверяем, есть ли заказы с этим товаром, кроме текущего
$args = [
'limit' => 1,
'status' => ['completed', 'processing', 'on-hold'],
'exclude' => [$order_id],
'return' => 'ids',
];
$orders_with_product = wc_get_orders($args);
$found = false;
foreach ($orders_with_product as $prev_order_id) {
$prev_order = wc_get_order($prev_order_id);
if (!$prev_order) continue;
foreach ($prev_order->get_items() as $prev_item) {
if ($prev_item->get_product_id() == $product_id) {
$found = true;
break 2;
}
}
}
// Если товар еще не был заказан ранее - удаляем
if (!$found) {
// Удаляем товар из каталога
wp_trash_post($product_id);
}
}
}Проверка результата после внедрения
- Оформите тестовый заказ с новым товаром.
- После смены статуса заказа на «завершён» зайдите в каталог товаров и проверьте, что товар перемещён в корзину (Trash).
- Оформите второй заказ с тем же товаром — он должен быть недоступен для выбора или уже отсутствовать.
Частые ошибки и как их исправить
- Ошибка: Товар не удаляется после заказа.
Причина: Хук не срабатывает, возможно, заказ не переходит в статус «завершён».
Решение: Проверьте, что вы используете правильный хук и что статус заказа изменяется на «completed». - Ошибка: Функция удаляет все товары, даже если они были куплены ранее.
Причина: Некорректная логика проверки наличия товара в предыдущих заказах.
Решение: Убедитесь, что исключаете текущий заказ из поиска и перебираете все старые заказы. - Ошибка: Удалённые товары не появляются в корзине, а полностью пропадают.
Решение: Используйтеwp_trash_post()вместоwp_delete_post()для возможности восстановления товара через админку.
Практические советы по безопасности и производительности
- Используйте
wp_trash_post()вместо полного удаления, чтобы избежать потери данных и случайных ошибок. - Не запускайте тяжелые запросы в цикле товаров без кеширования — при большом количестве заказов это может замедлить сайт.
- При необходимости добавьте логирование действий для отладки через
error_log()или специальные плагины.
Сравнение подходов: плагин vs кастомный код
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Плагин | Быстрое внедрение, поддержка обновлений | Может быть избыточным, снижать производительность | Использовать проверенные и легковесные решения |
| Кастомный код | Точный контроль, легкий и адаптируемый | Требует навыков и тестирования | Использовать в качестве расширения для уникальных задач |