Диагностика задачи: зачем удалять товары по дате последнего заказа
В интернет-магазинах на WooCommerce иногда возникает необходимость автоматически удалять товары, которые давно не заказывались. Это помогает очищать каталог от устаревших или нерелевантных товаров, улучшать навигацию и снижать нагрузку на базу данных.
Пример: у вас есть товары, которые не продавались более 6 месяцев, и вы хотите автоматически их удалить, чтобы не захламлять магазин.
Как найти товары без заказов или с последним заказом старше X дней
Для решения задачи важно понять, как связать товары с заказами. В WooCommerce связь между товаром и заказом ведется через wp_woocommerce_order_items и wp_woocommerce_order_itemmeta. Чтобы найти дату последнего заказа для товара, необходимо:
- Получить все заказы с товарами (статус «completed», «processing» и т.д.)
- Определить дату последнего заказа для каждого товара
- Выделить товары, для которых дата последнего заказа старше нужного периода или вовсе отсутствует заказ
Пошаговое решение: автоматическое удаление товаров
1. Создаем функцию для получения ID товаров без заказов или с устаревшим заказом
function get_products_to_delete( $days = 180 ) {
global $wpdb;
$threshold_date = date( 'Y-m-d H:i:s', strtotime( "-{$days} days" ) );
// Получаем ID товаров с последней датой заказа
$query = $wpdb->prepare(
"SELECT p.ID, MAX(o.post_date) as last_order_date
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN {$wpdb->posts} o ON o.ID = oi.order_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",
[]
);
$results = $wpdb->get_results( $query );
$products_to_delete = [];
foreach ( $results as $product ) {
if ( empty( $product->last_order_date ) || $product->last_order_date < $threshold_date ) {
$products_to_delete[] = $product->ID;
}
}
return $products_to_delete;
}Примечание: запрос упрощен для примера. Для точного связывания лучше использовать WooCommerce функции и метаданные заказов.
2. Функция удаления товаров по ID
function delete_products_by_ids( $product_ids ) {
foreach ( $product_ids as $product_id ) {
wp_delete_post( $product_id, true ); // true — удаляет без помещения в корзину
}
}3. Создаем WP-Cron задачу для регулярного удаления
add_action( 'wp', 'register_product_cleanup_cron' );
function register_product_cleanup_cron() {
if ( ! wp_next_scheduled( 'daily_product_cleanup_event' ) ) {
wp_schedule_event( time(), 'daily', 'daily_product_cleanup_event' );
}
}
add_action( 'daily_product_cleanup_event', 'daily_product_cleanup_callback' );
function daily_product_cleanup_callback() {
$products_to_delete = get_products_to_delete( 180 );
if ( ! empty( $products_to_delete ) ) {
delete_products_by_ids( $products_to_delete );
}
}Проверка результата после внедрения
Чтобы проверить, сработала ли автоматизация:
- Вручную запустите функцию
daily_product_cleanup_callback()через консоль WP-CLI:wp eval 'daily_product_cleanup_callback();' - Проверьте, что товары с датой последнего заказа более 180 дней отсутствуют в каталоге
- Проверьте логи ошибок PHP и запросы к базе на предмет ошибок
- Для отладки можно перед удалением логировать ID товаров, которые будут удалены
Частые ошибки и как их исправить
- Ошибка: Неправильное связывание товаров и заказов — причина: в запросе используется имя товара вместо ID заказа.
Решение: использовать WooCommerce API для получения заказов и товаров, напримерwc_get_orders()иwc_get_order_item_meta(). - Ошибка: Удаляются нужные товары или товары с заказами недавно — причина: неверный порог даты или часовой пояс.
Решение: проверяйте время сервера, используйте функции WordPress для времениcurrent_time('mysql'). - Ошибка: WP-Cron не срабатывает — причина: отсутствуют посещения на сайте.
Решение: используйте системный cron для вызова wp-cron.php или запускайте вручную.
Практические советы по безопасности и производительности
- Перед массовым удалением товаров сделайте резервную копию базы и файлов.
- Добавьте проверку ролей и прав пользователя, если планируете запускать удаление из админки.
- Для больших магазинов разбивайте удаление на партии по 50-100 товаров, чтобы избежать тайм-аутов.
- Логируйте удаленные товары в отдельный файл для аудита.
- Если используется WP-Cron, рекомендуем перевести на системный cron для надежности.
Сравнение вариантов реализации автоматического удаления
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Чистый PHP + WP-Cron | Собственная функция с cron задачей | Максимальный контроль, без лишних плагинов | Требует навыков разработки, возможны ошибки в логике |
| Плагины очистки каталога | Готовые решения из репозитория WordPress | Простота установки и настройки | Могут не покрывать специфичные запросы, нагрузка |
| WP-CLI скрипты | Запуск удаления вручную или по расписанию через командную строку | Высокая производительность, надежность | Требуется доступ к серверу, знания CLI |