Диагностика задачи: зачем удалять товары после отрицательной оценки
В интернет-магазинах на WooCommerce иногда требуется убрать из продажи товары, которые получили негативные отзывы или оценки ниже определённого порога. Это помогает поддерживать качество ассортимента и не вводить покупателей в заблуждение.
Стандартно WooCommerce не предлагает автоматического удаления товаров по оценкам, поэтому задача решается через кастомный код с использованием хуков и API отзывов.
Шаги решения: как реализовать автоматическое удаление товара
1. Определяем порог отрицательной оценки
Для примера установим порог в 2 звезды. Если средняя оценка товара равна или меньше 2, товар будет удалён.
2. Отслеживаем добавление или изменение отзывов
Отслеживаем событие сохранения комментария (отзыва) с оценкой, чтобы пересчитать средний рейтинг товара.
add_action('comment_post', 'check_product_rating_after_review', 10, 2); // Когда добавляется новый отзыв
function check_product_rating_after_review($comment_ID, $comment_approved) {
if ($comment_approved != 1) return; // Проверяем только одобренные отзывы
$comment = get_comment($comment_ID);
$product_id = $comment->comment_post_ID;
if (get_post_type($product_id) !== 'product') return; // Только для товаров
$average = wc_get_rating_html( wc_get_average_rating($product_id) ); // Получаем рейтинг товара
$rating = floatval(get_post_meta($product_id, '_wc_average_rating', true)); // Получаем средний рейтинг из мета
if ($rating <= 2) {
wp_trash_post($product_id); // Удаляем товар в корзину
}
}3. Пересчет рейтинга товара
WooCommerce хранит средний рейтинг в мета поле _wc_average_rating. Мы используем это значение для проверки порога.
Проверка результата после внедрения
- Добавьте тестовый отзыв с оценкой 1 или 2 звезды к товару.
- Убедитесь, что отзыв одобрен (статус комментария «одобрен»).
- После добавления и одобрения отзыва товар должен автоматически переместиться в корзину (статус «корзина»).
- Проверьте вручную в админке WooCommerce в списке товаров, что товар исчез из активных.
Частые ошибки и как их исправить
- Отсутствие пересчёта рейтинга: Убедитесь, что рейтинг пересчитывается после каждого отзыва. Можно использовать хук
comment_postс задержкой, если рейтинг обновляется позже. - Удаление не тех постов: Проверяйте тип поста через
get_post_type(), чтобы случайно не удалить страницу или пост. - Отзывы без оценки: Проверьте, что отзывы содержат поле с оценкой. Если нет, код надо доработать для извлечения оценки из мета комментария.
Практические советы по безопасности и производительности
- Удаляйте товар в корзину через
wp_trash_post(), а не сразу удаляйте полностью, чтобы избежать потери данных без возможности восстановления. - Добавьте логирование действий удаления товаров, чтобы отслеживать причину удаления в случае ошибок.
- Если отзывы модераторит человек, учитывайте задержку между добавлением и одобрением — автоматизация срабатывает только после одобрения.
Альтернативные варианты реализации
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Код на хуках (как в статье) | Бесплатно, гибко, быстро | Требует знаний PHP, может конфликтовать с другими плагинами | Проверять на тестовом сайте перед запуском |
| Плагин автоматизации отзывов | Простота установки, поддержка | Может быть платным, ограниченная кастомизация | Использовать для сложных сценариев |
| Ручное удаление | Минимальный риск ошибок | Неэффективно для большого каталога | Использовать как временное решение |
Дополнительный пример: удаление товара по суммарному числу отрицательных отзывов
add_action('comment_post', 'delete_product_after_negative_review_count', 10, 2);
function delete_product_after_negative_review_count($comment_ID, $comment_approved) {
if ($comment_approved != 1) return;
$comment = get_comment($comment_ID);
$product_id = $comment->comment_post_ID;
if (get_post_type($product_id) !== 'product') return;
$args = [
'post_id' => $product_id,
'status' => 'approve',
'meta_key' => 'rating',
'meta_value' => 2,
'meta_compare' => '<=',
'count' => true
];
$negative_count = get_comments($args);
if ($negative_count >= 3) {
wp_trash_post($product_id);
}
}