Диагностика проблемы: почему нужно отключать неактивные товары
В интернет-магазинах на WooCommerce со временем накапливаются товары, которые долго не продаются или не обновлялись. Это влияет на удобство управления каталогом и может ухудшать пользовательский опыт. Ручное отключение товаров занимает много времени, поэтому автоматизация этой задачи критична для крупных проектов.
Как определить неактивные товары?
Под неактивными понимаются товары, у которых отсутствовали продажи или обновления в течение определённого периода (например, 90 дней). Чтобы диагностировать наличие таких товаров, можно использовать SQL-запрос к базе данных:
SELECT p.ID, p.post_title, MAX(o.post_date) AS last_order_date
FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_posts 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'
GROUP BY p.ID
HAVING last_order_date IS NULL OR last_order_date < NOW() - INTERVAL 90 DAY;Этот запрос показывает товары без заказов за последние 90 дней.
Пошаговое решение: как автоматически отключать неактивные товары
Для автоматического отключения используем WP-Cron и PHP-код с хуками WooCommerce.
1. Создаём функцию для проверки и смены статуса товара
function wpassist_disable_inactive_products() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [],
'fields' => 'ids',
];
$products = get_posts($args);
$threshold = strtotime('-90 days');
foreach ($products as $product_id) {
$last_order = get_post_meta($product_id, '_last_order_date', true);
if (!$last_order || strtotime($last_order) < $threshold) {
// Смена статуса на 'draft' (скрытый)
wp_update_post([
'ID' => $product_id,
'post_status' => 'draft',
]);
}
}
}2. Обновляем дату последнего заказа товара
Чтобы функция работала корректно, нужно обновлять метаполе _last_order_date при оформлении заказа. Добавляем хук на статус заказа:
add_action('woocommerce_order_status_completed', 'wpassist_update_last_order_date');
function wpassist_update_last_order_date($order_id) {
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
update_post_meta($product_id, '_last_order_date', current_time('mysql'));
}
}3. Регистрируем cron задачу для регулярного запуска
add_action('wpassist_cron_disable_inactive_products', 'wpassist_disable_inactive_products');
if (!wp_next_scheduled('wpassist_cron_disable_inactive_products')) {
wp_schedule_event(time(), 'daily', 'wpassist_cron_disable_inactive_products');
}Проверка результата после внедрения
- Проверьте наличие метаполя
_last_order_dateу товаров с помощью phpMyAdmin или через код:
var_dump(get_post_meta($product_id, '_last_order_date', true));- Убедитесь, что cron задача запущена (через плагин WP Crontrol или WP-CLI:
wp cron event list). - Проверьте, что товары с отсутствием заказов за 90+ дней сменили статус на
draft.
Частые ошибки и как исправить
- Не обновляется дата последнего заказа: убедитесь, что хук
woocommerce_order_status_completedработает, и в момент смены статуса заказа вызывается функция обновления метаданных. - WP-Cron не запускается: если на сайте мало трафика, WP-Cron может не срабатывать. Настройте системный cron для запуска
wp-cron.php. - Товары не меняют статус: проверьте права пользователя, под которым запускается код, и отсутствие ошибок в логах.
Практические советы по безопасности и производительности
- Используйте WP-Cron с системным cron для надёжности.
- Ограничивайте количество товаров, обрабатываемых за один запуск, чтобы не перегружать сервер.
- Сохраняйте резервные копии базы перед массовыми изменениями.
- Используйте транзиенты или кеширование для сокращения нагрузки при выборке товаров.
Сравнение методов автоматического отключения товаров
| Метод | Преимущества | Недостатки |
|---|---|---|
| Код с WP-Cron (как в статье) | Полный контроль, без сторонних плагинов, гибкость настройки | Требует навыков разработки, возможны проблемы с WP-Cron при низком трафике |
| Плагины для управления товарами | Простота использования, готовые настройки | Может замедлять сайт, ограниченная кастомизация |
| Ручное отключение | Полный контроль, простота для небольших магазинов | Трудоёмко, неэффективно при большом каталоге |