Диагностика задачи: зачем удалять товар после первого заказа
В ряде бизнес-сценариев требуется убирать товар из магазина сразу после того, как он был заказан впервые. Например, эксклюзивные предложения, лимитированные серии или услуги с ограниченным количеством. В WooCommerce стандартных настроек для этого нет, поэтому все реализуется через кастомный код.
Пошаговое решение: автоматическое удаление товара после первого заказа
1. Определяем событие для срабатывания кода
Лучше всего использовать хук woocommerce_order_status_completed, который срабатывает при смене статуса заказа на «завершен».
2. Получаем товары из заказа и удаляем их
Ниже пример кода, который проверяет каждый товар в заказе и удаляет его из базы данных WordPress, если это первый заказ с этим товаром.
add_action('woocommerce_order_status_completed', 'wp7_delete_products_after_first_order', 10, 1);
function wp7_delete_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();
// Проверяем, существует ли еще заказы с этим товаром, кроме текущего
$args = [
'limit' => 1,
'status' => ['completed','processing'],
'exclude' => [$order_id],
'return' => 'ids',
'meta_query' => [
[
'key' => '_product_id',
'value' => $product_id,
'compare' => '=',
]
]
];
// Используем WC_Order_Query для поиска заказов с этим товаром
$orders_with_product = wc_get_orders($args);
// Если других заказов с этим товаром нет, удаляем товар
if (empty($orders_with_product)) {
wp_delete_post($product_id, true); // true - безвозвратно
}
}
}
Объяснение: код получает все товары из завершенного заказа, проверяет есть ли другие завершенные или в обработке заказы с этим товаром (кроме текущего) и если таких нет, то удаляет товар.
3. Добавляем код в functions.php или в кастомный плагин
Лучше использовать кастомный плагин, чтобы не потерять изменения при обновлении темы.
Проверка результата после внедрения
- Создайте тестовый товар в WooCommerce.
- Сделайте заказ этого товара и переведите заказ в статус «завершен».
- Проверьте, что товар удалился из списка товаров (Товары > Все товары).
- Создайте второй заказ с этим же товаром (если хотите проверить, что он не удалится, если есть другие заказы).
Частые ошибки и как исправить
- Товар не удаляется: убедитесь, что заказ действительно в статусе «завершен» и что
woocommerce_order_status_completedсрабатывает. Можно добавитьerror_logдля отладки. - Удаляется неверный товар: проверьте, что берется правильный ID товара, а не вариации или другие посты.
- Функция удаляет товар при каждом заказе: убедитесь, что проверка других заказов работает правильно. Можно логировать запросы.
- Проблемы с производительностью: при большом количестве заказов запросы к базе могут быть тяжелыми. Можно оптимизировать запрос или делать удаление через WP Cron.
Практические советы по безопасности и производительности
- Используйте
wp_delete_post($product_id, true)с осторожностью — удаление безвозвратно. Если сомневаетесь, сначала переводите товар в черновик ('post_status' => 'draft'). - Добавляйте логирование удалений в отдельный файл для контроля.
- Если в магазине много заказов, рассмотрите реализацию отложенного удаления товаров через планировщик (
wp_schedule_single_event). - Проверяйте права пользователя, под которым выполняется скрипт, чтобы избежать ошибок с доступом.
Сравнение вариантов реализации удаления товара после заказа
| Вариант | Преимущества | Недостатки |
|---|---|---|
Код на хуке woocommerce_order_status_completed | Простая реализация, автоматическая обработка | Риск нагрузки при большом количестве товаров и заказов |
| Удаление через WP Cron (отложенный) | Меньшая нагрузка, можно контролировать время удаления | Сложнее в реализации, задержка удаления |
| Ручное удаление через админку | Максимальный контроль | Трудозатратно, не автоматизировано |