Проблема: как автоматически отключить отзывы на товары после определённого срока?
В WooCommerce стандартно отзывы остаются открытыми на товар бессрочно. В некоторых магазинах требуется ограничить возможность оставлять отзывы, например, через 30 дней после покупки, чтобы избежать спама и увеличить релевантность отзывов. В этой статье разберём, как реализовать автоматическое отключение отзывов на товар после заданного срока.
Диагностика проблемы
Если вы хотите ограничить отзывы по времени, но в WooCommerce нет такой настройки, значит, нужно внедрять кастомный код. Для проверки, что отзывы включены на уровне настроек, перейдите в WooCommerce → Настройки → Продукты → Общие и убедитесь, что отмечена опция «Включить отзывы». Если она отключена, никакие доработки не сработают.
Также проверьте, что тема поддерживает вывод отзывов, иначе отключение будет незаметным.
Пошаговое решение: код для автоматического отключения отзывов после 30 дней
Реализуем логику, при которой для каждого товара отзывы автоматически отключаются, если с даты последней покупки прошло более 30 дней. Для этого используем хук comments_open, который позволяет программно запретить открытие комментариев (отзывов).
Добавьте следующий код в файл functions.php вашей дочерней темы или в кастомный плагин:
add_filter('comments_open', 'disable_reviews_after_period', 10, 2);
function disable_reviews_after_period($open, $post_id) {
if (get_post_type($post_id) !== 'product') {
return $open; // Не трогаем остальные типы записей
}
// Получаем ID текущего пользователя
$user_id = get_current_user_id();
if (!$user_id) {
return $open; // Неавторизованные пользователи могут оставлять отзывы, если разрешено
}
// Получаем заказы пользователя с этим товаром
$orders = wc_get_orders(array(
'customer_id' => $user_id,
'limit' => -1,
'status' => array('completed', 'processing'),
'return' => 'ids',
));
$has_recent_purchase = false;
$now = current_time('timestamp');
$period_seconds = 30 * DAY_IN_SECONDS; // 30 дней
foreach ($orders as $order_id) {
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item) {
if ($item->get_product_id() == $post_id) {
$purchase_date = strtotime($order->get_date_completed());
if (!$purchase_date) {
$purchase_date = strtotime($order->get_date_created());
}
if ($purchase_date && ($now - $purchase_date) <= $period_seconds) {
$has_recent_purchase = true;
break 2; // Нашли покупку в срок — можно оставлять отзывы
}
}
}
}
// Если нет покупок за последние 30 дней — отключаем отзывы
return $has_recent_purchase ? $open : false;
}В этом коде:
- Фильтр
comments_openпроверяет для каждого товара, открыт ли комментарий (отзыв). - Проверяется, что пользователь залогинен и действительно покупал товар в последние 30 дней.
- Если покупок нет или они старше 30 дней — отзывы отключаются.
Проверка результата
Для проверки выполните такие шаги:
- Залогиньтесь как пользователь, который недавно купил товар (в пределах 30 дней). Зайдите на страницу товара — отзывы должны быть доступны.
- Залогиньтесь как пользователь без недавних покупок — отзывы должны быть закрыты.
- Проверьте страницу товара вне авторизации — отзывы могут быть открыты или закрыты, в зависимости от настроек WooCommerce (в коде отзывы открыты для гостей, если не отключены глобально).
Если отзывы не отображаются корректно, убедитесь, что тема выводит шаблон comments.php для товаров.
Частые ошибки и как их исправить
- Отзывы остались открытыми для всех: проверьте, что функция
wc_get_ordersвозвращает заказы пользователя правильно. Возможно, пользователь не залогинен, или есть проблемы с правами. - Отзывы закрыты для всех: возможно, дата покупки не определяется (например, заказ не завершён). В коде учтён fallback на дату создания заказа, но проверьте данные в админке WooCommerce.
- Проблемы с производительностью: выборка всех заказов пользователя может быть тяжелой на больших магазинах. Для оптимизации стоит кэшировать результаты или использовать более узкие запросы.
- Отзывы не отображаются в теме: убедитесь, что в шаблоне single-product.php или comments.php есть код для вывода отзывов
comments_template().
Практические советы по безопасности и производительности
- Код не допускает SQL-инъекций, так как использует штатные функции WooCommerce и WordPress.
- Для ускорения работы на крупных сайтах рекомендуется кешировать результаты проверки покупок, например, с помощью
transient. - Обязательно тестируйте код на staging-среде перед внедрением на рабочем сайте.
- Если используете сторонние плагины безопасности или кеширования, убедитесь, что они не конфликтуют с вашим фильтром
comments_open.
Сравнение решений: плагин vs кастомный код
| Критерий | Плагин | Кастомный код | Компромисс |
|---|---|---|---|
| Гибкость | Ограничена настройками плагина | Максимальная, можно подстроить под любые условия | Зависит от навыков разработки |
| Производительность | Может быть избыточно тяжелым | Оптимизируемый под задачи | Нужна оптимизация кода |
| Безопасность | Зависит от качества плагина | Контролируется разработчиком | Требует знаний |
| Обновления | Обновляется автором | Зависит от разработчика сайта | Риск устаревания кода |