Диагностика задачи: зачем автоматически удалять товары с нулевым остатком и без продаж
В интернет-магазинах на WooCommerce часто накапливаются товары, которые уже не продаются и имеют нулевой остаток. Это негативно влияет на производительность сайта, SEO и пользовательский опыт. Вручную мониторить и удалять такие товары неудобно, особенно при большом каталоге. Автоматизация этой задачи позволит поддерживать базу актуальной без дополнительной работы.
Как определить товары для удаления: критерии и проверка
Для автоматического удаления нам нужны конкретные критерии:
- Количество на складе = 0 (мета поле
_stock) - Отсутствие продаж — количество продаж товара равно 0 (мета поле
total_sales) - Дата публикации — товар опубликован более N дней назад (чтобы не удалять новые товары)
Проверить эти параметры можно с помощью SQL-запроса к базе данных или через WP-CLI:
SELECT p.ID, p.post_title, pm1.meta_value AS stock, pm2.meta_value AS sales FROM wp_posts p
LEFT JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_stock'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = 'total_sales'
WHERE p.post_type = 'product' AND p.post_status = 'publish'
AND pm1.meta_value = '0' AND pm2.meta_value = '0'
AND p.post_date < DATE_SUB(NOW(), INTERVAL 30 DAY);Этот запрос покажет товары с нулевым остатком и без продаж старше 30 дней.
Пошаговое решение: автоматическое удаление через WP-Cron и пользовательскую функцию
Оптимальный способ — создать функцию, которая удаляет товары по критериям, и запускать её раз в сутки через WP-Cron.
1. Создаем функцию удаления товаров
function wps_delete_unsold_out_of_stock_products() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'date_query' => [
[
'before' => '30 days ago',
],
],
'meta_query' => [
'relation' => 'AND',
[
'key' => '_stock',
'value' => '0',
'compare' => '=',
'type' => 'NUMERIC',
],
[
'key' => 'total_sales',
'value' => '0',
'compare' => '=',
'type' => 'NUMERIC',
],
],
'fields' => 'ids',
];
$products = get_posts($args);
foreach ($products as $product_id) {
wp_delete_post($product_id, true);
}
}2. Регистрируем WP-Cron событие для ежедневного запуска
function wps_schedule_daily_product_cleanup() {
if (!wp_next_scheduled('wps_daily_product_cleanup_hook')) {
wp_schedule_event(time(), 'daily', 'wps_daily_product_cleanup_hook');
}
}
add_action('wp', 'wps_schedule_daily_product_cleanup');
add_action('wps_daily_product_cleanup_hook', 'wps_delete_unsold_out_of_stock_products');3. Как добавить задачу вручную (для отладки)
// Временно вызвать функцию вручную
add_action('init', function() {
if (isset($_GET['run_product_cleanup'])) {
wps_delete_unsold_out_of_stock_products();
exit('Cleanup done');
}
});Проверка результата после внедрения
Чтобы убедиться, что автоматическое удаление работает:
- Добавьте тестовый товар с нулевым остатком и нулевыми продажами, опубликованный более 30 дней назад.
- Запустите вручную функцию через URL вида
https://example.com/?run_product_cleanup - Проверьте, что товар исчез из админки и базы (таблица
wp_posts). - Проверьте логи сервера на наличие ошибок PHP.
Для контроля можно добавить логирование удалённых товаров, например:
function wps_delete_unsold_out_of_stock_products() {
$args = [...]; // как выше
$products = get_posts($args);
foreach ($products as $product_id) {
error_log('Deleted product ID: ' . $product_id);
wp_delete_post($product_id, true);
}
}Частые ошибки и как их исправить
- Функция не удаляет товары: Проверьте правильность meta_key и значения
_stockиtotal_sales. Иногда запас хранится в другом мета поле, например,_manage_stockили используются сторонние плагины, меняющие логику. - Удаляются не все нужные товары: Ограничение по дате может быть слишком жёстким, попробуйте увеличить или убрать фильтр
date_query. - WP-Cron не срабатывает: Проверьте, что на сайте посещения достаточные для запуска WP-Cron или настройте системный cronjob для запуска
wp-cron.php. - Удаление товаров приводит к ошибкам: Убедитесь, что
wp_delete_post()вызывается с параметромtrueдля принудительного удаления без перемещения в корзину.
Практические советы по безопасности и производительности
- Перед автоматическим удалением делайте резервную копию базы данных, особенно если у вас большой каталог.
- Для больших магазинов используйте постраничный вывод (
posts_per_pageс лимитом и пагинацией), чтобы не перегружать память. - Используйте транзиенты или логи для мониторинга количества удалённых товаров и предотвращения повторных удалений.
- Для безопасности ограничьте запуск ручных вызовов функции проверкой nonce или прав администратора.
- Если используете WPShop Clearfy Pro, дополнительно можно настроить очистку базы от устаревших метаданных и записей.
Сравнение методов автоматического удаления товаров
| Метод | Преимущества | Недостатки |
|---|---|---|
| WP-Cron + свой код | Гибкость, контроль, не требует сторонних плагинов | Зависит от посещаемости сайта, требует отладки |
| Плагины очистки базы (например, Clearfy Pro) | Удобный интерфейс, дополнительные функции оптимизации | Может стоить денег, ограниченная кастомизация |
| Ручное удаление через SQL | Быстрое решение для опытных администраторов | Высокий риск, требует бэкапа, не автоматично |