Определение неактивных товаров в WooCommerce
Неактивные товары — это товары, которые не имели ни одной продажи за определённый период времени. Такие товары могут занимать место в базе данных, замедлять работу сайта и мешать управлению каталогом. Автоматическое удаление таких товаров помогает поддерживать актуальность магазина и оптимизировать производительность.
Диагностика проблемы: как понять, что в магазине есть неактивные товары
Для выявления неактивных товаров можно использовать SQL-запросы к базе данных WooCommerce, а также отчёты продаж в админке. Чаще всего проблема возникает, если товаров много, и их количество с нулевыми продажами растёт.
Пример SQL-запроса для выборки товаров без продаж за последние 6 месяцев:
SELECT p.ID, p.post_title FROM wp_posts AS p
LEFT JOIN wp_woocommerce_order_items AS oi ON p.ID = oi.order_item_id
LEFT JOIN wp_woocommerce_order_itemmeta AS oim ON oi.order_item_id = oim.order_item_id AND oim.meta_key = '_product_id'
LEFT JOIN wp_posts AS o ON oi.order_id = o.ID AND o.post_type = 'shop_order' AND o.post_status IN ('wc-completed','wc-processing')
WHERE p.post_type = 'product' AND p.post_status = 'publish'
AND (o.ID IS NULL OR o.post_date < DATE_SUB(NOW(), INTERVAL 6 MONTH))
GROUP BY p.ID;Если в результате много товаров, стоит задуматься об их удалении или архивировании.
Пошаговое решение: автоматическое удаление неактивных товаров по времени без продаж
1. Создание пользовательской функции для удаления
Добавьте следующий код в файл functions.php вашей дочерней темы или в плагин для кастомных функций:
function wc_delete_inactive_products() {
global $wpdb;
// Период в днях, например 180 дней (6 месяцев)
$days = 180;
// Получаем ID товаров без продаж за последние 180 дней
$product_ids = $wpdb->get_col($wpdb->prepare(
"
SELECT p.ID FROM {$wpdb->posts} p
LEFT JOIN (
SELECT DISTINCT oim.meta_value AS product_id
FROM {$wpdb->prefix}woocommerce_order_items oi
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
INNER JOIN {$wpdb->posts} o ON oi.order_id = o.ID
WHERE o.post_type = 'shop_order'
AND o.post_status IN ('wc-completed', 'wc-processing')
AND o.post_date > DATE_SUB(NOW(), INTERVAL %d DAY)
AND oim.meta_key = '_product_id'
) AS sold_products ON p.ID = sold_products.product_id
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND sold_products.product_id IS NULL
", $days
));
if (!empty($product_ids)) {
foreach ($product_ids as $product_id) {
wp_delete_post($product_id, true); // true - удаление без перемещения в корзину
}
}
}2. Запуск функции по расписанию (WP-Cron)
Чтобы функция запускалась автоматически, создайте событие WP-Cron:
function wc_schedule_inactive_product_deletion() {
if (!wp_next_scheduled('wc_delete_inactive_products_hook')) {
wp_schedule_event(time(), 'daily', 'wc_delete_inactive_products_hook');
}
}
add_action('wp', 'wc_schedule_inactive_product_deletion');
add_action('wc_delete_inactive_products_hook', 'wc_delete_inactive_products');3. Очистка расписания при деактивации темы или плагина
function wc_unschedule_inactive_product_deletion() {
$timestamp = wp_next_scheduled('wc_delete_inactive_products_hook');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wc_delete_inactive_products_hook');
}
}
// Добавляйте вызов этой функции при деактивации плагина или темы
// register_deactivation_hook(__FILE__, 'wc_unschedule_inactive_product_deletion');Проверка результата после внедрения
1. Создайте тестовый товар без продаж и проверьте, что он удалится через 24 часа (если WP-Cron работает).
2. Проверьте логи сервера и базы данных на предмет ошибок.
3. Используйте SQL-запрос из раздела диагностики, чтобы убедиться, что список неактивных товаров пуст после выполнения скрипта.
Частые ошибки и как их исправить
- WP-Cron не запускается автоматически. Проверьте, включён ли WP-Cron, и настроен ли на вашем хостинге запуск событий. Для проверки вручную вызовите функцию
wp-cron.phpчерез браузер или консоль. - Удаляются товары с продажами. Проверьте правильность SQL-запроса, особенно фильтрацию по датам и статусам заказов.
- Удаление не происходит из-за прав. Убедитесь, что ваш пользователь WordPress имеет права на удаление товаров.
- Потеря данных. Рекомендуется делать резервную копию базы данных перед внедрением автодеятельности.
Практические советы по безопасности и производительности
- Всегда создавайте резервные копии базы данных перед автоматическим удалением данных.
- Ограничьте период времени для удаления (например, не менее 3 месяцев), чтобы избежать удаления недавно добавленных товаров.
- Используйте транзакции или пакетное удаление, если товаров очень много, чтобы не перегружать сервер.
- Для больших магазинов можно настроить удаление через WP-CLI с запуском по cron вне WordPress.
- Рассмотрите использование плагинов для архивации товаров вместо удаления, если требуется сохранить историю.
Сравнение способов удаления неактивных товаров
| Метод | Плюсы | Минусы | Рекомендации |
|---|---|---|---|
| Ручное удаление через админку | Простота, контроль | Долго, неэффективно при большом количестве товаров | Для небольших магазинов |
| SQL-запросы | Быстро, гибко | Риск ошибок, требует навыков SQL | Для опытных разработчиков |
| Автоматизация через WP-Cron и PHP-функции | Автоматизация, регулярность | Зависит от корректности WP-Cron и кода | Оптимальный вариант для средних и больших магазинов |
| Плагины очистки товаров | Удобство, поддержка | Могут быть платными, ограничены функционалом | Использовать, если не хочется писать код |