Диагностика проблемы: зачем удалять товары без заказов
В интернет-магазинах на WooCommerce часто накапливаются товары, которые не покупаются и не имеют заказов. Это увеличивает размер базы данных, замедляет работу админки и может негативно влиять на SEO, если такие товары остаются видимыми. Автоматическое удаление таких товаров помогает поддерживать каталог в актуальном состоянии и улучшает производительность сайта.
Как определить товары без заказов
Товар без заказов — это продукт, ID которого отсутствует в записях таблицы 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
LEFT JOIN wp_woocommerce_order_itemmeta oim ON oim.order_item_id = oi.order_item_id
WHERE p.post_type = 'product'
AND oim.meta_value IS NULL
GROUP BY p.ID;
Этот запрос покажет товары, которые не связаны ни с одним заказом. Но для автоматизации лучше использовать PHP-код с WP_Query и функциями WooCommerce.
Пошаговое решение: как написать функцию для автоматического удаления товаров без заказов
1. Создаем функцию для проверки заказов по продукту
function has_orders($product_id) {
global $wpdb;
$query = $wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_order_items oi
JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
JOIN {$wpdb->prefix}posts p ON p.ID = oi.order_id
WHERE oim.meta_key = '_product_id' AND oim.meta_value = %d AND p.post_status IN ('wc-completed', 'wc-processing')",
$product_id
);
return (bool) $wpdb->get_var($query);
}
2. Функция удаления товаров без заказов
function delete_products_without_orders() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'fields' => 'ids'
];
$products = get_posts($args);
foreach ($products as $product_id) {
if (!has_orders($product_id)) {
wp_delete_post($product_id, true); // жесткое удаление
}
}
}
3. Запуск функции через WP-Cron
if (!wp_next_scheduled('auto_delete_no_order_products')) {
wp_schedule_event(time(), 'daily', 'auto_delete_no_order_products');
}
add_action('auto_delete_no_order_products', 'delete_products_without_orders');
Это позволит запускать очистку ежедневно. Для запуска вручную из админки можно добавить кнопку или вызвать функцию напрямую.
Проверка результата после внедрения
- Проверьте наличие товаров в каталоге до запуска скрипта.
- Запустите функцию вручную в админке или дождитесь запуска по расписанию.
- Убедитесь, что товары без заказов удалены (через админку или SQL-запрос).
- Проверьте, что товары с заказами не затронуты.
- Проверьте логи ошибок и нагрузку на базу после выполнения.
Частые ошибки и как их исправить
- Удаление товаров с заказами: бывает, если в функции проверки заказов не учитываются статусы заказов. Используйте только статусы
wc-completedиwc-processingдля проверки. - Большая нагрузка на базу при большом каталоге: разбивайте удаление на партии по 50-100 товаров, используя параметр
posts_per_pageи пагинацию. - WP-Cron не работает: проверьте, что на сайте активно выполнение wp-cron, или настройте системный cron-задание.
- Потеря данных: перед удалением сделайте бэкап базы и файлов.
Практические советы по безопасности и производительности
- Используйте
wp_delete_post($product_id, true)для полного удаления, если хотите очистить базу, иначе товары попадут в корзину. - Добавьте логирование удаленных товаров для последующего аудита.
- Для крупных магазинов лучше делать удаление партиями с паузами, чтобы не блокировать базу.
- Перед удалением проверяйте наличие связанных данных, например, отзывов или метаданных, чтобы избежать ошибок.
- По возможности интегрируйте очистку с плагинами оптимизации базы, например, Clearfy Pro (https://wpshop.ru/plugins/clearfy?utm_source=wpcoding.ru&utm_medium=article&utm_campaign=woocommerce-udalit-tovary-bez-zakazov-avtomatizatsiya) для комплексной чистки.
Сравнение способов удаления товаров без заказов
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| SQL-запросы напрямую | Удаление через SQL-запросы к базе | Быстро, можно делать массово | Риск повредить данные, не учитывает логику WP |
| PHP-функция с WP_Query и wp_delete_post | Использует WordPress API для удаления | Безопасно, учитывает все связи | Может быть медленнее на больших данных |
| Плагины оптимизации (Clearfy Pro) | Готовые решения с UI | Удобно для админов, дополнительные функции | Платные, могут влиять на производительность |