воскресенье, 29 июля 2018 г.

Кастомизация bitrix:form.result.new — кое-что изменилось.


Предупреждение: эта статья создана в процессе разработки сайтов в компании Smart Traffic, в которой в настоящее время я работаю в должности разработчика Битрикс, и напечатана с разрешения руководства компании. Первоначально она была опубликована на нашем сайте.
Smart Traffic — интернет-агентство, предлагающее комплексное обслуживание в сфере интернет-маркетинга. Мы - отличная команда профессионалов, рекомендую обращаться к нам, если Вам необходимо разработать сайт на CMS 1С-Битрикс!

* * * 

Формы битрикс используются довольно широко, но тем не менее стандартный шаблон формы использует табличную верстку, что не всегда удобно, когда требуется сделать оригинальные красивые формы в стиле сайта с блочной или какой-то особой нестандартной версткой. Подогнать стили под таблицу из стандартной верстки для таких форм иногда сложновато, да и не нужно, нужно просто кастомизировать дефолтовые формы битрикс, полностью изменив разметку шаблона. Некоторые разработчики полностью отказываются от их использования и тратят значительное время, чтобы сделать собственный кастомный компонент, где они делают с шаблоном формы, что им захочется. Ну что же, это тоже возможный способ решения проблем — все зависит от конкретной ситуации. Но и у форм битрикс много достоинств, они известны, не будем их перечислять все, отмечу только то, что больше всего нравится мне лично — готовая админка, где можно задать и настроить поля, просмотреть сохраненные результаты форм, легко и просто подключить почтовый шаблон, который уже будет срабатывать при заполнении и получении формы. Поэтому кастомизировать формы битрикс можно и нужно, когда это для вас удобно.

Чаще всего, например, используется кастомизация компонента bitrix:form.result.new, находящегося в составе комплексного компонента bitrix.form. На первый взгляд, ничего необычного — кастомизируем также точно, как и любой компонент. Однако, не все так гладко, практика показывает, что кое-что работает по-другому. Где это прописано в ядре Битрикса — а бог его знает. Да и нужно ли в этом разбираться? Ведь все равно дорабатывать ядро мы не будем, помня о том, что все это затрется при первом же обновлении. Мы будем кастомизировать bitrix:form.result.new методом, похожим на стандартную кастомизацию, но все же отличающимся в некоторых деталях — мы учтем то, что не сработает, и обойдем эти проблемы.

Во-первых, как подключить собственный шаблон bitrix:form.result.new? И это не тот «собственный шаблон», который мы видим на странице настройки формы http://ваш_сайт.рф/bitrix/admin/form_edit.php?lang=ru&ID=ид_формы на вкладке «шаблон формы», где мы можем отметить опцию «использовать свой шаблон формы». Тут, насколько я понимаю, на самом деле собирается шаблон на основе стандартного табличного же шаблона с помощью специального конструктора — меняется количество и типы полей формы, встроенные в разметку стили, затем шаблон сохраняется, суда по всему, в базу данных, а не в файловую структуру сайта. И потом подключается оттуда. Как быть, если нам это не подходит — у нас уже есть сделанная верстальщиком блочная разметка формы, например?

Смотрим внутрь компонента bitrix:form. Видим, что как и в обычном комплексном компоненте, вложенный компоненет bitrix: form.result.new, например, подключается в файле new.php, который имеет такой вид:
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$APPLICATION->IncludeComponent("bitrix:form.result.new", "", $arParams, $component);
?>
Казалось бы, все ок. Создадим собственный шаблон bitrix:form.result.new и подключим его в этом вызове, например, так:

$APPLICATION->IncludeComponent("bitrix:form.result.new", "moy_shablon", $arParams, $component);

Но нет! Не подключает,ся собака страшная! Возможно, это как-то связано с версионностью Битрикса на сайте, и в более новых версиях это возможно. Но у меня в данном конкретном случае использовалась версия 16.5.13 и обновлять ее было не желательно. Как ни бился, собственный шаблон через этот вызов подключить не удалось, всегда и неизменно подключается только дефолтовый шаблон, который лежит по адресу ваш_сайт.рф/bitrix/templates/ваш_шаблон_сайта/components/bitrix/form/ваш_шаблон_комплексного_компонента_форм/bitrix/form.result.new/.default ! Даже если в настройках комплексного компонента bitrix:form убирать опцию "IGNORE_CUSTOM_TEMPLATE" => "Y" — все равно не работает, по крайней мере на этом конкретном сайте! Очевидно, что эта настройка, предназначена, чтобы блокировать подключение тех кастомных шаблонов, которые сделаны в конструкторе в админке и хранятся в базе данных.

Тут надо сделать лирическое отступление. До этого момента я описал путь, который я и сам использовал на других сайтах. На этом же конкретном сайте разработчик кастомизировал формы до меня, но сделал он это аналогично тому способу, который я сейчас описываю. У меня была задача исправить накладку, которая появится чуть позже. Поэтому продложим.

Итак, чтобы обойти тот момент, что кастомный шаблон bitrx:form.result.new не желает подключаться в вызове файла new.php делаем так — кастомизируем сам шаблон ваш_сайт.рф/bitrix/templates/ваш_шаблон_сайта/components/bitrix/form/ваш_шаблон_комплексного_компонента_форм/bitrix/form.result.new/.default . А на странице настроек шаблона оставим отмеченной опцию «использовать стандартный шаблон». И после кастомизации обычно все работает. Способ кастомизации достаточно подробно описан в интернете, все детали его обсужать не будем. Остановимся только на том моменте, который вызвал — причем не сразу, а со временем, - ошибку работы формы. А именно — первое, что делается очень часто (хотя и не всегда) в кастомном шаблоне — строка кода <?=$arResult[«FORM_HEADER»] ?>, которая отвечает за показ заголовка формы, подменяется на что-то такое:

<form id="bp1" name="<?=$arResult["WEB_FORM_NAME"]?>" action="<?=POST_FORM_ACTION_URI?>" method="POST" enctype="multipart/form-data" class="contact-form" novalidate="novalidate">
<input type="hidden" name="WEB_FORM_ID" value="<?=$arParams["WEB_FORM_ID"]?>">
<?=bitrix_sessid_post()?>

Последняя строка здесь является обязательной, она формирует скрытое поле для передачи идентификатора сессии в обработчик формы. Если ее опустить, форма может вообще не работать. Подробное описание можно посмотреть здесь и здесь:

https://dev.1c-bitrix.ru/api_help/main/functions/other/bitrix_sessid_post.php

https://dev.1c-bitrix.ru/api_help/main/functions/other/check_bitrix_sessid().php

В данном конкретном случае к тегу form был добавлен id="bp1", который ни для чего другого не служит, кроме как для подключения нужных стилей к самой форме и вложенным в нее элементам разметки. Все остальные строки кода в кастомном шаблоне нас не интересуют в данном случае — они зависят от конкретной реализации разметки шаблона. Итак, разработчик сделал это до того, как сайт попал в мои руки. Сделано было грамотно, и все работало какое-то время, кажется, даже несколько лет. И в один «прекрасный» момент работать перестало. Форма перестала правильно отрабатывать, выбрасывая сообщение, что данные получены, в результаты формы перестало писаться все, что нужно. Ну и понятно, что и почтовый шаблон перестал отрабатывать, потому что форма не пишется вообще. Некоторое время я потратил на то, чтобы 1) проверить все настройки самой формы в админке 2) проверить кастомизированный шаблон bitrix:form.result.new, в котором я не нашел ничего криминального. Затем стал отлаживать форму по частям. Первым делом, перенастроил код — подсунул шаблону .default стандартную табличную форму — и о чудо! Табличная форма отрабатывает нормально! Только вид у нее, естественно, «табличный», то есть никакой вообще. Ну что же, стал я тогда брать значимые куски кода из кастомной формы и подставлять их в стандартный табличный шаблон, ожидая, когда же он помрёт. Повезло практически сразу — подстановка приведенного выше куска, отвечающего за заголовок формы, вместо <?=$arResult[«FORM_HEADER»] ?>, сразу же вызвало ту же самую ошибку — форма перестала отправляться! Попробовал убрать из него из тега form параметр id="bp1" — а вдруг ядро битрикс где-то там внутри себя использует идентификаторы для обработки формы, и мой идентификатор этому мешает? Нет, не помогло. Конечно же, сразу пришло в голову, что что-то изменилось в ядре, что отвечало за обработку форм. И было бы в будущем очень интересно понять — а что же именно. Но — это задача академическая, так сказать. А заказчик сайта ждет, когда же бедные погибшие формы заработают. И ждет чтобы это случилось как можно скорее! Поэтому на этот раз я просто обошел проблему — заменил кастомно прописанный заголовок обратно на стандартный вызов заголовка формы, но для сохранения стилизации заключил его в div с тем же самым id, который до этого был в теге form. Вот как это стало выглядеть:

<div id="bp1">
<?=$arResult["FORM_HEADER"]?>
… собственно код кастомизированной формы …
<?=$arResult["FORM_FOOTER"]?>
</div>

И о чудо! Все заработало, хотя казалось бы это должно было быть одно и тоже, но оказалось, что не одно. Надо сказать, что проблема на этом сайте возникла после одного из обновлений Битрикс. Вот такой вот он Битрикс — странный и загадочный! И не всегда обратно совместимый — особенно если кастомизированный.