Почему нужно удалять товары без заказов
В интернет-магазине на WooCommerce нередко копится много товаров, которые не пользуются спросом и не имеют ни одного заказа. Такие товары занимают место в базе данных, могут запутывать покупателей и ухудшать производительность сайта. Автоматическое удаление таких товаров позволяет поддерживать каталог в актуальном состоянии без ручной проверки.
Диагностика проблемы: как определить товары без заказов
Для начала нужно получить список товаров, которые ни разу не были заказаны. В WooCommerce информация о заказах и товарах хранится в таблицах wp_posts (товары - тип product) и wp_woocommerce_order_items.
Пример SQL-запроса для поиска товаров без заказов:
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
WHERE p.post_type = 'product' AND p.post_status = 'publish'
GROUP BY p.ID
HAVING COUNT(oi.order_item_id) = 0;Этот запрос основан на названии товара, что не всегда надежно, особенно если названия меняются. Более точный способ — связать товары с заказами через метаданные и order items, но это сложнее и требует JOIN по wp_woocommerce_order_itemmeta. Для базовой проверки вышеуказанного запроса достаточно.
Пошаговое решение: как автоматически удалять товары без заказов
1. Создаем WP-CLI команду для удаления
WP-CLI — удобный инструмент для выполнения таких задач. Ниже пример кастомной команды, которая удалит все опубликованные товары без заказов:
if ( defined('WP_CLI') && WP_CLI ) {
WP_CLI::add_command('wc-delete-unused-products', function() {
global $wpdb;
$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
WHERE p.post_type = 'product' AND p.post_status = 'publish'
GROUP BY p.ID
HAVING COUNT(oi.order_item_id) = 0"
);
if ( empty($product_ids) ) {
WP_CLI::success('Нет товаров без заказов для удаления.');
return;
}
foreach ( $product_ids as $product_id ) {
wp_delete_post( $product_id, true ); // true - безвозвратное удаление
}
WP_CLI::success('Удалено товаров без заказов: ' . count($product_ids));
});
}2. Запуск команды
В терминале сервера запустите команду:
wp wc-delete-unused-productsЭто удалит товары без заказов навсегда.
3. Автоматизация через WP-Cron
Чтобы удалять товары регулярно, например, раз в неделю, добавьте планировщик событий:
function schedule_wc_delete_unused_products() {
if ( ! wp_next_scheduled( 'wc_delete_unused_products_cron' ) ) {
wp_schedule_event( time(), 'weekly', 'wc_delete_unused_products_cron' );
}
}
add_action( 'wp', 'schedule_wc_delete_unused_products' );
add_action( 'wc_delete_unused_products_cron', function() {
// Вызов вашей функции удаления товаров, аналогичной WP-CLI
});Реализуйте функцию удаления товаров по аналогии с WP-CLI внутри хука wc_delete_unused_products_cron.
Проверка результата после внедрения
- Перед запуском сделайте резервную копию базы данных.
- Запустите SQL-запрос из раздела диагностики и убедитесь, что список товаров без заказов сокращается после удаления.
- Проверьте в админке WooCommerce, что удаленные товары исчезли.
- Убедитесь, что на фронтенде товары не отображаются и ссылки на них ведут на 404.
Частые ошибки и их исправление
1. Неудаление товаров из-за неправильной связи с заказами
Если товары с заказами удаляются или не удаляются товары без заказов, значит запрос некорректен. Проверьте связь между order_items и товарами. Лучше использовать order_itemmeta с ключом _product_id для точной связи.
2. Удаление товаров с черновиками или скрытых статусов
Убедитесь, что в запросе указан статус publish, чтобы не трогать товары в разработке.
3. Потеря данных без бэкапа
Всегда делайте резервные копии базы перед массовыми удалениями.
Практические советы по безопасности и производительности
- Используйте WP-CLI для выполнения тяжелых операций, чтобы не нагружать фронтенд.
- Ограничьте количество удаляемых товаров за один запуск, чтобы избежать таймаутов, например, обрабатывайте партии по 50 товаров.
- Добавьте логи удаления для аудита.
- Используйте транзакции базы данных, если поддерживается, для отката в случае ошибки.
Сравнение вариантов удаления товаров без заказов
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Ручной SQL-запрос | Быстро и напрямую | Риск ошибок, нет логов, требует навыков | Использовать только для диагностики |
| WP-CLI команда | Автоматизация, безопасность, логи | Требует доступа к серверу | Оптимальный для разработчиков |
| Плагин | Простота использования | Может быть тяжелым, лишним функционалом | Использовать, если нет доступа к серверу |