Диагностика проблемы: зачем и когда удалять неактивные товары
В WooCommerce с течением времени в каталоге могут накапливаться товары, которые давно не продаются или не обновлялись, а также товары со статусом «черновик» или «отклонён». Это приводит к увеличению базы данных, замедлению работы сайта и даже ухудшению пользовательского опыта. Автоматическое удаление таких товаров позволяет поддерживать каталог в актуальном состоянии без лишнего ручного труда.
Определение неактивных товаров: критерии и фильтры
Для автоматического удаления важно задать чёткие критерии — какие товары считать неактивными. Чаще всего используют следующие условия:
- Статус товара — 'draft', 'pending', 'trash' или 'private'.
- Дата последнего обновления или изменения меньше определённого срока (например, 6 месяцев).
- Отсутствие продаж за определённый период (например, 3 месяца).
В WooCommerce дата последней продажи для товара не хранится по умолчанию, но её можно получить, проанализировав заказы.
Пример SQL запроса для определения последней продажи товара
SELECT MAX(p.post_date) as last_order_date FROM wp_posts p
JOIN wp_woocommerce_order_items oi ON p.ID = oi.order_id
JOIN wp_woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
WHERE p.post_type = 'shop_order'
AND p.post_status IN ('wc-completed', 'wc-processing')
AND oim.meta_key = '_product_id'
AND oim.meta_value = %d;Однако для автоматизации лучше использовать WP-функции и WP_Query.
Пошаговое решение: скрипт для автоматического удаления неактивных товаров
Рассмотрим готовый пример кода, который можно добавить в functions.php или в отдельный плагин.
function wpcodes_delete_inactive_products() {
// Параметры: товары не обновлявшиеся более 180 дней
$days_inactive = 180;
$date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_inactive . ' days'));
// Получаем товары со статусом 'publish' и датой изменения меньше threshold
$args = [
'post_type' => 'product',
'post_status' => 'publish',
'date_query' => [
[
'column' => 'post_modified',
'before' => $date_threshold,
],
],
'fields' => 'ids',
'posts_per_page' => -1,
];
$query = new WP_Query($args);
if (!$query->have_posts()) {
return; // Нет неактивных товаров
}
foreach ($query->posts as $product_id) {
// Проверяем наличие продаж для данного товара
$orders = wc_get_orders([
'limit' => 1,
'status' => ['completed', 'processing'],
'product' => $product_id,
'date_created' => '>' . $date_threshold,
]);
if (empty($orders)) {
// Нет продаж за последние 180 дней, удаляем товар без возможности восстановления
wp_delete_post($product_id, true);
}
}
}
// Запуск по крону ежедневно
add_action('wpcodes_daily_product_cleanup', 'wpcodes_delete_inactive_products');
// Регистрация события при активации плагина или темы
function wpcodes_schedule_daily_cleanup() {
if (!wp_next_scheduled('wpcodes_daily_product_cleanup')) {
wp_schedule_event(time(), 'daily', 'wpcodes_daily_product_cleanup');
}
}
add_action('wp', 'wpcodes_schedule_daily_cleanup');
// Очистка при деактивации
function wpcodes_clear_schedule() {
$timestamp = wp_next_scheduled('wpcodes_daily_product_cleanup');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpcodes_daily_product_cleanup');
}
}
register_deactivation_hook(__FILE__, 'wpcodes_clear_schedule');Объяснение кода
- Выбираем товары, обновлённые более 180 дней назад.
- Для каждого товара проверяем, были ли продажи за последние 180 дней.
- Если продаж нет, удаляем товар полностью (
wp_delete_postсtrue). - Запускаем функцию через WP-Cron ежедневно.
Проверка результата после внедрения
Чтобы убедиться, что скрипт работает корректно:
- Добавьте тестовые товары с разными датами обновления и продаж.
- Запустите событие вручную из консоли WP-CLI:
wp cron event run wpcodes_daily_product_cleanup - Проверьте, что товары без продаж и с устаревшей датой удалились.
- Просмотрите логи сервера или подключите логирование внутри функции для отладки.
Частые ошибки и как их исправить
- Удаление нужных товаров: Неправильное условие даты или отсутствие проверки продаж может привести к удалению актуальных товаров. Всегда тестируйте на копии сайта.
- Функция не запускается: WP-Cron зависит от посещений сайта. Для надёжности используйте системный cron или WP-CLI.
- Проблемы с производительностью: Обработка большого количества товаров за один запуск может тормозить сайт. Ограничьте количество товаров одной итерацией или используйте пакетную обработку.
Практические советы по безопасности и производительности
- Всегда создавайте резервные копии базы перед массовым удалением.
- Используйте транзиенты или опции для отслеживания прогресса удаления.
- Запускайте скрипт в период низкой нагрузки.
- Ограничьте права пользователя, под которым запускается скрипт, чтобы избежать удаления важных данных.
- Добавьте логирование удалённых товаров в отдельный файл или в системный лог.
Таблица сравнения вариантов удаления неактивных товаров
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Ручное удаление через админку WooCommerce | Простота, контроль | Трудоёмко при большом каталоге | Подходит для малого бизнеса |
| Плагин для очистки WooCommerce | Автоматизация, удобство | Может конфликтовать, нагрузка | Использовать проверенные плагины |
| Кастомный скрипт через WP-Cron (как в статье) | Гибкость, точность | Требует навыков, отладка | Оптимальный вариант для разработчиков |