Проблема: накопление неактуальных товаров в WooCommerce
В крупных интернет-магазинах на WooCommerce часто возникает ситуация, когда в каталоге остаются товары, на которые давно не было заказов. Это не только загромождает базу данных, но и ухудшает пользовательский опыт, затрудняя поиск актуальных товаров. Ручное удаление таких товаров — трудозатратный процесс, особенно при большом ассортименте.
Диагностика проблемы: как выявить товары без активных заказов
Первый шаг — определить, какие товары не связаны с активными заказами. Активные заказы — это заказы со статусами, например, processing, on-hold, completed, в зависимости от логики магазина. Товары, которые не встречаются в строках таких заказов, считаются без заказов.
Для диагностики удобно использовать SQL-запрос, чтобы получить список ID товаров без активных заказов:
SELECT p.ID, p.post_title FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
LEFT JOIN wp_posts o ON oi.order_id = o.ID
WHERE p.post_type = 'product'
AND (o.post_status NOT IN ('wc-processing','wc-on-hold','wc-completed') OR o.ID IS NULL)Однако такой запрос не всегда точен из-за структуры данных WooCommerce, поэтому лучше использовать WP_Query с кастомным SQL или PHP для точного анализа.
Пошаговое решение: автоматическое удаление товаров без активных заказов
1. Создание WP-CLI команды для безопасного удаления
WP-CLI позволяет выполнять задачи напрямую из командной строки, что удобно для автоматизации и исключает ошибки через админку.
if ( defined('WP_CLI') && WP_CLI ) {
WP_CLI::add_command('wc-delete-unused-products', function() {
global $wpdb;
// Получаем ID товаров без активных заказов
$product_ids = $wpdb->get_col(
"SELECT p.ID FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
LEFT JOIN {$wpdb->posts} o ON oi.order_id = o.ID
WHERE p.post_type = 'product'
AND (o.post_status NOT IN ('wc-processing','wc-on-hold','wc-completed') OR o.ID IS NULL)"
);
if (empty($product_ids)) {
WP_CLI::success('Нет товаров без активных заказов.');
return;
}
foreach ($product_ids as $product_id) {
wp_delete_post($product_id, true); // Полное удаление
WP_CLI::log("Удалён товар ID: $product_id");
}
WP_CLI::success('Удаление завершено.');
});
}2. Запуск команды и проверка результата
В терминале выполните:
wp wc-delete-unused-productsВы увидите список удалённых товаров и итоговое сообщение.
3. Автоматизация с помощью WP-Cron
Чтобы удалять товары регулярно, добавьте событие WP-Cron:
function schedule_delete_unused_products() {
if ( ! wp_next_scheduled( 'delete_unused_products_hook' ) ) {
wp_schedule_event( time(), 'daily', 'delete_unused_products_hook' );
}
}
add_action( 'wp', 'schedule_delete_unused_products' );
add_action( 'delete_unused_products_hook', function() {
// Вызов той же логики удаления, что и в WP-CLI
// Можно вынести в отдельную функцию для повторного использования
});Проверка результата после внедрения
- Проверьте наличие товаров в админке WooCommerce: товары без заказов должны отсутствовать.
- Запустите SQL-запрос из раздела «Диагностика», чтобы убедиться, что таких товаров нет.
- Проверьте логи WP-CLI (если используется) и WP-Cron, чтобы убедиться в отсутствии ошибок.
Частые ошибки и как их исправить
- Неправильный статус заказа: Если удаляются товары с активными заказами, проверьте статусы, указанные в запросе. Статусы могут отличаться в зависимости от локализации и плагинов.
- Удаление связанных данных: При удалении товаров важно использовать
wp_delete_post($id, true)для полного удаления, иначе товар может остаться в базе. - Проблемы с производительностью: При большом количестве товаров запрос может работать долго. Используйте ограничение и обработку партиями, например, через
LIMITи циклы. - Конфликты с плагинами кэширования: После удаления товаров очистите кэш сайта и объектов.
Практические советы для безопасности и производительности
- Создавайте резервную копию базы данных перед запуском автоматического удаления.
- Тестируйте скрипты сначала в staging-среде.
- Используйте WP-CLI для операций на больших сайтах — это безопаснее и эффективнее.
- При использовании WP-Cron убедитесь, что системный cron настроен или WP-Cron вызывается регулярно.
- Если у вас установлен Clearfy Pro, воспользуйтесь его функцией оптимизации и очистки базы для повышения производительности.
Сравнение вариантов удаления товаров без заказов
| Метод | Преимущества | Недостатки |
|---|---|---|
| Ручное удаление через админку | Простота, нет необходимости в коде | Трудоёмко, риск ошибок при большом количестве товаров |
| WP-CLI команда | Автоматизация, скорость, точность | Требует доступа к командной строке, базовые навыки |
| WP-Cron автоматизация | Полная автоматизация, регулярное поддержание чистоты | Зависимость от cron, сложнее отлаживать |