Диагностика проблемы: зачем автоматически удалять товары без остатка
В интернет-магазине на WooCommerce товары с нулевым или отрицательным остатком могут создавать неудобства: они занимают место в каталоге, вводят клиентов в заблуждение и снижают конверсию. Особенно актуально для магазинов с большим ассортиментом и частыми изменениями остатков.
Основная задача — автоматизировать удаление таких товаров, чтобы не выполнять это вручную и не допускать появления недоступных позиций на сайте.
Как настроить автоматическое удаление товаров в WooCommerce при отсутствии на складе
Использование WP-Cron для периодической проверки и удаления товаров
Для решения подойдет кастомный код, который будет запускаться по расписанию (например, раз в сутки) и удалять товары с остатком 0 или меньше.
Добавьте следующий код в functions.php вашей активной темы или в отдельный плагин:
if ( ! wp_next_scheduled( 'wpmeta_delete_out_of_stock_products' ) ) {
wp_schedule_event( time(), 'daily', 'wpmeta_delete_out_of_stock_products' );
}
add_action( 'wpmeta_delete_out_of_stock_products', 'wpmeta_delete_out_of_stock_products_callback' );
function wpmeta_delete_out_of_stock_products_callback() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_stock',
'value' => 0,
'compare' => '<=',
'type' => 'NUMERIC',
],
],
'fields' => 'ids',
];
$query = new WP_Query( $args );
if ( ! empty( $query->posts ) ) {
foreach ( $query->posts as $product_id ) {
wp_delete_post( $product_id, true );
}
}
}Объяснение:
wp_schedule_eventсоздает ежедневное событие.- Хук
wpmeta_delete_out_of_stock_productsзапускает функцию удаления. - Функция ищет все товары с мета-полем
_stockменьше или равным 0 и удаляет ихwp_delete_postс параметромtrue(без возможности восстановления из корзины).
Вариант с использованием сторонних плагинов
Если вы предпочитаете не писать код, можно использовать плагины автоподдержки WooCommerce, например:
| Плагин | Функционал | Плюсы | Минусы |
|---|---|---|---|
| WooCommerce Advanced Bulk Edit | Массовое редактирование товаров, фильтрация по остатку, удаление | Интерфейс, без кода | Ручное действие, нет автоматизации |
| WP All Import + WP All Export | Импорт и экспорт с фильтрацией, можно настроить удаление через импорт | Гибкость | Сложнее в настройке |
Пошаговое руководство по внедрению кода
- Сделайте резервную копию сайта (базы данных и файлов).
- Подключитесь к сайту через FTP или файловый менеджер хостинга.
- Откройте
functions.phpактивной темы или создайте плагин с этим кодом. - Вставьте код и сохраните файл.
- Проверьте, что в админке в разделе «Инструменты» - «Запланированные события» (если установлен WP Crontrol) появилось событие
wpmeta_delete_out_of_stock_products. - Подождите 24 часа или запустите событие вручную (через WP Crontrol или программно).
Как проверить, что автоматическое удаление работает
- Создайте тестовый товар с остатком 0.
- Вручную запустите хук (через WP Crontrol или временно добавьте вызов
wpmeta_delete_out_of_stock_products_callback()в код). - Обновите список товаров — тестовый товар должен исчезнуть.
- Убедитесь, что другие товары с остатком > 0 не удаляются.
Частые ошибки и как их исправить
Товар не удаляется, хотя остаток 0
- Проверьте, что остаток хранится в метаполе
_stock. Некоторые плагины или кастомные решения могут использовать другие метаполя. - Убедитесь, что товар имеет тип
product, а не вариацию или кастомный тип.
Планировщик событий не запускается
- Проверьте, включен ли WP-Cron на сайте (иногда его отключают в
wp-config.phpчерезdefine('DISABLE_WP_CRON', true);). - Если отключен, настройте системный cron на вызов
wp-cron.phpили запускайте вручную.
Удаление происходит слишком часто или не по расписанию
- Проверьте, нет ли дублированных хук-событий через WP Crontrol.
- Если нужно изменить период, замените 'daily' на 'hourly' или 'twicedaily', но учитывайте нагрузку.
Практические советы по безопасности и производительности
- При удалении товаров используйте
wp_delete_post( $product_id, true )для полного удаления без попадания в корзину, иначе база может разрастаться. - Перед массовым удалением сделайте экспорт списка товаров на всякий случай.
- Не запускайте удаление чаще одного раза в сутки без необходимости — нагрузка на базу может повыситься.
- Если магазин большой, ограничьте удаление партиями по 100 товаров за раз, добавив пагинацию в WP_Query.
- Для контроля и лога добавьте запись в файл или базу данных о количестве удаленных товаров за запуск.
Пример кода с ограничением на 100 товаров за запуск и логированием
function wpmeta_delete_out_of_stock_products_callback() {
$args = [
'post_type' => 'product',
'posts_per_page' => 100,
'meta_query' => [
[
'key' => '_stock',
'value' => 0,
'compare' => '<=',
'type' => 'NUMERIC',
],
],
'fields' => 'ids',
];
$query = new WP_Query( $args );
$deleted_count = 0;
if ( ! empty( $query->posts ) ) {
foreach ( $query->posts as $product_id ) {
if ( wp_delete_post( $product_id, true ) ) {
$deleted_count++;
}
}
}
if ( $deleted_count > 0 ) {
error_log( "[wpmeta] Deleted $deleted_count out of stock products on " . date('Y-m-d H:i:s') );
}
}