Диагностика проблемы: почему товары без склада остаются в каталоге
В WooCommerce товары с нулевым запасом (stock quantity) часто продолжают отображаться в каталоге, если не настроена автоматическая фильтрация или удаление. Это создает неудобства для покупателей и мешает управлению ассортиментом. Основная причина — отсутствие автоматической очистки или скрытия таких товаров.
Проверить наличие товаров без склада можно через админку WooCommerce: Товары > Все товары, отфильтровав по наличию или просматривая столбец "Склад".
Пошаговое решение: автоматическое удаление товаров без склада
1. Создаем WP-Cron задачу для регулярной проверки и удаления товаров
Добавьте следующий код в functions.php вашей темы или в кастомный плагин:
if ( ! wp_next_scheduled( 'auto_delete_out_of_stock_products' ) ) {
wp_schedule_event( time(), 'daily', 'auto_delete_out_of_stock_products' );
}
add_action( 'auto_delete_out_of_stock_products', 'delete_out_of_stock_products' );
function delete_out_of_stock_products() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '='
]
],
'fields' => 'ids',
];
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
foreach ( $query->posts as $product_id ) {
wp_delete_post( $product_id, true );
}
}
}2. Объяснение кода
wp_schedule_eventзапускает событие один раз в день.WP_Queryвыбирает все товары со статусом складаoutofstock.- Цикл удаляет каждый товар полностью (
wp_delete_postсtrueдля обхода корзины).
3. Настройка частоты
Если нужно изменить частоту, можно зарегистрировать кастомный интервал:
add_filter( 'cron_schedules', function( $schedules ) {
$schedules['every_six_hours'] = [
'interval' => 21600, // 6 часов в секундах
'display' => 'Каждые 6 часов'
];
return $schedules;
});И заменить 'daily' на 'every_six_hours' в wp_schedule_event.
Проверка результата после внедрения
- Проверьте, что в WooCommerce есть товары со статусом "нет в наличии" (
outofstock). - Запустите функцию вручную для теста, вызвав
delete_out_of_stock_products()через WP CLI или временно вызвав прямо из темы (не забудьте убрать после теста):
add_action('init', function() {
if ( current_user_can('administrator') && isset($_GET['run_delete_oos']) ) {
delete_out_of_stock_products();
echo 'Удаление выполнено';
exit;
}
});После вызова перейдите по ссылке https://ваш-сайт/?run_delete_oos=1 и проверьте, что товары удалились.
Если все работает, Cron будет удалять такие товары автоматически согласно расписанию.
Частые ошибки и как исправить
- Товары не удаляются: Проверьте, запланировано ли событие Cron — используйте плагин WP Crontrol для просмотра запланированных задач.
- Удаляются не все товары: Проверьте, что статус склада действительно
outofstock. Иногда WPML или кастомные статусы мешают выборке. - Функция вызывается часто и нагружает сайт: уменьшите частоту Cron или добавьте лимит на количество удаляемых товаров за один раз.
- Удаление происходит, но товары остаются в поиске: возможно, нужен сброс кеша — очистите кеш плагинов или CDN.
Практические советы по безопасности и производительности
- Удаляйте товары только при полном понимании последствий — удаление необратимо при
wp_delete_post($id, true). - Для больших магазинов добавьте ограничение на количество удаляемых товаров за один запуск, чтобы избежать таймаута:
$args['posts_per_page'] = 20; // например, 20 товаров за раз- Используйте транзиенты или опции для отслеживания прогресса, если удаление занимает много времени.
- Перед массовым удалением сделайте резервную копию базы данных.
- Если не хотите удалять товары, можно вместо этого скрывать их из каталога с помощью фильтра
woocommerce_product_is_visible.
Альтернативы: удаление через плагин или код
| Метод | Плюсы | Минусы |
|---|---|---|
| Код с WP-Cron (как выше) | Точный контроль, легкость кастомизации, нет лишних плагинов | Требует навыков, может быть сложным для новичков |
| Плагины для очистки каталога | Простота установки, готовый функционал | Могут влиять на производительность, нет гибкости |
| Ручное удаление через админку | Полный контроль над каждым товаром | Не подходит для больших магазинов, требует времени |