Диагностика задачи: зачем удалять товар после продажи
В WooCommerce бывают ситуации, когда нужно автоматически удалить товар из каталога сразу после его продажи. Например, это может быть уникальный товар с ограниченным количеством 1 (one-of-a-kind), цифровой продукт с лицензией на одного пользователя или эксклюзивная услуга. В стандартном WooCommerce нет встроенного механизма для автоматического удаления товара после успешной продажи, поэтому требуется кастомное решение.
Как определить событие для удаления товара
Для удаления товара после продажи необходимо отслеживать статус заказа. Обычно логично выполнять удаление при переходе заказа в статус completed, так как это означает, что оплата прошла и заказ обработан.
Для этого используем хук WordPress woocommerce_order_status_completed. Он срабатывает при изменении статуса заказа на "завершен".
Пример кода для удаления товара после продажи
add_action('woocommerce_order_status_completed', 'wc_delete_product_after_sale');
function wc_delete_product_after_sale($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 && get_post_type($product_id) === 'product') {
wp_delete_post($product_id, true); // true - удаляет без перехода в корзину
}
}
}В этом коде мы проходим по всем товарам в заказе и удаляем их из базы данных WordPress сразу после смены статуса заказа на "завершен".
Пошаговое решение с доработками
1. Создайте дочерний плагин или используйте файл functions.php темы
Добавьте приведённый выше код в файл functions.php вашей активной темы или в отдельный плагин, чтобы изменения не потерялись при обновлениях.
2. Ограничение удаления по условию
Часто нужно удалять не все товары, а только определённые. Например, товары с мета-полем delete_after_sale или товары определённой категории.
add_action('woocommerce_order_status_completed', 'wc_delete_product_after_sale_conditional');
function wc_delete_product_after_sale_conditional($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;
// Проверяем пользовательское поле
$delete_flag = get_post_meta($product_id, 'delete_after_sale', true);
if ($delete_flag !== 'yes') continue;
wp_delete_post($product_id, true);
}
}Теперь удалятся только товары с мета-ключом delete_after_sale, установленным в значение yes.
3. Добавление мета-поля через интерфейс
Для удобства добавьте мета-поле delete_after_sale в карточку товара. Это можно сделать через плагин Advanced Custom Fields (ACF) или вручную через add_meta_box.
Проверка результата после внедрения
- Создайте тестовый товар и установите мета-поле
delete_after_sale = yes. - Оформите заказ с этим товаром и оплатите его.
- Переведите заказ в статус "завершён" (completed) через админку WooCommerce.
- Проверьте, что товар исчез из списка товаров в админке (Товары > Все товары).
- Попробуйте открыть URL товара на сайте — должна быть ошибка 404.
Частые ошибки и как их исправить
- Товар не удаляется после смены статуса: Проверьте, что хук
woocommerce_order_status_completedсрабатывает. Добавьте временныйerror_logв функцию для отладки. - Удаляются все товары, а нужно только некоторые: Добавьте условие по мета-полю или категории, чтобы исключить нежелательные товары.
- Ошибка при удалении товара: Убедитесь, что у пользователя, под которым работает WordPress, есть права на удаление постов. Также проверяйте, что
wp_delete_postвызывается с правильным ID и вторым параметромtrueдля полного удаления. - Потеря данных или SEO-проблемы: При полном удалении товара URL становится недоступен. Если нужно сохранить URL, рассмотрите вариант пометки товара как "скрытый" или "черновик", вместо удаления.
Практические советы по безопасности и производительности
- Удаление товара — необратимая операция, поэтому сделайте резервную копию базы данных перед внедрением.
- Если товар связан с другими плагинами (например, подписками, рейтингами), проверьте совместимость и возможные ошибки.
- Для массовых заказов с большим количеством товаров удаление может замедлить обработку — при необходимости оптимизируйте код или используйте WP-Cron для асинхронного удаления.
- Вместо удаления можно рассмотреть перевод товара в статус "черновик" (
wp_update_post(['ID' => $product_id, 'post_status' => 'draft'])), чтобы сохранить данные и SEO.
Сравнение способов реализации автоматического удаления товаров
| Метод | Преимущества | Недостатки |
|---|---|---|
Полное удаление через wp_delete_post | Полное удаление данных, освобождение места в базе | Потеря URL, SEO, необратимость |
| Перевод в статус "черновик" | Сохраняет данные и URL, можно восстановить | Товар виден в админке, но скрыт от покупателей |
| Использование пользовательских меток / категорий | Гибкость управления видимостью | Не освобождает место в базе |