Диагностика задачи: зачем и когда нужно удалять старые товары автоматически
В крупных магазинах на WooCommerce может накапливаться множество устаревших или снятых с продажи товаров. Ручное удаление таких товаров занимает много времени и увеличивает риск ошибок. Часто возникает задача настроить автоматическое удаление товаров, которые были опубликованы более определённого времени назад (например, 6 месяцев или 1 год). Это помогает поддерживать актуальность каталога и оптимизировать базу данных.
Пошаговое решение: как настроить автоматическое удаление старых товаров
1. Создаём пользовательскую функцию для удаления товаров
Для удаления товаров по дате публикации используем WP_Query с параметром date_query и функцию wp_delete_post(). Добавим функцию в файл functions.php вашей темы или создадим отдельный плагин.
function wc_delete_old_products() {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'date_query' => array(
array(
'before' => date('Y-m-d', strtotime('-6 months')),
'inclusive' => true,
),
),
'posts_per_page' => -1,
'fields' => 'ids',
);
$old_products = get_posts($args);
foreach ($old_products as $product_id) {
wp_delete_post($product_id, true); // true - безвозвратное удаление
}
}2. Настраиваем автоматический запуск через WP-Cron
Чтобы функция запускалась регулярно (например, раз в сутки), добавим планировщик заданий WP-Cron.
// Регистрируем событие при активации темы/плагина
function wc_schedule_old_product_deletion() {
if (!wp_next_scheduled('wc_delete_old_products_hook')) {
wp_schedule_event(time(), 'daily', 'wc_delete_old_products_hook');
}
}
add_action('wp', 'wc_schedule_old_product_deletion');
// Отписка при деактивации темы/плагина
function wc_unschedule_old_product_deletion() {
$timestamp = wp_next_scheduled('wc_delete_old_products_hook');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wc_delete_old_products_hook');
}
}
// Повесим на соответствующий хук деактивации плагина или темы
// Основная функция по хуку
add_action('wc_delete_old_products_hook', 'wc_delete_old_products');3. Проверяем права и резервное копирование
Убедитесь, что у вас есть полный бэкап сайта и базы данных перед запуском автоматического удаления. Также желательно добавить проверку прав пользователя или IP, если будете запускать функцию вручную.
Проверка результата после внедрения
- Запустите функцию вручную через админку (например, временно добавив вызов
wc_delete_old_products();вfunctions.phpи обновив страницу). Убедитесь, что товары старше 6 месяцев удаляются. - Проверьте журнал ошибок и логи сервера на наличие уведомлений.
- Через 24 часа проверьте, что функция сработала автоматически (можно добавить логирование с записью в файл или БД).
Частые ошибки и как исправить
- Товары не удаляются: проверьте, что хук WP-Cron работает (проверьте наличие событий через плагин WP Crontrol).
- Удаляются не те товары: уточните параметры
date_queryиpost_statusв запросе. - Появляются ошибки прав доступа: убедитесь, что скрипт запускается с нужными правами и что сервер не блокирует удаление.
- WP-Cron не срабатывает на хостинге: настройте системный cron или используйте плагин для эмуляции cron-событий.
Практические советы по безопасности и производительности
- Добавляйте в функцию удаление только по статусу
publish, чтобы не удалять случайно черновики или запланированные товары. - Если товаров много, делайте удаление пакетами (например, по 20-50 штук за один запуск), чтобы не превышать лимиты памяти и времени выполнения.
- Для логирования добавьте запись в отдельный файл или таблицу в базе — это позволит отслеживать, когда и какие товары были удалены.
- Перед удалением можно отправлять уведомления администратору с отчётом.
- Резервное копирование базы — обязательный шаг перед автоматическими удалениями.
Пример пакетного удаления с логированием
function wc_delete_old_products_batch() {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'date_query' => array(
array(
'before' => date('Y-m-d', strtotime('-6 months')),
'inclusive' => true,
),
),
'posts_per_page' => 20,
'fields' => 'ids',
);
$old_products = get_posts($args);
if (empty($old_products)) {
error_log('WC: Нет старых товаров для удаления');
return;
}
foreach ($old_products as $product_id) {
wp_delete_post($product_id, true);
error_log('WC: Удалён товар ID ' . $product_id);
}
}
add_action('wc_delete_old_products_hook', 'wc_delete_old_products_batch');Таблица сравнения вариантов удаления старых товаров
| Метод | Плюсы | Минусы |
|---|---|---|
| Ручное удаление через админку | Простота, контроль | Трудозатратно, риск пропуска |
| Автоматизация через WP-Cron + get_posts() + wp_delete_post() | Полный контроль, гибкость настроек, автоматизация | Нужен опыт, требуется настройка cron, возможны ошибки без бэкапа |
| Плагины для очистки товаров | Простота установки, готовые решения | Могут быть избыточны, не всегда гибкие |