Проблема: автоматическое удаление товаров с нулевым остатком в WooCommerce
Во многих интернет-магазинах на WooCommerce возникает необходимость убирать товары из каталога, если их запас на складе равен нулю. Это предотвращает отображение недоступных товаров и улучшает пользовательский опыт. Однако WooCommerce по умолчанию не удаляет такие товары, а лишь помечает их как «Нет в наличии».
Рассмотрим, как диагностировать проблему, настроить автоматическое удаление и проверить корректность работы, а также разберём частые ошибки и рекомендации по безопасности.
Диагностика проблемы
Для начала убедитесь, что у товаров включён учёт запасов и что остаток действительно уменьшается до нуля.
- В админке откройте карточку товара, вкладка «Запасы».
- Проверьте, включена ли опция «Включить управление запасами».
- Убедитесь, что «Количество на складе» равно 0.
- Проверьте, что настройка «Разрешить покупку при отсутствии товара» отключена (WooCommerce → Настройки → Товары → Запасы).
Если после этих проверок товар всё ещё отображается в каталоге, значит нужен кастомный код для автоматического удаления.
Пошаговое решение: удаление товара при нулевом остатке
Добавим хук, который будет реагировать на изменение количества товара и при достижении нуля автоматически удалять товар.
1. Добавление кода в functions.php или отдельный плагин
add_action('woocommerce_reduce_order_stock', 'remove_product_if_stock_zero', 10, 1);
function remove_product_if_stock_zero($order) {
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product || ! $product->managing_stock()) {
continue;
}
$stock_quantity = $product->get_stock_quantity();
if ($stock_quantity === 0) {
wp_trash_post($product->get_id());
}
}
}
Объяснение:
woocommerce_reduce_order_stock— хук вызывается после уменьшения запасов при заказе.- Функция перебирает товары в заказе, проверяет их остаток.
- Если остаток равен 0, товар отправляется в корзину удалённых записей с помощью
wp_trash_post().
2. Альтернативный хук для массового обновления запасов
Если остатки обновляются вручную или через импорт, можно использовать ежедневный крон для удаления товаров с нулевым остатком:
add_action('wp_loaded', function() {
if (!wp_next_scheduled('remove_zero_stock_products_daily')) {
wp_schedule_event(time(), 'daily', 'remove_zero_stock_products_daily');
}
});
add_action('remove_zero_stock_products_daily', function() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_stock_status',
'value' => 'outofstock',
]
]
];
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
wp_trash_post(get_the_ID());
}
wp_reset_postdata();
}
});
Этот код создаст ежедневное задание, которое будет автоматически удалять все товары со статусом outofstock.
Проверка результата после внедрения
- Создайте или используйте товар с включённым учётом запасов.
- Сделайте заказ, который полностью снимет остаток товара.
- После успешного заказа товар должен быть перемещён в корзину удалённых записей.
- Проверьте в админке WooCommerce → Товары, что товара больше нет в списке активных.
- Если используете крон, проверьте через wp-cli:
и убедитесь, что товары удалились.wp cron event run remove_zero_stock_products_daily
Частые ошибки и их исправление
- Товар не удаляется при нулевом остатке — проверьте, что включён учёт запасов и остатки обновляются корректно.
- Функция не срабатывает при импорте или ручном обновлении запасов — используйте крон-задачу для регулярной проверки.
- Удалённые товары появляются снова — возможно, синхронизация с внешней системой восстанавливает их. В этом случае нужно настроить логику синхронизации с учетом удаления.
- Удаление приводит к ошибкам в заказах — не удаляйте товары, которые уже связаны с активными заказами. Можно вместо удаления менять статус товара на «скрыт» (
private).
Практические советы по безопасности и производительности
- Перед удалением товара лучше отправлять его в корзину удалённых записей, чтобы была возможность восстановления.
- При большом количестве товаров используйте пагинацию в WP_Query для крон-задач, чтобы не перегружать сервер.
- Проверяйте, что удаление не нарушает целостность заказов и отчетов.
- Для улучшения безопасности соблюдайте стандарты WordPress: используйте nonce и права пользователя, если код расширяется для ручного запуска.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы | Использование |
|---|---|---|---|
Хук woocommerce_reduce_order_stock | Мгновенное удаление после заказа | Не срабатывает при ручном обновлении запасов | Для автоматического управления после продажи |
| Крон-задача с WP_Query | Удаление всех товаров со статусом outofstock ежедневно | Задержка до 1 дня; нагрузка при большом каталоге | Для регулярного массового удаления |
| Ручное удаление через админку | Контроль и выборочная очистка | Трудозатратно, требует времени | Малые магазины или временное решение |