Проблема с просроченными купонами в WooCommerce
В WooCommerce купоны часто используются для акций и скидок. После окончания срока действия или достижения лимита использования такие купоны остаются в базе данных, создавая беспорядок и потенциально мешая администрированию магазина. Ручное удаление неэффективно при большом количестве купонов, поэтому нужна автоматизация.
Диагностика проблемы: как понять, что купоны просрочены и требуют удаления
WooCommerce хранит купоны как записи типа shop_coupon. В метаданных купона есть ключи date_expires (в формате UNIX timestamp) и usage_count (количество использований). Чтобы выявить просроченные купоны, нужно проверить:
- Истек ли срок действия (
date_expiresменьше текущего времени). - Достигнут ли лимит использования (
usage_count>=usage_limit).
Для диагностики можно использовать следующий SQL-запрос в phpMyAdmin или через wpdb:
SELECT ID, post_title FROM wp_posts p
JOIN wp_postmeta m ON p.ID = m.post_id
WHERE p.post_type = 'shop_coupon'
AND (
(m.meta_key = 'date_expires' AND m.meta_value < UNIX_TIMESTAMP())
OR
(m.meta_key = 'usage_limit' AND
(SELECT meta_value FROM wp_postmeta WHERE post_id = p.ID AND meta_key = 'usage_count') >= m.meta_value
)
);Пошаговое решение: автоматическое удаление просроченных купонов через хук WordPress
Реализуем функцию, которая будет запускаться по расписанию (WP Cron) и удалять купоны, срок действия которых истек или достигнут лимит использования.
1. Создание функции удаления
function wpmg_delete_expired_coupons() {
$args = [
'post_type' => 'shop_coupon',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => [
'relation' => 'OR',
[
'key' => 'date_expires',
'value' => time(),
'compare' => '<',
'type' => 'NUMERIC',
],
[
'key' => 'usage_limit',
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC',
],
],
];
$coupons = get_posts($args);
foreach ($coupons as $coupon) {
$usage_limit = (int) get_post_meta($coupon->ID, 'usage_limit', true);
$usage_count = (int) get_post_meta($coupon->ID, 'usage_count', true);
$date_expires = (int) get_post_meta($coupon->ID, 'date_expires', true);
// Проверяем условия удаления
if (($date_expires && $date_expires < time()) || ($usage_limit > 0 && $usage_count >= $usage_limit)) {
wp_delete_post($coupon->ID, true); // Полное удаление
}
}
}2. Регистрация WP Cron для запуска функции
Добавим событие, которое будет запускать очистку ежедневно.
function wpmg_schedule_coupon_cleanup() {
if (!wp_next_scheduled('wpmg_daily_coupon_cleanup')) {
wp_schedule_event(time(), 'daily', 'wpmg_daily_coupon_cleanup');
}
}
add_action('wp', 'wpmg_schedule_coupon_cleanup');
add_action('wpmg_daily_coupon_cleanup', 'wpmg_delete_expired_coupons');3. Очистка WP Cron при деактивации темы или плагина
function wpmg_clear_coupon_cleanup_schedule() {
$timestamp = wp_next_scheduled('wpmg_daily_coupon_cleanup');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpmg_daily_coupon_cleanup');
}
}
register_deactivation_hook(__FILE__, 'wpmg_clear_coupon_cleanup_schedule');Проверка результата после внедрения
Для проверки работы решения:
- Создайте пару купонов с прошедшей датой истечения или с лимитом использования, достигнутым в ходе тестовых заказов.
- Запустите вручную функцию в консоли WP-CLI:
wp eval 'wpmg_delete_expired_coupons();' - Проверьте, что данные купоны удалены из админки WooCommerce > Купоны.
- Через 24 часа проверьте, что новые просроченные купоны автоматически удаляются WP Cron-ом.
Частые ошибки и как их исправить
- Купоны не удаляются: проверьте, что WP Cron работает на вашем сервере (используйте плагин WP Crontrol для отладки).
- Удаляются не те купоны: уточните условия в
meta_query, внимательно проверьте типы данных и сравнения. - Слишком большая нагрузка при выборке: используйте пагинацию в
get_postsи обрабатывайте пачками. - Функция не подключена: убедитесь, что код добавлен в functions.php вашей активной темы или в плагин.
Практические советы по безопасности и производительности
- Для избегания конфликтов и потери данных сохраняйте резервную копию базы перед активацией автоматического удаления.
- Используйте
wp_delete_post($id, true)для полного удаления без помещения в корзину. - Проверяйте логи ошибок сервера и WooCommerce на предмет сбоев при работе скрипта.
- Если база очень большая, настройте обработку купонов частями с помощью пагинации
'posts_per_page' => 50и цикла по страницам.
Сравнение методов удаления просроченных купонов
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Ручное удаление | Полный контроль | Трудозатратно при большом количестве | Использовать для единичных случаев |
| Плагины очистки | Простота установки | Может быть избыточным, нагрузка | Подходит для магазинов с небольшим числом купонов |
| Код с WP Cron (наше решение) | Автоматизация, контроль, без лишних плагинов | Требует базовых навыков разработки | Оптимальный вариант для большинства магазинов |