Июн
01
2021

Заполнение полей и ответов Вебформ в Битрикс

Покажу как заполнять значения полей и значения вопросов в модуле Webforms в 1C-Bitrix.

Для начала немного теории

В у вебформ есть 2 сущности, в которые мы можем сохранять данные: Вопросы и Поля. Вопросы отображаются в самой форме на странице, их видит пользователь. А поля нужны только для администратора, пользователю они не показываются, заполнить их пользователь соответственно тоже не может.

Значения вопросов в результатах, по-моему, это ответы - буду называть их так. Битрикс сам путается в названиях. В результатах ответы подписаны как Поля, а то, что в настройках вебформы подписано как Поля, в результатах - Дополнительные поля

1 - Вопросы, 2 - Ответы, 3 - поля, 4 - значения полей

Работать будем через события вебформ. Обработчики лучше всего добавлять в файле /local/php_interface/init.php. Так советует сам Битрикс и это очень удобно, когда все доработки по сайту лежат в отдельной папке local.

Если нет файла /local/php_interface/init.php, создайте его и в начало добавьте следующий код.

<?php

if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/init.php')) {
	require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/init.php');
}

Заполнение ответов

Основную работу делает сам модуль: выводит вопросы пользователю и сохраняет ответы. Но нам может потребоваться как-то изменить ответы. Например, из номера телефона убрать все лишние символы.

Чтобы заполнять ответы, нам надо знать тип вопроса и его ID.

ID - 54, тип - text

Получим объект, через который добавляются события:

$eventManager = \Bitrix\Main\EventManager::getInstance();

Нам надо событие на добавление результатов в вебформу:

$eventManager->addEventHandler(
    'form',
    'onBeforeResultAdd',
    'clearPhone'
);

/*
 * Очищаем номер телефона от посторонних символов
 */
function clearPhone($WEB_FORM_ID, &$arFields, &$arrVALUES)
{

}

Напишем логику в нашу функцию. "form_text_54" - это имя поля ответа, которое надо очищать. Имена полей в вебформах строятся по такому шаблону: form_{ТИП}_{ID}, где {ТИП} - тип вопроса, {ID} - ID вопроса.

function clearPhone($WEB_FORM_ID, &$arFields, &$arrVALUES)
{
	// Работаем только с формой №11
	if ($WEB_FORM_ID !== '11') return;

	// Имя нужного поля
	$valueName = 'form_text_54';
	
	// Вырезаем всё, кроме цифр и плюса
	$arrVALUES[$valueName] = preg_replace('#[^0-9\+]#', '', $arrVALUES[$valueName]);
}

Но писать ID в коде - это плохо, так делать не надо. Часто доработки создаются на тестовом сайте и после переносятся на боевой сайт и в процессе переноса ID могут измениться.

Чтобы всё было красиво, добавим функцию получения полей. Так как поля после создания почти не меняются, нет смысла каждый раз получать их из базы - добавим кеширование.

function getWebformQuestions($WEB_FORM_ID)
{
	$cache = \Bitrix\Main\Data\Cache::createInstance();
	
	if ($cache->initCache(999999999, 'webform_values_' . $WEB_FORM_ID))
	{
		$values = $cache->getVars();
	}
	elseif ($cache->startDataCache())
	{
		$sort = null;
		$filtered = false;
		$res = CFormField::GetList($WEB_FORM_ID, 'ALL', $sort, $sort, [], $filtered);
		
		$values = [];
		while ($arValue = $res->fetch())
		{
			$values[] = [
				'ID' => $arValue['ID'],
				'CODE' => $arValue['SID'],
				'TYPE' => $arValue['TITLE_TYPE'],
			];
		}
		
		$cache->endDataCache($values);
	}
	
	return $values;
}

Скорректируем функцию:

function clearPhone($WEB_FORM_ID, &$arFields, &$arrVALUES)
{
	// Работаем только с формой №11
	if ($WEB_FORM_ID !== '11') return;
	
	// Получаем все вопросы формы
	$questions = getWebformQuestions($WEB_FORM_ID);
	
	// Перебираем вопросы
	foreach ($questions as $question) {
		
		// Ищем вопрос с кодом PHONE
		if ($question['CODE'] === 'PHONE') {
			
			// Воссоздаем имя поля с ответом
			$valueName = "form_{$question['TYPE']}_{$question['ID']}";
			break;
		}
	}
	
	// Вырезаем всё, кроме цифр и плюса
	$arrVALUES[$valueName] = preg_replace('#[^0-9\+]#', '', $arrVALUES[$valueName]);
}

Заполнение значений дополнительных полей

С полями всё намного проще, потому что мы сразу можем обращаться по коду. Например, нам надо сохранить страницу, на которой пользователь отправил результат.

Первое, создаем поле с кодом PAGE, типом текст

$eventManager = Main\EventManager::getInstance(); 
$eventManager->addEventHandler(
    'form',
    'onAfterResultAdd',
    'addWebformPage'
);

/*
 * В результаты формы добавляем ссылку на страницу, на которой заполнена форма
 */
function addWebformPage($WEB_FORM_ID, $RESULT_ID)
{
	// Заполняем поле
	CFormResult::SetField($RESULT_ID, 'PAGE', $_SERVER['HTTP_REFERER']);
}

В примере показано как сохранить адрес страницы, на которой заполнена форма в битрикс. $_SERVER['HTTP_REFERER'] - страница, откуда отправлена форма.

Пожалуйста, оцените на сколько вам понравилась статья!
Голосов: 6 Среднее: 5