Зачем нужна автоматическая система отзывов в WordPress
Отзывы — один из ключевых элементов для повышения доверия к сайту и улучшения пользовательского опыта. Ручное управление отзывами занимает много времени, особенно если их большое количество. Автоматизация процесса сбора, модерации и уведомления позволяет существенно сократить нагрузку и улучшить качество обратной связи. В этой статье вы узнаете, как создать на WordPress собственную систему отзывов с автоматической модерацией, уведомлениями по email и удобным интерфейсом для пользователей.
Рассмотрим, как использовать кастомные типы записей, AJAX для динамического добавления отзывов без перезагрузки страницы, а также примеры плагинов, которые помогут с модерацией и защитой от спама.
Создание кастомного типа записей для отзывов
Первым шагом создадим кастомный тип записей wpcommunity_review, в котором будут храниться отзывы пользователей. Это позволит отделить отзывы от постов и страниц, удобно управлять ими в админке.
function wpcommunity_register_review_cpt() {
$labels = [
'name' => 'Отзывы',
'singular_name' => 'Отзыв',
'add_new' => 'Добавить отзыв',
'add_new_item' => 'Добавить новый отзыв',
'edit_item' => 'Редактировать отзыв',
'all_items' => 'Все отзывы',
'menu_name' => 'Отзывы',
'name_admin_bar' => 'Отзыв',
];
$args = [
'labels' => $labels,
'public' => false,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => ['title', 'editor', 'author'],
'has_archive' => false,
'rewrite' => false,
'show_in_rest' => true,
];
register_post_type('wpcommunity_review', $args);
}
add_action('init', 'wpcommunity_register_review_cpt');Этот тип записей невидим на фронтенде по умолчанию, но позволит удобно хранить отзывы в базе и управлять ими.
Добавление пользовательских полей для оценки
Отзывы часто включают не только текст, но и рейтинг. Добавим метаполе для оценки от 1 до 5 с помощью API метаполей:
function wpcommunity_add_review_meta_boxes() {
add_meta_box('wpcommunity_review_rating', 'Рейтинг', 'wpcommunity_review_rating_meta_box_callback', 'wpcommunity_review', 'side');
}
add_action('add_meta_boxes', 'wpcommunity_add_review_meta_boxes');
function wpcommunity_review_rating_meta_box_callback($post) {
$value = get_post_meta($post->ID, '_wpcommunity_review_rating', true);
echo '<label for="wpcommunity_review_rating_field">Оценка (1-5):</label>';
echo '<input type="number" id="wpcommunity_review_rating_field" name="wpcommunity_review_rating_field" value="' . esc_attr($value) . '" min="1" max="5" />';
}
function wpcommunity_save_review_meta_box_data($post_id) {
if (array_key_exists('wpcommunity_review_rating_field', $_POST)) {
update_post_meta($post_id, '_wpcommunity_review_rating', intval($_POST['wpcommunity_review_rating_field']));
}
}
add_action('save_post', 'wpcommunity_save_review_meta_box_data');Форма добавления отзыва с использованием AJAX
Чтобы пользователи могли оставлять отзывы без перезагрузки страницы, создадим простую AJAX-форму. Она будет отправлять данные на сервер, где отзыв сохранится как новая запись типа wpcommunity_review в статусе pending для модерации.
HTML и JavaScript формы
Добавьте на страницу следующий код формы и скрипта:
<form id="wpcommunity-review-form">
<input type="text" name="title" placeholder="Заголовок отзыва" required />
<textarea name="content" placeholder="Текст отзыва" required></textarea>
<label>Рейтинг:
<select name="rating" required>
<option value="">Выберите оценку</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</label>
<button type="submit">Отправить отзыв</button>
<div id="wpcommunity-review-message"></div>
</form>
<script>
document.getElementById('wpcommunity-review-form').addEventListener('submit', function(e) {
e.preventDefault();
var formData = new FormData(this);
formData.append('action', 'wpcommunity_submit_review');
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
method: 'POST',
credentials: 'same-origin',
body: formData
})
.then(response => response.json())
.then(data => {
var messageDiv = document.getElementById('wpcommunity-review-message');
if(data.success) {
messageDiv.textContent = 'Спасибо за ваш отзыв! После проверки он появится на сайте.';
this.reset();
} else {
messageDiv.textContent = 'Ошибка: ' + data.data;
}
});
});
</script>Обработка AJAX запроса в functions.php
Теперь добавим обработчик на PHP, который сохранит отзыв в базу и отправит уведомление администратору.
function wpcommunity_ajax_submit_review() {
if (!isset($_POST['title'], $_POST['content'], $_POST['rating'])) {
wp_send_json_error('Не все поля заполнены');
}
$title = sanitize_text_field($_POST['title']);
$content = sanitize_textarea_field($_POST['content']);
$rating = intval($_POST['rating']);
if ($rating < 1 || $rating > 5) {
wp_send_json_error('Некорректный рейтинг');
}
$review_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_type' => 'wpcommunity_review',
'post_status' => 'pending',
'post_author' => 0
]);
if (is_wp_error($review_id) || !$review_id) {
wp_send_json_error('Ошибка при сохранении отзыва');
}
update_post_meta($review_id, '_wpcommunity_review_rating', $rating);
// Отправка уведомления админу
$admin_email = get_option('admin_email');
$subject = 'Новый отзыв ожидает модерации';
$message = "Поступил новый отзыв:\n\n" . $title . "\n" . $content . "\nРейтинг: " . $rating;
wp_mail($admin_email, $subject, $message);
wp_send_json_success();
}
add_action('wp_ajax_wpcommunity_submit_review', 'wpcommunity_ajax_submit_review');
add_action('wp_ajax_nopriv_wpcommunity_submit_review', 'wpcommunity_ajax_submit_review');Модерация и защита от спама
Чтобы не захламлять базу спамом, рекомендуем включить встроенную в WordPress модерацию комментариев и отзывы сохранять с статусом pending. Для защиты от ботов можно добавить простую капчу или использовать популярные плагины:
- Clearfy Pro — улучшает безопасность и очищает сайт от спама;
- Antispam Bee — бесплатный плагин для борьбы со спамом в комментариях и отзывах;
- Добавление Google reCAPTCHA на форму отзывов с помощью плагина Google Captcha (reCAPTCHA) by BestWebSoft.
Пример простой проверки поля honeypot (скрытое поле, которое должен оставить пустым человек):
if (!empty($_POST['wpcommunity_honeypot'])) {
wp_send_json_error('Подозрение на спам');
}Вывод отзывов на сайте с пагинацией и фильтрацией по рейтингу
После модерации отзывы можно выводить на сайте с помощью WP_Query. Добавим пример вывода 5 отзывов на страницу с возможностью фильтрации по рейтингу:
$args = [
'post_type' => 'wpcommunity_review',
'post_status' => 'publish',
'posts_per_page' => 5,
'meta_query' => [],
'paged' => get_query_var('paged') ? get_query_var('paged') : 1,
];
if (!empty($_GET['rating'])) {
$rating = intval($_GET['rating']);
if ($rating >= 1 && $rating <= 5) {
$args['meta_query'][] = [
'key' => '_wpcommunity_review_rating',
'value' => $rating,
'compare' => '=',
'type' => 'NUMERIC',
];
}
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$rating = get_post_meta(get_the_ID(), '_wpcommunity_review_rating', true);
echo '<h3>' . get_the_title() . '</h3>';
echo '<p>' . get_the_content() . '</p>';
echo '<p>Рейтинг: ' . intval($rating) . '</p>';
}
// пагинация
echo paginate_links(['total' => $query->max_num_pages]);
}
wp_reset_postdata();Для удобства добавьте в шаблон форму фильтрации по рейтингу:
<form method="GET">
<select name="rating" onchange="this.form.submit()">
<option value="">Все рейтинги</option>
<option value="5">5</option>
<option value="4">4</option>
<option value="3">3</option>
<option value="2">2</option>
<option value="1">1</option>
</select>
</form>Дополнительные плагины для расширения функционала отзывов
Если хотите сэкономить время и получить готовое решение, обратите внимание на плагины с расширенными возможностями:
- Expert Review — плагин с удобной системой рейтингов, модерации и шаблонов вывода;
- Site Reviews — мощный бесплатный плагин с поддержкой коротких кодов, виджетов и интеграцией с популярными темами;
- WP Community темы, например WPCommunity, позволяют стилизовать отзывы в соответствии с дизайном сайта.