Форма обратной связи - веб-форма, письма, свой обработчик
Ставим форму обратной связи на страницу, разбираемся, где искать пришедшие заявки, и добавляем свою проверку перед сохранением результата.
Решение
Ставим веб-форму на страницу:
$APPLICATION->IncludeComponent('bitrix:form.result.new', '', [ 'WEB_FORM_ID' => 1, // идентификатор формы из настроек модуля 'USE_EXTENDED_ERRORS' => 'Y', // подробные сообщения об ошибках полей 'SEF_MODE' => 'N', 'CACHE_TIME' => 0, // форму не кэшируем: в ней живая сессия]);Поля рисует не шаблон компонента, а описание формы в настройках модуля. Добавить поле в разметку недостаточно: оно должно существовать в самой форме, иначе введённое значение никуда не сохранится и в письмо не попадёт.
Читаем результаты из кода:
use Bitrix\Main\Loader;
Loader::includeModule('form');$res = CFormResult::GetList(1, ($by = 'ID'), ($order = 'DESC'), [], $isFiltered);while ($result = $res->Fetch()) { printf("%-6s %-20s %s\n", $result['ID'], $result['DATE_CREATE'], $result['USER_AUTH'] ?: 'гость');}Ответы хранятся в базе независимо от отправки письма. Даже при полностью сломанной почте заявки продолжают накапливаться, и это главный довод в пользу веб-формы против самописной формы на одном письме.
Проверяем, куда уходит письмо:
$res = CFormResult::GetList(1, ($by = 'ID'), ($order = 'DESC'), [], $f);// шаблон письма и получатель настраиваются в почтовых событиях модуля почты$events = CEventType::GetList(['TYPE_ID' => 'FORM_FILLING_FORM_1']);while ($event = $events->Fetch()) { printf("событие %s: %s\n", $event['EVENT_NAME'], $event['NAME']);}Каждая веб-форма создаёт при сохранении своё почтовое событие. Адрес получателя задаётся в шаблоне письма, а не в настройках формы, и жалобу «письмо не приходит» разбирают именно в шаблоне и в журнале отправки.
Добавляем свою проверку перед сохранением:
AddEventHandler('form', 'onBeforeResultAdd', static function ($formId, &$fields) { if ($formId == 1 && empty($fields['form_text_2'])) { return false; // отклоняем результат: обязательное поле пустое } });Обработчик получает поля до записи и умеет отклонить результат целиком. Проверка на стороне браузера от него не избавляет: запрос легко отправить в обход разметки, и на сервере он выглядит обычным заполнением формы.
Отдельная веб-форма заводится под каждый сценарий: заявка, отзыв, вопрос по заказу. Разделение по формам сразу даёт раздельные списки результатов и раздельные письма получателям, а склеивать одну общую форму обратно на несколько потом заметно дороже, чем развести их с самого начала.
Своя форма нужна там, где сценарий выходит за рамки сбора заявок: данные уходят во внешнюю систему, ответ зависит от введённого, поля появляются по условию. Такую форму принимают контроллером и сохраняют своим кодом, а хранение и письма пишут руками - и именно этот объём работы веб-форма и экономит.
Типичные проблемы
Форма отправляется, письма нет.
Проблема в отправке почты, а не в форме. Результат при этом сохранён в базе, и заявка не потеряна.
Добавленное в шаблон поле не сохраняется.
Его нет в описании формы. Компонент принимает только те поля, которые заведены в настройках модуля.
Форма отправляется дважды.
Страница с формой закэширована вместе с ключом сессии. Форму выводят без кэширования компонента.
Проверка обходится пустым запросом.
Она сделана только на стороне браузера. Серверную проверку добавляют обработчиком события сохранения.
Результаты есть, а в фильтре админки не находятся.
Фильтр ищет по значениям полей, а не по тексту письма. Поиск по свободному тексту в результатах ограничен.
Частые вопросы
Как отправить копию письма клиенту?
Вторым почтовым событием со своим шаблоном и получателем из поля формы. Одно событие одному получателю - обычная схема.
Можно ли приложить файл к заявке?
Да, полем типа «файл» в описании формы. Файл сохраняется вместе с результатом, а в письмо попадает ссылкой.
Как показать форму без перезагрузки страницы?
Режимом обмена у компонента или своим запросом к контроллеру. Второй путь даёт полный контроль над разметкой и ответом.
Куда деваются результаты после удаления формы?
Удаляются вместе с ней. Перед удалением формы результаты выгружают: восстановить их потом неоткуда.
Смежное
-
Форма обратной связи - оглавление подтемы
-
Согласие на обработку данных: соглашение, компонент, запись факта - что приложить к форме по закону
-
Спам через формы сайта: капча, скрытое поле, ограничение частоты - что делать с потоком заявок от ботов
-
Опрос на сайте: голосование, результаты, повторное участие - когда вместо ответа нужен голос
-
Веб-формы - устройство модуля целиком
-
Настройка отправки почты - почему письма не доходят
-
AJAX-запрос: контроллер, свой файл и ответ в JSON - приём своей формы
-
Отправка формы через AJAX: проверка полей, защита, ответ с ошибками - своя форма без модуля веб-форм
-
Заявки с сайта: хранение, дубли, передача в CRM - что происходит с заявкой дальше
-
Заявка с формы не сохранилась: разбор причин - если результата нет в списке
-
Комментарии и отзывы к контенту: форум как движок, модерация - обратная связь под самим контентом
-
Настройка веб-формы: вопросы, статусы результатов, права - устройство самой формы и её результатов
-
Письмо с заявкой приходит пустым: разбор причин - разбор письма без значений полей
-
Ограничения веб-формы и правка анкеты - когда от человека нужна одна анкета
-
Форма добавления элемента с витрины: свойства, модерация - когда результат нужен элементом инфоблока