Большая книга рецептов Битрикс – шинкуем компоненты
«Ларису Ивановну хачу!»
Мимино
Введение
Хороший уровень разработки на Битрикс подразумевает, что пользователь сайта получает в свои руки максимально удобный инструмент управления. Визуальные компоненты, доступные для пользователя в визуальном редакторе, являются важной частью этого инструмента, а поскольку стандартный набор компонентов Битрикс далеко не всегда является достаточным, то приходит время, когда разработчик должен научиться добавлять свои.
Что делать-то будем?
В качестве примера для создания компонента мы воспользуемся нехитрым кодом веб-формы, которая может использоваться с редакцией Старт. Разумеется, это и рядом не лежит с функциональностью модуля веб-форм, который входит в поставку редакций Стандарт и выше, но в нашем случае это как раз та простая и понятная иллюстрация, которая нужна для демонстрации.
Первым делом – самолеты
На одном из сайтов для веб-формы мы использовали страницу с кодом, взятым на каком-то сайте с примерами скриптов. Код создает веб-форму и отправляет заполненные пользователем поля в качестве почтового сообщения на заданный адрес.
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetPageProperty("NOT_SHOW_NAV_CHAIN",
"Y");
$APPLICATION->SetTitle("Обратная
связь");
?>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide code from non-js
browsers
function validate()
{
formObj = document.contact;
if ((formObj.name.value == "")
||
(formObj.email.value ==
"") ||
(formObj.subject.value ==
"") ||
(formObj.msg.value == ""))
{
alert("Вы не заполнили
некоторые обязательные поля!");
return false;
}
else {
alert('Спасибо за ваше
сообщение! Мы постараемся ответить на него как можно быстрее!');
return true;
}
}
// end hiding -->
</SCRIPT>
<?
if ($_SERVER['REQUEST_METHOD'] ==
"POST"):
$name = $_POST[name];
$email = $_POST[email];
$company = $_POST[company];
$phone = $_POST[phone];
$msg = $_POST[msg];
$subject = $_POST[subject];
$redirecturl =
$_POST[$redirecturl];
// $msg2 is set in config.inc
which formats the body of the message
mail("info@xxxx.ru",
"[Форма обратной связи] - $subject", "$msg",
"From: $email \nReply-To: $email");
if ($redirecturl != "")
{
header("Request-URI:
$redirecturl");
header("Content-Location:
$redirecturl");
header("Location:
$redirecturl");
} else {
echo "<br><center>Спасибо
за ваше сообщение! Мы постараемся ответить на него как можно
быстрее!</center><br>";
}
else:
?>
<TABLE BORDER=0 cellpadding=5
cellspacing=0>
<TR>
<TD>
<TABLE BORDER=0 cellpadding=2
cellspacing=0>
<form action="<?
echo $APPLICATION->GetCurPage();?>" method="post"
name="contact" onSubmit="return validate()">
<input type=hidden
value='<? echo $APPLICATION->GetCurDir();?>'
name="redirecturl"><BR>
<TR>
<TD>
<BR>
<DIV>
1. ФИО *<BR>
<input type=text
value='ваше имя' size=50 maxlength=50 name=name class='txtfield'><BR>
2. Email*<BR>
<input type='text'
value='you@yourname.ru' size='50' maxlength='60' name='email'><BR>
3. Огранизация<BR>
<input type='text'
value='' size='50' maxlength='50' name='company'><BR>
4. Телефон<BR>
<input type='text'
value='(000) 000-0000' size='50' maxlength='32' name='phone'><BR>
5. Тема сообщения *<BR>
<input type='text'
value='' size='50' maxlength='60' name='subject'><BR>
6. Текст сообщения
*<BR>
<textarea name='msg'
rows='7' cols='50'></textarea><BR>
</DIV>
<input type='submit'
value='submit'>* Обязательные поля<BR>
</TD>
</tR>
</FORM>
</tABLE>
</TD>
</TR>
</tABLE>
<?
endif;
?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
Все бы ничего, но вот при попытках редактировать эту страницу в визуальном редакторе пользователь получал кашу, а сохранение страницы ее окончательно портило. Не говоря уже о том, что для внесения изменений в параметры формы надо было в этой самой форме копаться, чего пользователь делать не должен.
Что такое компонент?
Выделить необходимый php-код в отдельный файл для того, чтобы использовать его потом в виде вызываемого файла дело простое. Но отличие компонента состоит в том, что помимо самого файла существует файл описания, который опознается ядром Битрикс, в результате чего пользователь видит в визуальном редакторе новый «кирпичик» с изображением и названием компонента и может настраивать его свойства.
Иными словами, компонент в терминах Битрикс – это выделенный в отдельный файл php-код с законченной функциональностью, файл регистрации компонента в системе и описания его параметров, а также файлы локализации.
Шаг первый. Регистрация компонента.
Выделим код веб-формы в отдельный файл, который и станет нашим компонентом – mail_form.php:
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide code from non-js
browsers
function validate()
{
formObj = document.contact;
if ((formObj.name.value == "")
||
(formObj.email.value ==
"") ||
(formObj.subject.value ==
"") ||
(formObj.msg.value == ""))
{
alert("Вы не заполнили
некоторые обязательные поля!");
return false;
}
else {
alert('Спасибо за ваше
сообщение! Мы постараемся ответить на него как можно быстрее!');
return true;
}
}
// end hiding -->
</SCRIPT>
<?
if ($_SERVER['REQUEST_METHOD'] ==
"POST"):
$name = $_POST[name];
$email = $_POST[email];
$company = $_POST[company];
$phone = $_POST[phone];
$msg = $_POST[msg];
$subject = $_POST[subject];
$redirecturl =
$_POST[$redirecturl];
// $msg2 is set in config.inc
which formats the body of the message
mail("info@xxxx.ru",
"[Форма обратной связи] - $subject", "$msg",
"From: $email \nReply-To: $email");
if ($redirecturl != "")
{
header("Request-URI:
$redirecturl");
header("Content-Location:
$redirecturl");
header("Location:
$redirecturl");
} else {
echo "<br><center>Спасибо
за ваше сообщение! Мы постараемся ответить на него как можно
быстрее!</center><br>";
}
else:
?>
<TABLE BORDER=0 cellpadding=5
cellspacing=0>
<TR>
<TD>
<TABLE BORDER=0 cellpadding=2
cellspacing=0>
<form action="<?
echo $APPLICATION->GetCurPage();?>" method="post"
name="contact" onSubmit="return validate()">
<input type=hidden
value='<? echo $APPLICATION->GetCurDir();?>'
name="redirecturl"><BR>
<TR>
<TD>
<BR>
<DIV>
1. ФИО *<BR>
<input type=text
value='ваше имя' size=50 maxlength=50 name=name class='txtfield'><BR>
2. Email*<BR>
<input type='text'
value='you@yourname.ru' size='50' maxlength='60' name='email'><BR>
3. Огранизация<BR>
<input type='text'
value='' size='50' maxlength='50' name='company'><BR>
4. Телефон<BR>
<input type='text'
value='(000) 000-0000' size='50' maxlength='32' name='phone'><BR>
5. Тема сообщения *<BR>
<input type='text'
value='' size='50' maxlength='60' name='subject'><BR>
6. Текст сообщения
*<BR>
<textarea name='msg'
rows='7' cols='50'></textarea><BR>
</DIV>
<input type='submit'
value='submit'>* Обязательные поля<BR>
</TD>
</tR>
</FORM>
</tABLE>
</TD>
</TR>
</tABLE>
<?
endif;
?>
Поскольку добавить новый компонент в ядро системы мы не сможем, мы должны разместить его в шаблоне по умолчанию (/bitrix/templates/.default). Создадим подкаталог mail_form в шаблоне по умолчанию и поместим туда файл mail_form.php. Теперь необходимо создать файл описания «.description.php», который также необходимо разместить в каталоге «/bitrix/templates/.default/mail_form/». В простейшем случае он будет выглядеть следующим образом:
<?
$sSectionName = «Почтовая форма»;
/**************************************************************************
Component for displaying Mail-form
page
***************************************************************************/
$arTemplateDescription["mail_form.php"]
= array(
"PARENT" =>
".separator",
"NAME" => «Почтовая
форма»,
"DESCRIPTION" => «Форма
обратной связи»,
"ICON" =>
"/bitrix/templates/.default/mail_form/images/form_fill.gif",
"PARAMS" => array(
"REDIRECT_PAGE" =>
array(
"NAME" =>
«Перенаправить на страницу»),
"TYPE" => "STRING",
"DEFAULT" => ""
),
"MAIL_TO" => array(
"NAME" => «Отправить
письмо по адресу»,
"TYPE" => "STRING",
"DEFAULT" =>
"name@domain.com"
),
)
);
?>
Теперь нам достаточно открыть визуальный редактор Битрикс, чтобы обнаружить в выпадающем списке наборов компонентов новую запись «Почтовая форма». В наборе будет содержаться только один компонент «Почтовая форма», который, при размещении на странице, позволит пользователю задать два строковых параметра – страницу перенаправления и адрес электронной почты для получения результатов.
Переменная $sSectionName формирует название для списка наборов компонентов в выпадающем списке. Каждый элемент массива $arTemplateDescription формирует описание очередного компонента. Параметр "PARENT" позволяет группировать несколько компонентов в одном наборе в группу. Если в качестве значения указывается ".separator", то компонент попадает корневую группу текущего набора. Поля "NAME" и "DESCRIPTION" формируют текстовые названия и описания компонента в визуальном редакторе. Поле "ICON" указывает Битрикс изображение, которое будет ассоциировано с компонентом. Параметр-массив "PARAMS" описывает параметры компонента и связывает каждый из них с визуальным элементом редактирования параметра. В нашем случае мы использовали два строковых параметра, для редактирования которых будут использованы простые поля редактирования. Примеры более сложных визуальных элементом вы можете «подсмотреть» в стандартных компонентах (в частности, в файле /bitrix/modules/iblock/install/templates/iblock/catalog/.description.php)
Шаг второй. Использование параметров в коде компонента.
Как видно из описания компонента, пользователь может указать два параметра формы. Добавим в начало кода компонента следующие строки в качестве комментария:
<?
/*************************************************************************
Инициализируем начальные параметры
компонента
*************************************************************************/
/*
$REDIRECT_PAGE =
$arParams["REDIRECT_PAGE"]; // путь к странице
результатов
$MAIL_TO =
$arParams["MAIL_TO"]; // адрес для получения
значений формы
*/
?>
а в основной код вносим ряд изменений.
В частности, строку
mail("info@sarunion.ru",
"[Форма обратной связи] - $subject", "$msg",
"From: $email \nReply-To: $email");
заменяем на
mail($MAIL_TO, "[Форма обратной
связи] - $subject", "$msg", "From: $email
\nReply-To: $email");
а код
<input type=hidden
value='<? echo $APPLICATION->GetCurDir();?>'
name="redirecturl">
заменяем на
<input type=hidden
value='<? echo $REDIRECT_PAGE; ?>' name='redirecturl'>
Теперь при изменении пользователем значений свойств компонента в визуальном редакторе, поведение компонента будет меняться.
Шаг третий. Локализация.
Самое последнее, но очень важное, что необходимо сделать – это подготовить файлы с текстовыми константами для компонента и файла регистрации, а также внести изменения в код обоих файлов для использования этих константы. Названия файлов констант совпадают с названиями основных файлов. В частности, для русского языка необходимо создать следующие файлы:
/bitrix/templates/.default/lang/ru/mail_form/mail_form.php
/bitrix/templates/.default/lang/ru/mail_form/.description.php
Приведем код данных файлов целиком:
mail_form.php
<?
$MESS ['NAME_REQUIRED'] = "Необходимо указать имя";
$MESS ['MESSAGE_REQUIRED'] = "Необходимо написать текст сообщения";
$MESS ['PHONE_OR_MAIL_REQUIRED'] = "Необходимо указать либо телефон, либо email";
$MESS ['MAIL_FORM_FILLED'] = "Заполнена форма обратной связи \n\n\n";
$MESS ['MAIL_FORM_FROM'] = "От кого : ";
$MESS ['MAIL_FORM_COMPANY'] = "Компания: ";
$MESS ['MAIL_FORM_PHONE'] = "Телефон : ";
$MESS ['MAIL_FORM_BODY'] = "Текст сообщения:\n\n";
$MESS ['MAIL_ERROR'] = "Сообщение не отправлено";
$MESS ['THANK_YOU'] = "<br><center>Спасибо за ваше сообщение! Мы постараемся ответить на него как можно быстрее!</center><br>";
$MESS ['NAME_FIELD'] = "Имя*";
$MESS ['PHONE_FIELD'] = "Телефон*";
$MESS ['EMAIL_FIELD'] = "Email*";
$MESS ['COMPANY_FIELD'] = "Компания";
$MESS ['MESSAGE_FIELD'] = "Текст сообщения*";
$MESS ['MESSAGE_SUBMIT'] = "Отправить";
$MESS ['MAIL_FORM_COMMENT'] = "Поля, отмеченные знаком *, являются обязательными для заполнения";
?>
.description.php
<?
$MESS ['MAILFORM_SECTION_NAME'] = "Почтовая форма";
$MESS ['MAIL_FORM_PAGE_NAME'] = "Обратная связь";
$MESS ['MAIL_FORM_PAGE_DESCRIPTION'] = "Почтовая форма обратной связи";
$MESS ['REDIRECT_PAGE_DESC'] = "Перенаправить на страницу";
$MESS ['MAIL_TO_DESC'] = "Отправить на адрес";
?>
Подключение файла локализации делается при помощи функции IncludeTemplateLangFile(__FILE__);
Добавим вызов этой функции и использование констант в «/bitrix/templates/.default/mail_form/.description.php»:
<?
IncludeTemplateLangFile(__FILE__);
$sSectionName = GetMessage("MAILFORM_SECTION_NAME");
/**************************************************************************
Component for displaying Mail-form page
***************************************************************************/
$arTemplateDescription["mail_form.php"] = array(
"PARENT" => ".separator",
"NAME" => GetMessage("MAIL_FORM_PAGE_NAME"),
"DESCRIPTION" => GetMessage("MAIL_FORM_PAGE_DESCRIPTION"),
"ICON" => "/bitrix/templates/.default/mail_form/images/form_fill.gif",
"PARAMS" => array(
"REDIRECT_PAGE" => array(
"NAME" => GetMessage("REDIRECT_PAGE_DESC"),
"TYPE" => "STRING",
"DEFAULT" => ""
),
"MAIL_TO" => array(
"NAME" => GetMessage("MAIL_TO_DESC"),
"TYPE" => "STRING",
"DEFAULT" => "name@domain.com"
),
)
);
?>
Аналогичные изменения необходимо внести и в код компонента:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?
IncludeTemplateLangFile(__FILE__);
/*************************************************************************
Инициализируем начальные параметры компонента
*************************************************************************/
/*
$REDIRECT_PAGE = $arParams["REDIRECT_PAGE"]; // путь к странице результатов
$MAIL_TO = $arParams["MAIL_TO"]; // адрес для получения значений формы
*/
?>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide code from non-js browsers
function validate()
{
formObj = document.contact;
if (formObj.name.value == "") {
alert("<? echo GetMessage("NAME_REQUIRED"); ?>");
}
else
{
if (formObj.msg.value == "") {
alert("<? echo GetMessage("MESSAGE_REQUIRED"); ?>");
}
else {
if ((formObj.phone.value = "") || (formObj.email.value == "")) {
alert("<? echo GetMessage("PHONE_OR_MAIL_REQUIRED"); ?>");
}
else {
return true;
}
}
}
return false;
}
// end hiding -->
</SCRIPT>
<?
if ($_SERVER['REQUEST_METHOD'] == "POST"):
$name = $_POST[name];
$email = $_POST[email];
$company = $_POST[company];
$phone = $_POST[phone];
$msg = $_POST[msg];
$redirecturl = $_POST[$redirecturl];
$message_body = GetMessage("MAIL_FORM_FILLED")
.GetMessage("MAIL_FORM_FROM").$name."\n"
.GetMessage("MAIL_FORM_COMPANY").$company."\n"
.GetMessage("MAIL_FORM_PHONE").$phone."\n\n\n"
.$msg;
echo GetMessage("MAIL_FORM_BODY").$message_body;
$rsSites = CSite::GetByID(SITE_ID);
$arSite = $rsSites->Fetch();
$res = mail($MAIL_TO, $arSite["NAME"].GetMessage("MAIL_FORM_FILLED"), "$message_body", "From: $email \nReply-To: $email");
if (!$res) echo GetMessage("MAIL_ERROR");
if ($redirecturl != "") {
header("Request-URI: $redirecturl");
header("Content-Location: $redirecturl");
header("Location: $redirecturl");
} else {
echo GetMessage("THANK_YOU");
}
else:
?>
<TABLE BORDER=0 cellpadding=0 cellspacing=0>
<TR>
<TD valign="top">
<TABLE BORDER=0 cellpadding=0 cellspacing=0>
<form action="<?$APPLICATION->GetCurUri();?>" method="post" name="contact" onSubmit="return validate()">
<input type=hidden value='<? echo $REDIRECT_PAGE; ?>' name='redirecturl'>
<TR>
<TD valign="top">
<table BORDER=0 cellpadding=0 cellspacing=0 width="495">
<tr>
<td valign="top" width="165" class="feed">
<? echo GetMessage("NAME_FIELD"); ?>:</td>
<td width="330">
<input type=text value='' size=50 maxlength=30 name=name class='inputfield2'>
</td>
</tr>
<tr>
<td valign="top" class="feed" style="padding-top:10px;">
<? echo GetMessage("PHONE_FIELD"); ?>:
</td>
<td valign="top" width="330" style="padding-top:10px;">
<input type='text' value='' size='50' maxlength='30' name='phone' class='inputfield2'>
</td>
</tr>
<tr>
<td valign="top" class="feed" style="padding-top:10px;">
<? echo GetMessage("EMAIL_FIELD"); ?>:
</td>
<td valign="top" width="330" style="padding-top:10px;">
<input type='text' value='' size='50' maxlength='30' name='email' class='inputfield2'>
</td>
</tr>
<tr>
<td valign="top" class="feed" style="padding-top:10px;">
<? echo GetMessage("COMPANY_FIELD"); ?>:
</td>
<td valign="top" width="330" style="padding-top:10px;">
<input type='text' value='' size='50' maxlength='30' name='company' class='inputfield2'>
</td>
</tr>
<tr>
<td valign="top" width="165" class="feed" style="padding-top:10px;">
<? echo GetMessage("MESSAGE_FIELD"); ?>:
<input type='submit' value='<? echo GetMessage("MESSAGE_SUBMIT"); ?>' class='button' border='' width='101' height='22' style="margin-top:70px;margin-left:30px;"></td>
<td valign="top" width="330" style="padding-top:10px;">
<textarea name='msg' rows='7' cols='39'></textarea></td>
</tr>
<tr>
<td valign="top" width="165" class="feed" style="padding-top:10px;"></td>
<td valign="top" width="330" style="padding-top:10px;"><FONT class="smalltext"><? echo GetMessage("MAIL_FORM_COMMENT"); ?></FONT></td>
</tr>
</table>
</TD>
</TR>
</FORM>
</TABLE>
</TD>
</TR>
</TABLE>
<?
endif;
?>
Заключение
Мы выделили существующий php-код в качестве файла отдельного от публичной части сайта, зарегистрировали его в виде компонента в Битрикс, добавили локализацию. Аналогичным образом вы сможете создавать свои компоненты для Битрикс в рамках своих проектов.