Проблема: необходимость автоматического удаления устаревших товаров в WooCommerce
При работе с WooCommerce может возникнуть задача автоматического удаления товаров, срок действия которых истек, или которые больше не актуальны (например, сезонные предложения, товары с датой окончания акции и т.п.). Ручное удаление таких товаров неудобно и чревато ошибками — особенно при большом ассортименте.
В стандартном WooCommerce нет встроенного инструмента для автоматического удаления товаров по дате или метке срока годности. Решение — реализовать логику через кастомный код с использованием WP-Cron и WP_Query.
Диагностика: как определить товары для удаления
Для автоматического удаления нужно однозначно понимать, по какому признаку товар считать устаревшим. Чаще всего применяются следующие подходы:
- Использование пользовательского метаполя с датой окончания действия товара (
meta_key = 'expiration_date'). - Использование таксономии (например, категория или тег «устаревший»).
- Использование стандартного поля
post_dateдля товаров, которые не обновлялись определённое время.
В этом примере мы рассмотрим автоматическое удаление товаров с метаполем expiration_date, в котором хранится дата в формате YYYY-MM-DD.
Пошаговое решение: код для автоматического удаления товаров с истекшей датой
1. Добавление метаполя expiration_date при создании или редактировании товара
Если у вас ещё нет поля expiration_date, его можно добавить через ACF или вручную, например, с помощью метабокса.
2. Функция для удаления просроченных товаров
function wpteam_delete_expired_products() {
$today = date('Y-m-d');
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'expiration_date',
'value' => $today,
'compare' => '<',
'type' => 'DATE',
),
),
'fields' => 'ids',
);
$expired_products = get_posts($args);
foreach ($expired_products as $product_id) {
wp_delete_post($product_id, true); // true - удаляет без возможности восстановления
}
}3. Планирование задачи с помощью WP-Cron
Чтобы функция выполнялась регулярно, регистрируем cron-задачу.
if (!wp_next_scheduled('wpteam_delete_expired_products_hook')) {
wp_schedule_event(time(), 'daily', 'wpteam_delete_expired_products_hook');
}
add_action('wpteam_delete_expired_products_hook', 'wpteam_delete_expired_products');4. Добавление кода в тему или плагин
Рекомендуется использовать дочернюю тему или свой плагин для добавления этого кода. Вставьте весь код в functions.php или отдельный файл плагина.
Проверка результата после внедрения
- Создайте несколько товаров с метаполем
expiration_date, включая даты в прошлом и будущем. - Запустите функцию вручную через
wpteam_delete_expired_products()в консоли WP-CLI или временно вызовите её в коде. - Проверьте, что товары с прошедшей датой удалились без ошибок.
- Убедитесь, что cron-задача запланирована: в терминале WP-CLI выполните
wp cron event listи найдитеwpteam_delete_expired_products_hook.
Частые ошибки и их исправление
- Товары не удаляются: Проверьте, что у товаров действительно есть метаполе
expiration_dateв правильном формате. Используйтеvar_dump(get_post_meta($product_id, 'expiration_date', true));для проверки. - Функция удаляет лишние товары: Убедитесь, что сравнение даты корректное и формат даты в метаполе соответствует
Y-m-d. - WP-Cron не срабатывает: Проверьте режим работы WP-Cron (на сервере должен быть трафик) или настройте системный cron для вызова
wp-cron.php. - Ошибка при удалении товаров: Проверьте права пользователя, под которым работает скрипт, и убедитесь, что функция
wp_delete_post()вызывается с параметром$force_delete = trueдля полного удаления.
Советы по безопасности и производительности
- Используйте
wp_delete_post()с параметромtrue, чтобы полностью удалить товары без помещения в корзину, если это необходимо. - При большом количестве товаров используйте пагинацию в запросе, чтобы не перегружать память:
$paged = 1;
do {
$args['paged'] = $paged;
$expired_products = get_posts($args);
foreach ($expired_products as $product_id) {
wp_delete_post($product_id, true);
}
$paged++;
} while (count($expired_products) > 0);- Перед массовым удалением сделайте резервную копию базы данных.
- Для больших магазинов с высокой нагрузкой рассмотрите создание отдельной задачи на сервере (cron) вместо WP-Cron.
Сравнение вариантов реализации удаления товаров
| Метод | Плюсы | Минусы |
|---|---|---|
| Удаление по метаполю expiration_date + WP-Cron | Гибкий, настраиваемый, полностью автоматизированный | Требует правильного заполнения метаполя, настройка cron |
| Ручное удаление через админку WooCommerce | Просто, не требует кода | Неэффективно для большого количества товаров, риск ошибки |
| Использование плагинов автоматизации (например, WP All Import с cron) | Может включать расширенные функции | Платные, могут быть избыточными для простой задачи |