Блог вопиющего в пустыне
Для тех, кто не имеет желания читать нижеследующую писанину, можете сразу перейти по ССЫЛКЕ и посмотреть как работает сляпанная в итоге форма.
Попытка 1. Сначала попробовал в Административной панели создать свою Форму для получения данных из базы: Сервисы/Веб-формы/Настройка форм/Создать .
Создал страницу, вставил компонент Веб-форма. В Параметры компонента-Источник данных выбрал созданную форму. Сохранил. В текстовые поля ввел исходные данные. Нажал «Показать результаты». Естественно, получил: «Спасибо! Ваша заявка принята!». Полез в шаблон компонента. А там вот такая «хрень»:
form questions
**************************************************************************/?>
<table class="form-table data-table"><thead><tr>
<th colspan="2"> </th></tr></thead>
<tbody>
<?
foreach ($arResult["QUESTIONS"] as $FIELD_SID => $arQuestion)
{
?>
<tr><td>
<? if (is_array($arResult["FORM_ERRORS"]) && array_key_exists($FIELD_SID, $arResult ['FORM_ERRORS'])):?>
<span class="error-fld" title="<?=htmlspecialcharsbx($arResult["FORM_ERRORS"][$FIELD_SID])? >"></span>
<?endif;?>
<?=$arQuestion["CAPTION"]?><? if ($arQuestion["REQUIRED"] == "Y"):?><?=$arResult ["REQUIRED_SIGN"];?>
<?endif;?>
<?=$arQuestion["IS_INPUT_CAPTION_IMAGE"] == "Y" ? "<br/>".$arQuestion["IMAGE"] ["HTML_CODE"] : ""?>
</td>
<td><?=$arQuestion["HTML_CODE"]?></td></tr>
<?
} //endwhile
?>
…здесь Captcha
</tbody><tfoot><tr><th colspan="2">
<input <?=(intval($arResult["F_RIGHT"]) < 10 ? "disabled=\"disabled\"" : "");?> type="submit" name="web_form_submit" value="<?=htmlspecialcharsbx(strlen(trim($arResult["arForm"]["BUTTON"])) <= 0 ? GetMessage("FORM_ADD") : $arResult["arForm"]["BUTTON"]);?>" />
<?if ($arResult["F_RIGHT"] >= 15):?>
<input type="hidden" name="web_form_apply" value="Y" /><input type="submit" name="web_form_apply" value="<?=GetMessage("FORM_APPLY")?>" /><?endif;?>
<input type="reset" value="<?=GetMessage("FORM_RESET");?>" />
</th></tr></tfoot></table>
<p>
<?=$arResult["REQUIRED_SIGN"];?> - <?=GetMessage("FORM_REQUIRED_FIELDS")?>
</p>
<?=$arResult["FORM_FOOTER"]?>
<?
} //endif (isFormNote)
?>
Вот и где здесь action=" " или что-то в этом роде?
Попытался вставить тег <form id="Form" action="rezult.php" method="POST">, в котором дальнейшие действия передаются файлу rezult.php. Результат – тот же. Как ни ковырялся, - ничего. Либо в ответ «спасибо», либо очищает поля формы. Да. Тяжко приходится дилетанту. Наконец дошло: обработка входящих данных формы идет где-то в анналах битрикса, причём очень и очень глубоко, и явно не для средних умов. Поэтому не стал дальше «мучиться дурью», отказался от этой своей формы, и занялся main.feedback-ом.
Попытка 2. А вот в main.feedback-е нужный тег <form action="<? =POST_FORM_ACTION_URI?>" method="POST"> оказался на месте.
Вместо <?=POST_FORM_ACTION_URI?> подставил имя php-файла (rezult.php), через который шло соединение с базой данных. Также добавил в форму Согласие на обработку персональных данных. И случилось чудо. Форма заработала.
Попробовал добавить в Параметры компонента новые поля («Фамилия участника тестирования» и «Номер паспорта»), для чего отредактировал .parameters.php
по адресу \bitrix\components\bitrix\main.feedback\, а именно в массив "PARAMETERS" добавил следующие Array:
"FAM" => Array(
"NAME" => GetMessage("MFP_FAM"),
"TYPE" => "STRING",
"DEFAULT" => GetMessage("MFP_FAM"),
"PARENT" => "BASE",
),
"DOCUM" => Array(
"NAME" => GetMessage("MFP_DOCUM"),
"TYPE" => "STRING",
"DEFAULT" => GetMessage("MFP_DOCUM"),
"PARENT" => "BASE",
),
А в подмассив "VALUES" подмассива "REQUIRED_FIELDS" добавил "FAM" => GetMessage("MFP_FAM"), "DOCUM" => GetMessage("MFP_DOCUM"). Также в .parameters.php, находящийся в \bitrix\components\bitrix\main.feedback\lang\ru\ добавил следующие $MESS:
$MESS ['MFP_FAM'] = "Фамилия участника тестирования";
$MESS ['MFP_DOCUM'] = "Номер паспорта (без серии)";
После чего в Параметрах компонента появились нужные поля.
Хотя, что с этими параметрами, что без них, форма всё равно передает управление rezult.php, где идет моя обработка условия обязательных для заполнения полей. В итоге, всё моё действо по сути свелось к тому, что в форму main.feedback вставил <form action="rezult.php" method="POST"> и удалил лишнее. Естественно, что удовлетворения от содеянного получено не было, т.к. выглядело это, скажем прямо, убого (покромсал стандартный компонент).
Попытка 3. В итоге попробовал создать свой компонент, для чего воспользоваться простым примером создания компонента, размещенным на портале dev.1c-bitrix.ru.
1) Создал структуру папок и файлов компонента: /bitrix/components/zakupki32/testrezult . В папке testrezult создал три файла component.php, .description.php, .parameters.php и папку для хранения шаблонов templates. В этой папке создал папку .default и в ней файл template.php.
2) В созданные файлы добавил следующий код (который скопировал из соответствующих файлов компонента main.feedback и слегка отредактировал под свою задачу).
component.php
$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"] = "TESTREZULT_FORM";
$arParams ["FAM"] = trim($arParams["FAM"]);
if($arParams ["FAM"] == '')
$arParams ["FAM"] = GetMessage("MF_FAM");
$arParams ["DOCUM"] = trim($arParams["DOCUM"]);
if($arParams ["DOCUM"] == '')
$arParams ["DOCUM"] = GetMessage("MF_DOCUM");
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("FAM", $arParams["REQUIRED_FIELDS"])) && strlen ($_POST["FAM"]) <= 1)
$arResult ["ERROR_MESSAGE"][] = GetMessage("MF_REQ_FAM");
if((empty ($arParams["REQUIRED_FIELDS"]) || in_array("DOCUM", $arParams["REQUIRED_FIELDS"])) && strlen($_POST["DOCUM"]) <= 5)
$arResult ["ERROR_MESSAGE"][] = GetMessage("MF_REQ_DOCUM");
}
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 (strlen ($captcha_word) > 0 && strlen($captcha_code) > 0)
{
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(
"FAMILIA" => $_POST["FAM"],
"DOCUMENT" => $_POST["DOCUM"],
);
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_FAM"] = htmlspecialcharsbx($_POST["FAM"]);
$_SESSION ["MF_DOCUM"] = htmlspecialcharsbx($_POST["DOCUM"]);
LocalRedirect($APPLICATION->GetCurPageParam("success=".$arResult["PARAMS_HASH"], Array ("success")));
}
$arResult["FAMILIA"] = htmlspecialcharsbx($_POST["FAM"]);
$arResult ["DOCUMENT"] = htmlspecialcharsbx($_POST["DOCUM"]);
}
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(strlen($_SESSION["MF_FAM"]) > 0)
$arResult["FAMILIA"] = htmlspecialcharsbx($_SESSION["MF_FAM"]);
if(strlen($_SESSION["MF_DOCUM"]) > 0)
$arResult["DOCUMENT"] = htmlspecialcharsbx($_SESSION["MF_DOCUM"]);
}
}
if($arParams["USE_CAPTCHA"] == "Y")
$arResult ["capCode"] = htmlspecialcharsbx($APPLICATION->CaptchaGetCode());
$this->IncludeComponentTemplate();
.description.php
$arComponentDescription = array(
"NAME" => GetMessage("MAIN_TESTREZULT_COMPONENT_NAME"),
"DESCRIPTION" => GetMessage("MAIN_TESTREZULT_COMPONENT_DESCR"),
"ICON" => "/images/feedback.gif",
"PATH" => array(
"ID" => "utility",
),
);
?>
.parameters.php
$site = ($_REQUEST["site"] <> ''? $_REQUEST["site"] : ($_REQUEST["src_site"] <> ''? $_REQUEST["src_site"] : false));
$arFilter = Array("TYPE_ID" => "TESTREZULT_FORM", "ACTIVE" => "Y");
if($site !== false)
$arFilter["LID"] = $site;
$arEvent = Array();
$dbType = CEventMessage::GetList($by="ID", $order="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",
),
"FAM" => Array(
"NAME" => GetMessage("MFP_FAM"),
"TYPE" => "STRING",
"DEFAULT" => GetMessage("MFP_FAM"),
"PARENT" => "BASE",
),
"DOCUM" => Array(
"NAME" => GetMessage("MFP_DOCUM"),
"TYPE" => "STRING",
"DEFAULT" => GetMessage("MFP_DOCUM"),
"PARENT" => "BASE",
),
"REQUIRED_FIELDS" => Array(
"NAME" => GetMessage("MFP_REQUIRED_FIELDS"),
"TYPE"=>"LIST",
"MULTIPLE"=>"Y",
"VALUES" => Array("NONE" => GetMessage("MFP_ALL_REQ"), "FAM" => GetMessage ("MFP_FAM"), "DOCUM" => GetMessage("MFP_DOCUM")),
"DEFAULT"=>"",
"COLS"=>25,
"PARENT" => "BASE",
),
"GROUPS" => array(
),
"PARAMETERS" => array(
"AJAX_MODE" => array(),
"USER_CONSENT" => array(),
),
)
);
?>
template.php
if(!defined("B_PROLOG_INCLUDED")||B_PROLOG_INCLUDED!==true)die();
?>
<?
include_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/captcha.php");
$cpt = new CCaptcha();
$cpt->SetCodeLength(5);
$cpt->SetCode();
$code=$cpt->GetSID();
?>
<div class="mfeedback">
<?if(!empty($arResult["ERROR_MESSAGE"]))
{
foreach($arResult["ERROR_MESSAGE"] as $v)
ShowError($v);
}
?>
<form id="Form" action="rezult.php" method="POST">
<?=bitrix_sessid_post()?>
<table class="form-table data-table"><thead>
<tr>
<th colspan="2"><?=GetMessage("MFT_PERDAN")?></th>
</tr></thead>
<tbody>
<tr>
<td><?=GetMessage("MFT_FAM")?> <font color="red"><span class="form-required starrequired">*</span></font></td>
<td><input type="text" id="FAM" name="FAM" maxlength="14" value=""></td></tr>
<tr>
<td><?=GetMessage("MFT_DOCUM")?> <font color="red"><span class="form-required starrequired">*</span></font></td>
<td><input type="text" id="DOCUM" name="DOCUM" maxlength="8" value=""></td></tr>
<tr>
<th colspan="2"><b><?=GetMessage("MFT_CAPTCHA")?></b></th></tr>
<tr><td> </td>
<td><input type="hidden" name="captcha_sid" value="<?=$code;?>"> <img src="/bitrix/tools/captcha.php?captcha_sid=<?=$code;?>" width="189" height="40" alt="CAPTCHA"></td></tr>
<tr>
<td><div class="mf-text3"><?=GetMessage("MFT_CAPTCHA_CODE")?><span class="mf-req"> *</span></div></td>
<td><input type="text" name="captcha_word" value=""></td></tr>
</tbody>
<tfoot>
<tr>
<th colspan="2">
<?$APPLICATION->IncludeComponent(
"bitrix:main.userconsent.request",
"template_soglasie",
array(
"ID" => "1",
"IS_CHECKED" => "Y",
"AUTO_SAVE" => "Y",
"IS_LOADED" => "Y",
"REPLACE" => array(
"button_caption" => "Отправить",
"fields" => array(
0 => "Email",
1 => "Телефон",
2 => "Имя",
),
),
"COMPONENT_TEMPLATE" => "template_soglasie",
"COMPOSITE_FRAME_MODE" => "A",
"COMPOSITE_FRAME_TYPE" => "AUTO"
),
false
);?>
<br/>
<input type="hidden" name="PARAMS_HASH" value="<?=$arResult["PARAMS_HASH"]?>">
<input type="submit" name="submit" value="<?=GetMessage("MFT_SUBMIT");?>" size="32"></th><br/>
</tr>
</tfoot>
</table>
</form><br/>
<div class="mf-text"><font color="red"> *</font> - <?=GetMessage("MFT_REQUIRED_FIELDS");?></div>
<?=$arResult["FORM_FOOTER"]?>
</div>
3) Запустил Мастер создания новой страницы
Нажал Готово. Появилось окно с выбором компонентов. Среди которых (о чудо!) появился только что созданный мною компонент Форма Результаты тестирования. Добавил его на страницу.
Перешел в Параметры компонента. Выбрал свой шаблон. Отметил обязательные для заполнения поля.
Сохранил Параметры и страницу. Появилась моя форма. Шаблон компонента, как того требуют разработчики, перед изменением скопировал в шаблон сайта, куда добавил также вложенную папку lang\ru , в которой создал файл template.php следующего содержания:
<?
$MESS ['MFT_PERDAN'] = "Персональные данные";
$MESS ['MFT_FAM'] = "Фамилия участника тестирования";
$MESS ['MFT_DOCUM'] = "Номер паспорта (без серии)";
$MESS ['MFT_BACK'] = "Назад (к форме ввода данных)";
$MESS ['MFT_REQUIRED_FIELDS'] = "обязательные для заполнения поля" ;
$MESS ['MFT_CAPTCHA'] = "Защита от автоматического заполнения";
$MESS ['MFT_CAPTCHA_CODE'] = "Введите слово на картинке";
$MESS ['MFT_SUBMIT'] = "Показать результаты";
$MESS ['MFT_Err'] = "Ошибка ввода персональных данных! Повторите ввод данных!";
?>
В общем, вроде бы всё. Нагородил целый огород, чтобы создать простой компонент, - форму для ввода двух исходных данных. По сути, в этом компоненте мне пришлось использовать тот же самый, немного переделанный шаблон main.feedback-а. При этом в шаблоне созданного компонента управление всё равно передается другому модулю. Только у меня это происходит явным образом (в form action указан файл rezult.php), а в main.feedback указан POST_FORM_ACTION_URI.
Как работает форма можно посмотреть ЗДЕСЬ.
P.S. Перед написанием данного поста мне не давал покоя вопрос: почему в битриксе отсутствует форма запроса к базе для получения из неё запрашиваемых данных? Но по ходу разбирательства понял, что поскольку любая форма с вводимыми в неё исходными данными всё равно передает управление другому модулю, то и нет особого смысла заново ваять то, что уже давно наваяли. Поэтому, не мудрствуя лукаво, слепил rezult.php и в битрикс-форме передал ему управление.
- Комментарии