Диагностика задачи: зачем удалять товары по статусу заказов
В WooCommerce иногда требуется автоматически убирать из магазина товары, которые связаны с определёнными статусами заказов. Например, если товар оказался в заказе со статусом «отменён» или «возврат», можно автоматически удалить или скрыть такой товар, чтобы не показывать его покупателям. Это помогает поддерживать актуальность каталога и снижает ошибочные продажи.
Как понять, что автоматическое удаление необходимо именно вам
- В магазине часто остаются товары, которые не должны быть доступны после определённого статуса заказа.
- Ручное управление товарами занимает слишком много времени и приводит к ошибкам.
- Нужно избежать продаж товаров, которые уже не доступны или требуют удаления.
Пошаговое решение: автоматическое удаление товаров по статусу заказа
1. Использование хука woocommerce_order_status_changed
WooCommerce предоставляет хук woocommerce_order_status_changed, который срабатывает при изменении статуса заказа. На его основе можно написать функцию, которая определит статус и удалит товары из магазина.
2. Пример кода для functions.php темы или плагина
add_action('woocommerce_order_status_changed', 'wpbit_delete_products_by_order_status', 10, 4);
function wpbit_delete_products_by_order_status($order_id, $old_status, $new_status, $order) {
// Указываем статусы, при которых нужно удалять товары
$statuses_to_delete = array('cancelled', 'refunded');
if (in_array($new_status, $statuses_to_delete)) {
// Получаем все товары из заказа
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
// Проверяем, существует ли товар
if (get_post_status($product_id)) {
// Удаляем товар (перемещаем в корзину)
wp_trash_post($product_id);
}
}
}
}
В этом примере товары из заказа будут отправлены в корзину на удаление при смене статуса заказа на cancelled или refunded. Это безопаснее полного удаления.
3. Альтернативный вариант — скрывать товары, а не удалять
Удаление товара — необратимый процесс. Если хотите временно скрыть товары, измените их статус на draft:
wp_update_post(array(
'ID' => $product_id,
'post_status' => 'draft'
));
Проверка результата после внедрения
Чтобы проверить, что автоматическое удаление сработало:
- Создайте тестовый заказ с нужными товарами.
- Измените статус заказа на один из целевых (например, «отменён»).
- Проверьте в админке, что товары перешли в корзину или стали черновиками.
- Проверьте, что товары больше не отображаются на сайте.
Для отладки полезно добавить логи, например, через error_log:
error_log('Product '. $product_id .' moved to trash due to order status '. $new_status);
Частые ошибки и как их исправить
- Ничего не происходит после изменения статуса заказа: убедитесь, что функция подключена, а хук правильно добавлен. Проверьте, что статус заказа действительно меняется на нужный.
- Удаляются не те товары: убедитесь, что вы используете
$item->get_product_id(), а не$item->get_variation_id(), если хотите удалять родительские товары. Возможно, надо учитывать вариации отдельно. - Удаление товаров приводит к ошибкам на сайте: проверьте, что в магазине нет ссылок на удалённые товары. Возможно, лучше использовать скрытие через изменение статуса.
- Функция срабатывает несколько раз: хук вызывается на каждый статус; добавьте дополнительную проверку или кеширование, чтобы избежать повторных действий.
Практические советы по безопасности и производительности
- Используйте
wp_trash_post()вместоwp_delete_post()для возможности восстановления товаров. - Ограничьте список статусов, чтобы избежать случайного удаления.
- Добавьте проверку прав пользователя, если функция вызывается в контексте админки.
- Если заказ содержит много товаров, учитывайте нагрузку на сервер при массовом удалении.
- Для крупных магазинов рассмотрите реализацию фоновых задач через WP-Cron или сторонние очереди, чтобы не замедлять работу сайта.
Сравнение вариантов удаления товаров по статусу заказа
| Метод | Описание | Преимущества | Недостатки |
|---|---|---|---|
| Удаление в корзину (wp_trash_post) | Перемещение товара в корзину на удаление | Безопасно, можно восстановить | Товары остаются в базе, занимают место |
| Смена статуса на draft | Скрытие товара без удаления | Быстро, безопасно, товары можно вернуть | Товары видны в админке, могут мешать |
| Полное удаление (wp_delete_post) | Удаление товара из базы данных | Освобождение места, чистая база | Риск потери данных, необратимо |