Bitrix main.feedback добавление полей телефон и согласие на обработку персональных данных

В коробке битрикса есть компонент main.feedback, который выводит форму обратной связи. Но в этом компоненте не хватает как минимум двух полей - это "телефон" и "согласие пользователя на обработку персональных данных". Приступим к их созданию!

Для начала скопируем текущий компонент в своё пространство имён (папка custom), которое создадим в папке "/local/components/" или "/bitrix/components/". Копировать компонент в своё пространство имён нужно для того, чтобы при установке обновлений наши правки не удалились.
Мы будем работать с папкой "local", поэтому комируем полностью содержимое папки "/bitrix/components/bitrix/main.feedback/" в "/local/components/custom/main.feedback/".

Первым делом в файле "/local/components/custom/main.feedback/.description.php" заменим путь отображения компонента в визуальном редакторе на наш. Для этого в ключе "ID" заменим значение "utility" на наше, например "custom".

<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();

$arComponentDescription = array(
  "NAME" => GetMessage("MAIN_FEEDBACK_COMPONENT_NAME"),
  "DESCRIPTION" => GetMessage("MAIN_FEEDBACK_COMPONENT_DESCR"),
  "ICON" => "/images/feedback.gif",
  "PATH" => array(
    "ID" => "custom", //тут заменили "utility" на "custom"
  ),
);
?>

Для отображения компонента перейдем на нашу тестовую страницу "/test2.php" (если у вас её нет, то вы её можете создать сами, нажав на "Создать страницу" в верхней панели). Далее нажимаем на "Изменить страницу". Откроется окно, в котором в правом выпадающем меню "Компоненты" нужно нажать на "Обновить". После этого появится наше "custom", раскрыв которое можно будет увидеть компонент "Форма обратной связи".

Хватаем компонент левой кнопкой мыщи и перетаскиваем влево. Всплывёт окно с настройками компонента. На вкладке "Основные параметры" есть параметр "Обязательные поля для заполнения", в которых не хватает наших полей.

Чтобы добавить поля в параметры компонента, нужно в файле "/local/components/custom/main.feedback/.parameters.php" в ключ "REQUIRED_FIELDS" дописать 2 значения, например, "PHONE" => GetMessage("MFP_PHONE"), "AGREEMENT" => GetMessage("MFP_AGREEMENT"). Содержимое файла:

<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

$site = ($_REQUEST["site"] <> ''? $_REQUEST["site"] : ($_REQUEST["src_site"] <> ''? $_REQUEST["src_site"] : false));
$arFilter = Array("TYPE_ID" => "FEEDBACK_FORM", "ACTIVE" => "Y");
if($site !== false)
  $arFilter["LID"] = $site;

$arEvent = Array();
$dbType = CEventMessage::GetList("id", "desc", $arFilter);
while($arType = $dbType->GetNext())
  $arEvent[$arType["ID"]] = "[".$arType["ID"]."] ".$arType["SUBJECT"];

$arComponentParameters = array(
  "PARAMETERS" => array(
    "USE_CAPTCHA" => Array(
      "NAME" => GetMessage("MFP_CAPTCHA"), 
      "TYPE" => "CHECKBOX",
      "DEFAULT" => "Y", 
      "PARENT" => "BASE",
    ),
    "OK_TEXT" => Array(
      "NAME" => GetMessage("MFP_OK_MESSAGE"), 
      "TYPE" => "STRING",
      "DEFAULT" => GetMessage("MFP_OK_TEXT"), 
      "PARENT" => "BASE",
    ),
    "EMAIL_TO" => Array(
      "NAME" => GetMessage("MFP_EMAIL_TO"), 
      "TYPE" => "STRING",
      "DEFAULT" => htmlspecialcharsbx(COption::GetOptionString("main", "email_from")), 
      "PARENT" => "BASE",
    ),
    "REQUIRED_FIELDS" => Array(
      "NAME" => GetMessage("MFP_REQUIRED_FIELDS"), 
      "TYPE"=>"LIST", 
      "MULTIPLE"=>"Y", 
      "VALUES" => Array("NONE" => GetMessage("MFP_ALL_REQ"), "NAME" => GetMessage("MFP_NAME"), "EMAIL" => "E-mail", "MESSAGE" => GetMessage("MFP_MESSAGE"),
        "PHONE" => GetMessage("MFP_PHONE"), "AGREEMENT" => GetMessage("MFP_AGREEMENT")), //тут добавили 2 наших поля
      "DEFAULT"=>"", 
      "COLS"=>25, 
      "PARENT" => "BASE",
    ),
    "EVENT_MESSAGE_ID" => Array(
      "NAME" => GetMessage("MFP_EMAIL_TEMPLATES"), 
      "TYPE"=>"LIST", 
      "VALUES" => $arEvent,
      "DEFAULT"=>"", 
      "MULTIPLE"=>"Y", 
      "COLS"=>25, 
      "PARENT" => "BASE",
    ),
  )
);
?>

Не забываем вынести в ленговые файлы фразы с названием полей. То есть в файлы "/local/components/custom/main.feedback/lang/ru/.parameters.php" и "/local/components/custom/main.feedback/lang/en/.parameters.php" добавляем 2 строки для каждого языка:

$MESS ["MFP_PHONE"] = "Телефон";
$MESS ["MFP_AGREEMENT"] = "Согласие на обработку данных";

Теперь, если переоткрыть окно с параметрами компонента, можно увидеть наши 2 поля. Выбираем их и жмём на "Сохранить".

Осталось добавить вывод полей в шаблон компонента и сделать их обработку.
Так как мы в параметрах компонента выбрали шаблон по умолчанию (.default), то открываем файл "/local/components/custom/main.feedback/templates/.default/template.php" и добавляем текстовое поле для телефона (после поля Email) и чекбокс для согласия обработки данных (после капчи).

<!--этот кусок для телефона-->
<div class="mf-name">
  <div class="mf-text">
    <?=GetMessage("MFT_PHONE")?><?if(empty($arParams["REQUIRED_FIELDS"]) || in_array("PHONE", $arParams["REQUIRED_FIELDS"])):?><span class="mf-req">*</span><?endif?>
  </div>
  <input type="text" name="user_phone" value="<?=$arResult["AUTHOR_PHONE"]?>">
</div>

<!--этот кусок для согласия-->
<div class="mf-message">
  <label><input type="checkbox" value="y" name="agreement"> <?=GetMessage("MFT_AGREEMENT")?></label>
</div>

Вносим в ленговые файлы "/local/components/custom/main.feedback/templates/.default/lang/ru/template.php" и "/local/components/custom/main.feedback/templates/.default/lang/en/template.php" фразы:

$MESS ["MFT_PHONE"] = "Телефон";
$MESS ["MFT_AGREEMENT"] = "даю согласие на обработку персональных данных";

Если открыть тестовую страницу, то увидим наши поля.

Чтобы получить значения созданных нами полей, нужно внести правки в файл "/local/components/custom/main.feedback/component.php", в котором написана логика работы формы. Телефон будем проверять на 11 цифр в строке (более сложную логику на проверку телефона вы можете придумать сами), а чекбокс на значение "y", которое будет проставляться при клике на него. Так же добавляем в массив, который передаётся в письмо, ключ "AUTHOR_PHONE", в который заполняем то, что введет пользователь. Полное содержимое файла ниже:

<?php
if(!defined("B_PROLOG_INCLUDED")||B_PROLOG_INCLUDED!==true)die();

/**
 * Bitrix vars
 *
 * @var array $arParams
 * @var array $arResult
 * @var CBitrixComponent $this
 * @global CMain $APPLICATION
 * @global CUser $USER
 */

$arResult["PARAMS_HASH"] = md5(serialize($arParams).$this->GetTemplateName());

$arParams["USE_CAPTCHA"] = (($arParams["USE_CAPTCHA"] != "N" && !$USER->IsAuthorized()) ? "Y" : "N");
$arParams["EVENT_NAME"] = trim($arParams["EVENT_NAME"]);
if($arParams["EVENT_NAME"] == '')
	$arParams["EVENT_NAME"] = "FEEDBACK_FORM";
$arParams["EMAIL_TO"] = trim($arParams["EMAIL_TO"]);
if($arParams["EMAIL_TO"] == '')
	$arParams["EMAIL_TO"] = COption::GetOptionString("main", "email_from");
$arParams["OK_TEXT"] = trim($arParams["OK_TEXT"]);
if($arParams["OK_TEXT"] == '')
	$arParams["OK_TEXT"] = GetMessage("MF_OK_MESSAGE");

if($_SERVER["REQUEST_METHOD"] == "POST" && $_POST["submit"] <> '' && (!isset($_POST["PARAMS_HASH"]) || $arResult["PARAMS_HASH"] === $_POST["PARAMS_HASH"]))
{
	$arResult["ERROR_MESSAGE"] = array();
	if(check_bitrix_sessid())
	{
		if(empty($arParams["REQUIRED_FIELDS"]) || !in_array("NONE", $arParams["REQUIRED_FIELDS"]))
		{
			if((empty($arParams["REQUIRED_FIELDS"]) || in_array("NAME", $arParams["REQUIRED_FIELDS"])) && mb_strlen($_POST["user_name"]) <= 1)
				$arResult["ERROR_MESSAGE"][] = GetMessage("MF_REQ_NAME");
			if((empty($arParams["REQUIRED_FIELDS"]) || in_array("EMAIL", $arParams["REQUIRED_FIELDS"])) && mb_strlen($_POST["user_email"]) <= 1)
				$arResult["ERROR_MESSAGE"][] = GetMessage("MF_REQ_EMAIL");
			if((empty($arParams["REQUIRED_FIELDS"]) || in_array("MESSAGE", $arParams["REQUIRED_FIELDS"])) && mb_strlen($_POST["MESSAGE"]) <= 3)
				$arResult["ERROR_MESSAGE"][] = GetMessage("MF_REQ_MESSAGE");
			//проверяем телефон. если не подходит под условие то записываем в ошибки
			if((empty($arParams["REQUIRED_FIELDS"]) || in_array("PHONE", $arParams["REQUIRED_FIELDS"])) && (mb_strlen(preg_replace("/[^0-9]/", "", $_POST["user_phone"])) !== 11))
				$arResult["ERROR_MESSAGE"][] = GetMessage("MF_REQ_PHONE");
			//проверяем согласие. если не подходит под условие то записываем в ошибки
			if((empty($arParams["REQUIRED_FIELDS"]) || in_array("AGREEMENT", $arParams["REQUIRED_FIELDS"])) && ($_POST["agreement"] !== "y"))
				$arResult["ERROR_MESSAGE"][] = GetMessage("MF_REQ_AGREEMENT");
			
		}
		if(mb_strlen($_POST["user_email"]) > 1 && !check_email($_POST["user_email"]))
			$arResult["ERROR_MESSAGE"][] = GetMessage("MF_EMAIL_NOT_VALID");
		if($arParams["USE_CAPTCHA"] == "Y")
		{
			$captcha_code = $_POST["captcha_sid"];
			$captcha_word = $_POST["captcha_word"];
			$cpt = new CCaptcha();
			$captchaPass = COption::GetOptionString("main", "captcha_password", "");
			if ($captcha_word <> '' && $captcha_code <> '')
			{
				if (!$cpt->CheckCodeCrypt($captcha_word, $captcha_code, $captchaPass))
					$arResult["ERROR_MESSAGE"][] = GetMessage("MF_CAPTCHA_WRONG");
			}
			else
				$arResult["ERROR_MESSAGE"][] = GetMessage("MF_CAPTHCA_EMPTY");

		}
		if(empty($arResult["ERROR_MESSAGE"]))
		{
			$arFields = Array(
				"AUTHOR" => $_POST["user_name"],
				"AUTHOR_EMAIL" => $_POST["user_email"],
				"AUTHOR_PHONE" => $_POST["user_phone"],//передаем телефон в почтовый шаблон
				"EMAIL_TO" => $arParams["EMAIL_TO"],
				"TEXT" => $_POST["MESSAGE"],
			);
			if(!empty($arParams["EVENT_MESSAGE_ID"]))
			{
				foreach($arParams["EVENT_MESSAGE_ID"] as $v)
					if(intval($v) > 0)
						CEvent::Send($arParams["EVENT_NAME"], SITE_ID, $arFields, "N", intval($v));
			}
			else
				CEvent::Send($arParams["EVENT_NAME"], SITE_ID, $arFields);
			$_SESSION["MF_NAME"] = htmlspecialcharsbx($_POST["user_name"]);
			$_SESSION["MF_EMAIL"] = htmlspecialcharsbx($_POST["user_email"]);
			$event = new \Bitrix\Main\Event('main', 'onFeedbackFormSubmit', $arFields);
			$event->send();
			LocalRedirect($APPLICATION->GetCurPageParam("success=".$arResult["PARAMS_HASH"], Array("success")));
		}

		$arResult["MESSAGE"] = htmlspecialcharsbx($_POST["MESSAGE"]);
		$arResult["AUTHOR_NAME"] = htmlspecialcharsbx($_POST["user_name"]);
		$arResult["AUTHOR_EMAIL"] = htmlspecialcharsbx($_POST["user_email"]);
		$arResult["AUTHOR_PHONE"] = htmlspecialcharsbx($_POST["user_phone"]);
	}
	else
		$arResult["ERROR_MESSAGE"][] = GetMessage("MF_SESS_EXP");
}
elseif($_REQUEST["success"] == $arResult["PARAMS_HASH"])
{
	$arResult["OK_MESSAGE"] = $arParams["OK_TEXT"];
}

if(empty($arResult["ERROR_MESSAGE"]))
{
	if($USER->IsAuthorized())
	{
		$arResult["AUTHOR_NAME"] = $USER->GetFormattedName(false);
		$arResult["AUTHOR_EMAIL"] = htmlspecialcharsbx($USER->GetEmail());
	}
	else
	{
		if($_SESSION["MF_NAME"] <> '')
			$arResult["AUTHOR_NAME"] = htmlspecialcharsbx($_SESSION["MF_NAME"]);
		if($_SESSION["MF_EMAIL"] <> '')
			$arResult["AUTHOR_EMAIL"] = htmlspecialcharsbx($_SESSION["MF_EMAIL"]);
	}
}

if($arParams["USE_CAPTCHA"] == "Y")
	$arResult["capCode"] =  htmlspecialcharsbx($APPLICATION->CaptchaGetCode());

$this->IncludeComponentTemplate();

Выносим в ленговые файлы "/local/components/custom/main.feedback/lang/ru/component.php" и "/local/components/custom/main.feedback/lang/en/component.php" фразы

$MESS ["MF_REQ_PHONE"] = "Телефон не заполнен или не верного формата (необходимо 11 цифр)";
$MESS ["MF_REQ_AGREEMENT"] = "Необходимо дать согласие на обработку персоальных данных";

Готово! Напоследок правим шаблон в админке сайта. Для этого переходим на вкладку "Настройки", раскрываем "Настройки продукта", раскрываем "Почтовые и СМС события", жмем на "Почтовые шаблоны". Находим по ID нащ шаблон (в настройках компонента мы выбирали 7), нажимаем на него, и вносим макрос с телефоном в текст сообщения.

Теперь, если попробовать отправить сообщение не заполнив телефон или согласие, выведутся ошибки, а в случае успеха придет письмо на почту.

Если вам нужен готовый архив с файлами, вы можете написать нам better@devroute.ru