Жутко не люблю (коллеги, голосуем) этот модуль. Кстати, когда я пришел в компанию ХХХ неокрепшим юнцом, веб-формы были первым модулем. То есть, я даже не знал где что лежит в Битриксе, а меня кидают в этот модуль. Представляете мой ужас? Я ненавидел этот продукт, не понимал восторга в лице коллеги-пма. Ну и вообще, отчаялся изучить сие ремесло. Но прошли годы, любовь к продукту появилась, ненависть к модулю осталась Но это лирика.
Задача. Изменить один ответ результата веб-формы после каждого добавления и изменения результата менять поле (допустим, писать туда информацию о пользователе). Вроде просто. В тех же ИБ это решается SetPropertyValueCode (аналогия кстати очень близка, но только в самой идеи, технологии и API рядом не стояли).
Проблема 1. Нельзя выводить это поле в форме (например, hidden'ом), ибо могут подделать.
Проблема 2. Изменить можно только посредством CFormResult::Update после сохранения. Но у него проблема - он требует передачи всех ответов одного результата, что довольно неприятно. Ищем зацепку. Находим -
Второй параметр - По умолчанию - "false" (будет взят стандартный массив $_REQUEST).
Так как в моем случае сохранение всегда происходило из формы, а не через API, то этот массив всегда полон и актуален. Решение оказалось простое:
То есть - подменяем ключ в реквесте, как-будто он прилетел от пользователя. И готово. Кстати, имхо как-то слишком тут не секюрно все это - что прилетело, то и кормим, не зависимо от того, были поля в форме или нет. Не зря не любил модуль.
Вот и все, задача решена. Приведу код обработчиков:
public static $disableUpdate = false;
public static function onAfterResultAddHandler($WEB_FORM_ID, $RESULT_ID) {
if ($WEB_FORM_ID==self::wfEvent2012reg && !defined('ADMIN_SECTION')) {
self::$disableUpdate = true;
$_REQUEST['form_dropdown_GUEST_STATUS'] = 72;
CFormResult::Update($RESULT_ID, false, 'N', 'N');
}
}
public static function onAfterResultUpdateHandler($WEB_FORM_ID, $RESULT_ID) {
if (!self::$disableUpdate && !defined('ADMIN_SECTION')) {
self::$disableUpdate = true;
$_REQUEST['form_dropdown_GUEST_STATUS'] = 72;
CFormResult::Update($RESULT_ID, false, 'N', 'N');
}
}
self::$disableUpdate нужен, чтобы скрипт не ушел в бесконечный цикл (обработчик вызывается внутри апдейта, где снова вызывается обработчик. Ну а ADMIN_SECTION требуется, чтобы в админке это поле можно было бы изменить.
Антон, обратите внимание, в формах есть вопросы, а есть еще поля!
"Вопрос" - это то что приходит из результата формы, а "поле" это как бы еще вопросы, но которые пользователь не редактирует и не видит.
В своем проекте, я записывваю в служебное поле статус пользователя на сайте, чтобы редактору сайта было проще понимать какой пользователь к нему обратился.
// для форм события с маленькой буквы!
// onAfterResultAdd
AddEventHandler( 'form', 'onAfterResultAdd', Array( "MyClass", "onAfterResultAddHandler" ) );
class MyClass
{
function onAfterResultAddHandler( $WEB_FORM_ID, $RESULT_ID )
{
if ($WEB_FORM_ID == 1 && $RESULT_ID > 0)
{
// подставим текущий статус пользователя.
global $USER;
$arLastStatus = CStatus::GetLastUserStatus( $USER->GetID() );
if ( is_array($arLastStatus) && isset( $arLastStatus["~NAME"] ) )
{
CFormResult::SetField($RESULT_ID, "STATUS", $arLastStatus["~NAME"]);
}
}
}
}
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».