Диагностика проблемы: зачем и когда нужно автоматическое удаление товаров
Магазины на WooCommerce часто сталкиваются с задачей удаления устаревших, временных или неактуальных товаров. Это бывает необходимо для поддержания актуального ассортимента, оптимизации базы данных и улучшения производительности. Ручное удаление товаров неудобно при большом каталоге, а плагины не всегда дают гибкую настройку по срокам или статусам товаров.
Как определить товары для автоматического удаления
Первым делом нужно сформулировать критерии удаления. Это могут быть:
- Товары, у которых дата публикации старше заданного срока (например, 180 дней).
- Товары с определённым статусом (например, черновики или личные).
- Товары с кастомным метаполем, например, меткой "устаревший".
В примерах ниже мы рассмотрим удаление товаров по дате публикации и по статусу.
Пошаговое решение: автоматическое удаление товаров через WP-Cron
1. Создаём функцию для удаления товаров
function wplancer_delete_old_products() {
$args = array(
'post_type' => 'product',
'post_status' => array('publish', 'draft', 'pending'),
'date_query' => array(
array(
'before' => '180 days ago',
'inclusive' => true,
),
),
'posts_per_page' => -1,
'fields' => 'ids',
);
$old_products = get_posts($args);
if (!empty($old_products)) {
foreach ($old_products as $product_id) {
wp_delete_post($product_id, true); // true - удаление без помещения в корзину
}
}
}2. Регистрируем cron-задачу для периодического запуска
if (!wp_next_scheduled('wplancer_daily_product_cleanup')) {
wp_schedule_event(time(), 'daily', 'wplancer_daily_product_cleanup');
}
add_action('wplancer_daily_product_cleanup', 'wplancer_delete_old_products');3. Добавляем очистку товаров по статусу (например, удалять черновики старше 30 дней)
function wplancer_delete_old_drafts() {
$args = array(
'post_type' => 'product',
'post_status' => 'draft',
'date_query' => array(
array('before' => '30 days ago'),
),
'posts_per_page' => -1,
'fields' => 'ids',
);
$draft_products = get_posts($args);
foreach ($draft_products as $product_id) {
wp_delete_post($product_id, true);
}
}
add_action('wplancer_daily_product_cleanup', 'wplancer_delete_old_drafts');Как проверить, что удаление сработало
- Проверьте логи сервера и WordPress на наличие ошибок.
- В админке WooCommerce убедитесь, что товары с указанными датами и статусами действительно удалены.
- Для теста временно замените интервал в wp_schedule_event с 'daily' на 'hourly' и ждите выполнение задачи, либо запустите функцию вручную через WP-CLI:
wp eval 'wplancer_delete_old_products();'Частые ошибки и как их исправить
- Крон-задача не запускается: Проверьте, что на сайте нет отключения WP-Cron (define('DISABLE_WP_CRON', true);). В этом случае настройте системный cron.
- Функция не удаляет товары: Убедитесь, что в
get_postsправильно указан тип поста и статус. Проверьте права пользователя, под которым запускается код. - Удаление происходит не полностью: Используйте
wp_delete_post($id, true)с параметром true, чтобы миновать корзину.
Практические советы по безопасности и производительности
- Перед удалением создавайте резервную копию базы данных.
- Если товаров очень много, разбивайте удаление на партии по 50-100 штук, чтобы избежать таймаутов.
- Логику удаления по кастомным метаполям можно добавить через
meta_queryвget_posts. - Для больших баз лучше запускать удаление через WP-CLI задачи на сервере, а не через WP-Cron.
Сравнение вариантов реализации автоматического удаления товаров
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| WP-Cron + код в functions.php | Легко настроить, не требует плагинов | Зависит от посещаемости сайта, может не сработать точно во время | Средние магазины с регулярным трафиком |
| Системный cron + WP-CLI | Точный запуск, высокая производительность, подходит для больших сайтов | Требует доступа к серверу и навыков администрирования | Большие магазины с большим каталогом |
| Плагины для автоматического удаления | Простота использования, настройки через UI | Могут быть громоздкими или недостаточно гибкими | Малые магазины, пользователи без навыков программирования |