Диагностика проблемы: зачем и когда нужно удалять товары без заказов
В крупных интернет-магазинах на WooCommerce с течением времени накапливаются товары, которые не продаются. Такие товары занимают место в базе данных, замедляют админку и могут путать покупателей. Автоматическое удаление товаров без активных заказов помогает поддерживать каталог в актуальном состоянии и облегчает управление магазином.
Проверить наличие таких товаров можно через SQL-запрос или WP_Query, например:
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_order_count',
'value' => 0,
'compare' => '=',
'type' => 'NUMERIC'
]
]
];
$products = get_posts($args);
echo 'Товаров без заказов: ' . count($products);Здесь _order_count — пользовательское метаполе, которое нужно создать для подсчёта заказов по товару. WooCommerce не хранит это напрямую, поэтому нужно сформировать логику подсчёта.
Пошаговое решение: автоматическое удаление товаров без заказов
1. Подсчёт заказов для каждого товара
Для определения, какие товары не имеют заказов, используем SQL-запрос, который подсчитывает количество заказов, где товар был добавлен:
function get_products_without_orders() {
global $wpdb;
$query = "
SELECT p.ID FROM {$wpdb->posts} p
LEFT JOIN (
SELECT order_item_id, order_item_name, order_id
FROM {$wpdb->prefix}woocommerce_order_items
) oi ON oi.order_item_name = p.post_title
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oim.order_item_id = oi.order_item_id AND oim.meta_key = '_product_id'
LEFT JOIN {$wpdb->posts} o ON o.ID = oi.order_id AND o.post_status IN ('wc-completed', 'wc-processing')
WHERE p.post_type = 'product'
GROUP BY p.ID
HAVING COUNT(o.ID) = 0
";
return $wpdb->get_col($query);
}Этот запрос возвращает ID товаров, у которых нет заказов в статусах "выполнен" и "обрабатывается".
2. Функция удаления товаров по ID
function delete_products_by_ids(array $product_ids) {
foreach ($product_ids as $id) {
wp_delete_post($id, true); // true — безвозвратное удаление
}
}3. Автоматизация через WP-Cron
Добавим задачу, которая будет запускаться, например, раз в неделю, и удалять неактивные товары.
add_action('wp', 'setup_weekly_delete_products_event');
function setup_weekly_delete_products_event() {
if (!wp_next_scheduled('weekly_delete_products_hook')) {
wp_schedule_event(time(), 'weekly', 'weekly_delete_products_hook');
}
}
add_action('weekly_delete_products_hook', 'auto_delete_inactive_products');
function auto_delete_inactive_products() {
$product_ids = get_products_without_orders();
if (!empty($product_ids)) {
delete_products_by_ids($product_ids);
}
}Проверка результата после внедрения
- В админке WooCommerce в разделе "Товары" должно уменьшиться количество товаров без активных заказов.
- Запустите вручную функцию
auto_delete_inactive_products()через WP-CLI или временно добавьте вызов в код для отладки. - Проверьте, что удалённые товары исчезли из базы данных и что пользовательские страницы товаров не доступны (404).
Частые ошибки и как исправить
- Удаляются нужные товары: Проверьте правильность SQL-запроса, чтобы учитывались только статусы заказов, которые действительно означают покупку.
- WP-Cron не запускается: Убедитесь, что на сайте есть посещения, либо настройте системный cron для вызова
wp-cron.php. - Удаление не происходит: Проверьте права пользователя, под которым выполняется скрипт, и наличие ошибок в логах.
- Высокая нагрузка при подсчёте: Для больших баз данных оптимизируйте запрос, добавьте индексы или реализуйте пакетную обработку.
Практические советы по безопасности и производительности
- Обязательно делайте резервные копии базы перед автоматическим удалением товаров.
- Добавьте в логи информацию о выполнении удаления, чтобы отслеживать процесс.
- Для избежания ошибок используйте транзакции или проверяйте зависимости товаров (например, связанные посты или отзывы).
- Если магазин большой, лучше разбить удаление на части, чтобы избежать таймаутов или превышения лимитов памяти.
- Временно отключайте кеширование при выполнении таких операций, чтобы изменения сразу отображались.
Сравнение способов удаления товаров без заказов
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| SQL-запрос + wp_delete_post | Прямое получение ID товаров через SQL, удаление через WP-функцию | Точный контроль, использует штатные WP функции | Сложный запрос, нагрузка на базу при большом объёме |
| Плагины очистки (например, Clearfy Pro) | Готовые инструменты для чистки и оптимизации сайта | Простота настройки, поддержка и обновления | Может быть избыточным, не всегда гибко |
| Ручная проверка и удаление через админку | Просмотр и удаление товаров по фильтрам | Никакого кода, безопасно | Трудоёмко, не подходит для больших сайтов |