Что значит автоматическое удаление товаров после первого заказа в WooCommerce
В WooCommerce иногда возникает задача автоматически удалять товар из каталога после того, как он был куплен один раз. Это актуально для ограниченных тиражей, эксклюзивных предложений или разовых товаров. Автоматизация избавляет от ручного контроля и снижает вероятность ошибки.
Диагностика проблемы: почему товары не удаляются автоматически
Если вы уже пытались реализовать удаление товара по событию первого заказа, но столкнулись с проблемами, проверьте следующее:
- Правильно ли срабатывает хук, связанный с оформлением заказа?
- Имеет ли код необходимые права для удаления товара?
- Учитывается ли вариант товара (variable product) или только простой товар?
- Нет ли конфликтов с другими плагинами, которые блокируют удаление?
Пошаговое решение: как автоматически удалять товар после первого заказа
1. Использование хука woocommerce_thankyou
Этот хук вызывается после успешного оформления заказа и подходит для получения ID заказа и обработки товаров.
2. Код для удаления товаров из заказа
add_action('woocommerce_thankyou', 'wpbook_delete_product_after_first_order', 10, 1);function wpbook_delete_product_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(); $product = wc_get_product($product_id); if (!$product) continue; // Проверяем, был ли товар уже куплен ранее $customer_id = $order->get_user_id(); if ($customer_id) { $orders = wc_get_orders(array( 'customer_id' => $customer_id, 'status' => array('completed', 'processing'), 'exclude' => array($order_id), 'limit' => 1, 'return' => 'ids' )); $already_bought = false; foreach ($orders as $previous_order_id) { $previous_order = wc_get_order($previous_order_id); foreach ($previous_order->get_items() as $prev_item) { if ($prev_item->get_product_id() == $product_id) { $already_bought = true; break 2; } } } // Если товар куплен впервые - удаляем его из базы if (!$already_bought) { wp_delete_post($product_id, true); // Удаляем без возможности восстановления } } }}Обратите внимание, что данный код удаляет товар из базы данных навсегда (второй параметр true в wp_delete_post). Если хотите просто скрыть товар, используйте смену статуса на "черновик".
3. Альтернатива: смена статуса товара вместо удаления
wp_update_post(array( 'ID' => $product_id, 'post_status' => 'draft' // Скрыть товар из каталогаПроверка результата после внедрения
- Сделайте тестовый заказ с новым пользователем на товар.
- После оплаты проверьте, исчез ли товар из каталога.
- Попробуйте заново заказать этот товар другим пользователем — он должен быть недоступен.
Можно дополнительно проверить вручную через админку, что товар удалён или скрыт.
Частые ошибки и как их исправить
- Хук не срабатывает: Убедитесь, что функция подключена в файле
functions.phpили в плагине и что плагин или тема не переопределяют хук. - Нет прав на удаление: Если код работает под пользователем без прав администратора, удаление не произойдёт. Выполняйте удаление от имени администратора.
- Удаление не происходит для вариаций: В коде учитывается ID родительского продукта. Для вариаций нужно дополнительно проверять
$item->get_variation_id()и удалять вариацию отдельно. - Удаление товара с зависимостями: Если товар связан с заказами или другими сущностями, удаление может вызвать ошибки. Лучше использовать смену статуса.
Практические советы по безопасности и производительности
- Всегда делайте резервную копию базы данных перед автоматическим удалением товаров.
- Вместо удаления используйте перевод товара в статус
draftилиprivate— это уменьшит риск поломок и позволит восстановить товар. - Добавляйте логи действий для отслеживания, какие товары были удалены и когда.
- Оптимизируйте запросы к базе, чтобы не перегружать сервер при большом количестве заказов.
Сравнение вариантов реализации автоматического удаления
| Метод | Плюсы | Минусы | Пример кода |
|---|---|---|---|
Удаление через wp_delete_post | Полное удаление товара, освобождение места в базе | Риск потери данных, возможные ошибки при связанных данных | В статье выше |
Смена статуса на draft | Безопасно, товар можно восстановить | Товар остается в базе, занимает место | wp_update_post(['ID' => $product_id, 'post_status' => 'draft']); |
| Использование плагина для управления статусами | Простота, управление через интерфейс | Дополнительный плагин, нагрузка | Плагины типа "WooCommerce Product Status Manager" |