В чем проблема с потерей данных в WPForms
При работе с большими формами в WPForms часто возникает ситуация, когда пользователь начинает заполнять форму, но по разным причинам (обновление страницы, закрытие вкладки, потеря соединения) данные теряются. Это критично при объемных опросах, заявках, заказах с вложениями, где повторное заполнение формы отнимает много времени. WPForms из коробки не поддерживает автоматическое сохранение промежуточных значений и загруженных файлов.
Решение проблемы сохранения черновиков требует доработки функционала через кастомный код или сторонние подходы, позволяющие сохранять промежуточные данные и восстанавливать их при повторном открытии формы.
Диагностика: что проверить перед реализацией
- Убедитесь, что версия WPForms Pro — базовая версия не поддерживает нужные хуки.
- Проверьте, используются ли AJAX-отправки — это упростит динамическое сохранение данных без перезагрузки.
- Определите, какие поля должны сохраняться (текстовые, выбор, файлы).
- Убедитесь, что на сервере достаточно места для временного хранения файлов.
- Проверьте ограничения хостинга на время сессии и размер POST-запросов.
Пошаговое решение: автосохранение данных и файлов черновика в WPForms
Шаг 1. Создаем обработчик AJAX для сохранения данных черновика
Добавьте в functions.php вашей темы следующий код:
add_action('wp_ajax_save_wpforms_draft', 'save_wpforms_draft_callback');
add_action('wp_ajax_nopriv_save_wpforms_draft', 'save_wpforms_draft_callback');
function save_wpforms_draft_callback() {
if (!isset($_POST['form_id']) || !isset($_POST['form_data'])) {
wp_send_json_error('Неверные данные');
}
$form_id = intval($_POST['form_id']);
$form_data = wp_unslash($_POST['form_data']);
$user_id = get_current_user_id() ?: 0;
// Сохраняем данные в пользовательские мета или в опцию
$key = 'wpforms_draft_' . $form_id . '_' . $user_id;
update_user_meta($user_id, $key, $form_data);
wp_send_json_success('Черновик сохранен');
}
Шаг 2. Добавляем JavaScript для отправки данных формы на сервер
Вставьте этот скрипт в footer или подключите отдельным файлом. Он будет сохранять данные каждые 30 секунд и при изменениях полей:
jQuery(document).ready(function($) {
var form = $('#wpforms-form-123'); // Укажите реальный ID формы
var draftSaveTimer = null;
function saveDraft() {
var formData = form.serialize();
$.post(ajaxurl, {
action: 'save_wpforms_draft',
form_id: 123, // ID формы
form_data: formData
}, function(response) {
if(response.success) {
console.log('Черновик сохранен');
}
});
}
form.on('change input', function() {
clearTimeout(draftSaveTimer);
draftSaveTimer = setTimeout(saveDraft, 30000); // 30 секунд после последнего изменения
});
// Сохраняем сразу при загрузке страницы
saveDraft();
});
Шаг 3. Восстанавливаем данные из черновика при загрузке формы
Добавьте PHP-код, который вставит сохранённые данные в поля формы при загрузке:
add_filter('wpforms_frontend_output', 'wpforms_restore_draft_data', 10, 3);
function wpforms_restore_draft_data($form_html, $form_data, $form) {
$user_id = get_current_user_id() ?: 0;
$key = 'wpforms_draft_' . $form->ID . '_' . $user_id;
$draft = get_user_meta($user_id, $key, true);
if ($draft) {
parse_str($draft, $draft_array);
// Заменяем значения полей в HTML формы
foreach ($draft_array as $field_id => $value) {
$pattern = '/(<input[^>]*name="' . preg_quote($field_id, '/') . '"[^>]*value=")[^"]*("[^>]*>)/i';
$replacement = '${1}' . esc_attr($value) . '${2}';
$form_html = preg_replace($pattern, $replacement, $form_html);
}
}
return $form_html;
}
Шаг 4. Работа с загруженными файлами
Для файлов лучше реализовать отдельный AJAX-обработчик, который будет загружать файлы во временную папку и возвращать идентификаторы, а при отправке формы переносить их в постоянное хранилище.
Пример обработки загрузки в AJAX:
add_action('wp_ajax_upload_wpforms_draft_file', 'upload_wpforms_draft_file_callback');
add_action('wp_ajax_nopriv_upload_wpforms_draft_file', 'upload_wpforms_draft_file_callback');
function upload_wpforms_draft_file_callback() {
if (empty($_FILES['file'])) {
wp_send_json_error('Файл не передан');
}
$file = $_FILES['file'];
$overrides = array('test_form' => false);
$movefile = wp_handle_upload($file, $overrides);
if ($movefile && !isset($movefile['error'])) {
wp_send_json_success(array('url' => $movefile['url'], 'file' => $movefile['file']));
} else {
wp_send_json_error($movefile['error']);
}
}
На клиенте нужно отдельно загружать файлы и сохранять ссылки в локальном состоянии формы.
Проверка результата после внедрения
- Начните заполнять форму, внесите изменения в поля и загрузите файлы.
- Подождите 30 секунд и обновите страницу — введённые данные должны восстановиться.
- Проверьте, что файлы загружаются в указанную временную папку.
- Отправьте форму — убедитесь, что данные и файлы передаются корректно и черновик удаляется.
- Проверьте консоль браузера на наличие ошибок JavaScript и AJAX-запросов.
Частые ошибки и их исправление
- Проблема: AJAX-запросы не выполняются. Проверьте, что
ajaxurlопределён и доступен в JS. Добавьтеwp_localize_scriptдля передачи URL в скрипт. - Данные не сохраняются в user_meta. Убедитесь, что
get_current_user_id()возвращает ID пользователя. Для гостей используйте сессионное хранение или cookie. - Невозможно восстановить файлы. Реализуйте отдельный механизм загрузки файлов и привязки к черновику, так как файлы нельзя сериализовать в строку.
- Форма не отображает восстановленные значения. Проверьте правильность парсинга и замены значений в HTML формы. Используйте уникальные имена полей.
Практические советы по безопасности и производительности
- Обязательно проверяйте права пользователя перед сохранением или чтением черновика.
- Для гостей реализуйте временное хранение в сессиях или cookie с шифрованием.
- Не сохраняйте в черновике чувствительные данные без шифрования.
- Ограничьте размер сохраняемых данных, чтобы не перегружать базу.
- Удаляйте старые черновики с помощью WP-Cron (например, старше 7 дней).
- Используйте nonce для защиты AJAX-запросов от CSRF.
Сравнение вариантов реализации автосохранения черновиков в WPForms
| Метод | Плюсы | Минусы | Подходит для |
|---|---|---|---|
| Сохранение в user_meta через AJAX | Простая реализация, быстрое восстановление | Только для авторизованных пользователей, нет поддержки файлов | Формы для зарегистрированных пользователей без файлов |
| Сохранение в cookie/session | Работает для гостей, без нагрузки на БД | Ограничение по объему данных, проблемы с безопасностью | Маленькие формы без файлов |
| Использование сторонних плагинов (например, Formidable Forms с автосохранением) | Готовые решения, поддержка файлов | Дополнительные расходы, сложность интеграции с WPForms | Крупные проекты, где важна надежность |
| Кастомная загрузка файлов через AJAX + сохранение в БД | Полный контроль, поддержка всех типов полей | Сложная реализация, требует времени на разработку | Проекты с большими формами и загрузкой файлов |