Диагностика задачи: зачем ограничивать количество отправок формы
В ряде сценариев необходимо ограничить, сколько раз один пользователь может отправить форму на сайте. Например, при проведении опроса, регистрации на событие или акциях с ограниченным участием. Без такой защиты можно получить искажение данных, спам или перегрузку базы данных.
WPForms не имеет встроенной функции ограничения количества отправок на одного пользователя по умолчанию, поэтому требуется кастомизация с проверкой по IP, куки, user ID или email.
Подходы к ограничению отправок в WPForms
1. Ограничение по ID зарегистрированного пользователя
Если на сайте есть авторизация, можно ограничить отправку формы одним и тем же пользователем по его ID в WordPress.
2. Ограничение по cookie для гостей
Для неавторизованных пользователей можно ставить cookie после отправки и блокировать повторную отправку.
3. Ограничение по IP-адресу
Ограничение по IP — менее надежно, так как IP могут меняться или быть общими у нескольких пользователей.
Пошаговое решение: ограничение отправок по ID пользователя и cookie
Шаг 1. Добавляем проверку перед отправкой формы
Используем хук wpforms_process_before, чтобы остановить отправку, если пользователь уже отправлял форму.
add_action('wpforms_process_before', 'limit_wpforms_submissions_per_user', 10, 3);
function limit_wpforms_submissions_per_user($fields, $entry, $form_data) {
$form_id = $form_data['id'];
$user_id = get_current_user_id();
$cookie_name = 'wpforms_submitted_' . $form_id;
// Проверяем для зарегистрированных пользователей
if ($user_id) {
global $wpdb;
$count = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}wpforms_entries WHERE user_id = %d AND form_id = %d",
$user_id, $form_id
));
if ($count > 0) {
wpforms()->process->errors[$form_id]['header'] = 'Вы уже отправляли эту форму.';
return;
}
} else {
// Проверяем cookie для гостей
if (isset($_COOKIE[$cookie_name])) {
wpforms()->process->errors[$form_id]['header'] = 'Вы уже отправляли эту форму.';
return;
}
}
}Шаг 2. Устанавливаем cookie после успешной отправки
Чтобы ограничение по cookie работало, ставим куку при успешной отправке формы с помощью хука wpforms_process_complete.
add_action('wpforms_process_complete', 'set_wpforms_submission_cookie', 10, 4);
function set_wpforms_submission_cookie($fields, $entry, $form_data, $entry_id) {
$form_id = $form_data['id'];
$cookie_name = 'wpforms_submitted_' . $form_id;
setcookie($cookie_name, '1', time() + DAY_IN_SECONDS * 30, COOKIEPATH, COOKIE_DOMAIN);
}Проверка результата
- Авторизуйтесь под одним пользователем и отправьте форму. Попытка повторной отправки должна выдать ошибку.
- Выйдите из аккаунта, очистите куки или используйте режим инкогнито, отправьте форму — повторная отправка в рамках срока действия cookie должна быть заблокирована.
- Убедитесь, что сообщение об ошибке отображается корректно вверху формы.
Частые ошибки и их устранение
- Ошибка: сообщение об ошибке не отображается. Проверьте, что используется правильный ключ для ошибок:
wpforms()->process->errors[$form_id]['header']. Сообщение должно выводиться в блоке заголовка формы. - Cookie не ставится или не работает. Убедитесь, что вызов
setcookie()происходит ДО вывода контента и что параметры COOKIEPATH и COOKIE_DOMAIN корректны. - Подсчет отправок для пользователей не работает. Проверьте, что таблица
wpforms_entriesсуществует и в ней есть полеuser_id. Если нет, понадобится кастомное сохранение user_id при отправке формы.
Практические советы по безопасности и производительности
- Для точного подсчёта отправок по пользователям рекомендуем сохранять user_id в пользовательском поле записи формы через хук
wpforms_process_entry_save, если плагин не делает этого по умолчанию. - Используйте nonce и стандартные WPForms механизмы защиты от CSRF.
- Для снижения нагрузки кэшируйте результаты подсчёта отправок, если на сайте очень много трафика.
Таблица сравнения подходов ограничения отправок
| Метод | Преимущества | Недостатки | Применимость |
|---|---|---|---|
| По user ID | Точно ограничивает зарегистрированных пользователей | Не работает для гостей | Сайты с авторизацией |
| По cookie | Работает для гостей | Легко обойти очисткой cookie | Для неавторизованных пользователей |
| По IP | Простая реализация | Общие IP, VPN, динамические IP | Дополнительный уровень защиты |