Диагностика проблемы: почему товары остаются в каталоге при нулевом запасе
В стандартной конфигурации WooCommerce товары с количеством на складе 0 могут продолжать отображаться в каталоге, если не настроено правильное управление запасами или видимость. Это приводит к негативному UX — пользователи видят товары, которых нельзя купить. Часто владельцы магазинов хотят полностью скрывать или удалять такие товары из публичного каталога.
Проверка текущих настроек управления запасами
Перейдите в WooCommerce > Настройки > Товары > Запасы и убедитесь, что включена опция Включить управление запасами. Если эта опция выключена, WooCommerce не будет учитывать количество товара.
Также проверьте, что в настройках товара включено управление запасами и задано количество.
Пошаговое решение: автоматическое удаление товаров при отсутствии на складе через код
Удалять товары полностью из базы данных не всегда желательно — лучше скрывать их из каталога. Однако, если задача именно удалить товары без запаса, можно сделать это с помощью WP-Cron и пользовательской функции.
1. Создаем функцию удаления товаров с нулевым запасом
function wpaction_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 (!empty($query->posts)) {
foreach ($query->posts as $product_id) {
wp_delete_post($product_id, true); // true — удаление без возможности восстановления
}
}
}
2. Запускаем функцию через WP-Cron ежедневно
if (!wp_next_scheduled('wpaction_daily_delete_out_of_stock')) {
wp_schedule_event(time(), 'daily', 'wpaction_daily_delete_out_of_stock');
}
add_action('wpaction_daily_delete_out_of_stock', 'wpaction_delete_out_of_stock_products');
Этот код регистрирует ежедневное задание, которое будет автоматически удалять все товары, у которых статус склада outofstock.
3. Альтернативный вариант — скрыть товары без удаления
Если важна сохранность данных, лучше скрыть товары с нулевым запасом из каталога. Для этого добавьте фильтр, исключающий товары из выборки:
function wpaction_exclude_out_of_stock_products($q) {
if (!is_admin() && $q->is_main_query() && (is_shop() || is_product_category() || is_product_tag())) {
$meta_query = $q->get('meta_query');
if (!is_array($meta_query)) {
$meta_query = [];
}
$meta_query[] = [
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!=',
];
$q->set('meta_query', $meta_query);
}
}
add_action('pre_get_posts', 'wpaction_exclude_out_of_stock_products');
Проверка результата после внедрения
- Для удаления: зайдите в административную панель > Товары и убедитесь, что товары с отсутствующим запасом исчезли.
- Для скрытия: откройте публичный каталог и проверьте, что товары с запасом 0 не отображаются.
- Для дополнительной проверки запустите WP-Cron вручную, используя плагин WP Crontrol или вызов функции напрямую.
Частые ошибки и как их исправить
- Функция не срабатывает: Проверьте, активна ли WP-Cron на сайте (wp-config.php не содержит define('DISABLE_WP_CRON', true);). При необходимости запускайте cron задачи вручную через сервер.
- Товары не удаляются: Убедитесь, что статус товара действительно
outofstock. Статус можно проверить в базе данных в таблицеwp_postmetaпо ключу_stock_status. - Удаление нежелательно: Используйте вариант с фильтром для скрытия товаров без удаления, чтобы избежать потери данных.
- Конфликты с плагинами кеширования: Очистите кеш после изменения поведения каталога, иначе изменения могут не отобразиться.
Практические советы по безопасности и производительности
- Перед внедрением автоматического удаления товаров сделайте резервную копию базы данных.
- Для магазинов с большим количеством товаров используйте ограничение количества удаляемых товаров за один запуск, чтобы избежать таймаута. Например, добавить 'posts_per_page' => 50 и запускать задачу чаще.
- Для повышения скорости запросов создайте индекс по мета-ключу
_stock_statusв базе данных MySQL. - Если используете скрытие, убедитесь, что фильтр не влияет на административную панель и REST API, чтобы не мешать внутренним процессам.
Сравнение вариантов удаления и скрытия товаров
| Метод | Преимущества | Недостатки | Пример кода |
|---|---|---|---|
| Удаление товаров | Полное удаление из базы, освобождение места, чистота каталога | Потеря данных, невозможность восстановления без резервной копии | wp_delete_post() |
| Скрытие товаров | Сохраняются данные, можно быстро вернуть товар, более безопасно | Товары остаются в базе, требует фильтрации запросов | Фильтр pre_get_posts с _stock_status |