Пользовательские действия
Форма настроек
Как устроена форма настроек пользовательского действия бизнес-процесса: properties_dialog.php, GetPropertiesDialog, GetPropertiesDialogValues и AJAX.
properties_dialog.php нужен, когда стандартной формы настроек уже не хватает:
нужно показать свои списки, добавить строки фильтра, подгрузить поля CRM или сохранить
сложную настройку в JSON.
Форма настроек
Форма открывается в дизайнере бизнес-процессов и сохраняет значения в свойства пользовательского действия.
Когда нужен properties_dialog.php
- тип CRM-сущности нужно выбирать из списка;
- условий фильтра может быть несколько;
- список полей зависит от выбранной сущности;
- значения списков должны подгружаться динамически;
- настройку нужно сохранить в JSON;
- перед сохранением шаблона нужно проверить заполнение.
GetPropertiesDialog
Метод подготавливает текущие значения и подключает файл формы через
ExecuteResourceFile().
public static function GetPropertiesDialog(
$documentType,
$activityName,
$arWorkflowTemplate,
$arWorkflowParameters,
$arWorkflowVariables,
$arCurrentValues = null,
$formName = ''
) {
$runtime = CBPRuntime::GetRuntime();
if (!is_array($arCurrentValues)) {
$arCurrentValues = [
'entity_type_id' => '',
'conditions_json' => '[]',
'select_fields' => '',
];
$current_activity = &CBPWorkflowTemplateLoader::FindActivityByName(
$arWorkflowTemplate,
$activityName
);
if (is_array($current_activity) && isset($current_activity['Properties'])) {
$properties = $current_activity['Properties'];
$arCurrentValues['entity_type_id'] = $properties['EntityTypeId'] ?? '';
$arCurrentValues['conditions_json'] = $properties['ConditionsJson'] ?? '[]';
$arCurrentValues['select_fields'] = $properties['SelectFields'] ?? '';
}
}
return $runtime->ExecuteResourceFile(__FILE__, 'properties_dialog.php', [
'documentType' => $documentType,
'activityName' => $activityName,
'arWorkflowTemplate' => $arWorkflowTemplate,
'arWorkflowParameters' => $arWorkflowParameters,
'arWorkflowVariables' => $arWorkflowVariables,
'arCurrentValues' => $arCurrentValues,
'formName' => $formName,
'entityTypeOptions' => self::getEntityTypeOptions(),
]);
}
Стандартные аргументы метода остаются в формате Битрикса:
$arWorkflowTemplate, $arWorkflowParameters,
$arWorkflowVariables. Это интерфейс платформы, а не место для
переименования переменных.
GetPropertiesDialogValues
Метод получает значения из формы, проверяет их и записывает в свойства блока.
public static function GetPropertiesDialogValues(
$documentType,
$activityName,
&$arWorkflowTemplate,
&$arWorkflowParameters,
&$arWorkflowVariables,
$arCurrentValues,
&$arErrors
) {
$arErrors = [];
$entity_type_id = trim((string) ($arCurrentValues['entity_type_id'] ?? ''));
$conditions_json = trim((string) ($arCurrentValues['conditions_json'] ?? '[]'));
$select_fields = trim((string) ($arCurrentValues['select_fields'] ?? ''));
if ($entity_type_id === '') {
$arErrors[] = [
'code' => 'emptyEntityTypeId',
'message' => 'Выберите тип CRM-сущности.',
];
}
$conditions = self::decodeConditionsJson($conditions_json);
if (empty($conditions)) {
$arErrors[] = [
'code' => 'emptyConditions',
'message' => 'Добавьте хотя бы одно условие фильтрации.',
];
}
if (!empty($arErrors)) {
return false;
}
$properties = [
'EntityTypeId' => $entity_type_id,
'ConditionsJson' => $conditions_json,
'SelectFields' => $select_fields,
];
$current_activity = &CBPWorkflowTemplateLoader::FindActivityByName(
$arWorkflowTemplate,
$activityName
);
$current_activity['Properties'] = $properties;
return true;
}
При false дизайнер покажет ошибки и не сохранит настройки. При
true свойства попадут в шаблон бизнес-процесса.
Имена полей формы
Имена HTML-полей должны совпадать с тем, что читает
GetPropertiesDialogValues().
<select name="entity_type_id">
<option value="">— выберите тип —</option>
</select>
<input type="hidden" name="conditions_json" value="[]" />
<input type="hidden" name="select_fields" value="" /> | Поле формы | Свойство действия | Что хранит |
|---|---|---|
entity_type_id | EntityTypeId | ID CRM-сущности или смарт-процесса. |
conditions_json | ConditionsJson | Условия фильтрации в JSON. |
select_fields | SelectFields | Поля, которые нужно вернуть в результатах. |
AJAX в форме
AJAX нужен только в дизайнере для настройки блока. Само выполнение бизнес-процесса
идёт через Execute().
Зачем нужен ajax.php
В действии расширенного поиска AJAX решает три задачи:
- получает список полей выбранной CRM-сущности;
- получает значения для списочного поля;
- ищет CRM-элементы для полей привязки.
Проверка сессии
AJAX-файл должен проверять сессию Битрикса. Без этой проверки форму можно дёргать прямыми запросами.
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
use BitrixMainLoader;
header('Content-Type: application/json; charset=UTF-8');
$response = [
'success' => false,
'error' => '',
];
try {
if (!check_bitrix_sessid()) {
throw new RuntimeException('Некорректная сессия. Обновите страницу и попробуйте снова.');
}
if (!Loader::includeModule('bizproc')) {
throw new RuntimeException('Не удалось подключить модуль bizproc.');
}
if (!Loader::includeModule('crm')) {
throw new RuntimeException('Не удалось подключить модуль crm.');
}
require_once __DIR__ . '/crmadvancedfindactivity.php';
// Обработка action.
} catch (Throwable $exception) {
$response['error'] = $exception->getMessage();
}
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php'; Подгрузка CRM-полей
Для формы настройки используется действие getFields. Оно возвращает
поля выбранной CRM-сущности.
if ($action === 'getFields') {
$entity_type_id = isset($_POST['entity_type_id']) ? (int) $_POST['entity_type_id'] : 0;
if ($entity_type_id <= 0) {
throw new RuntimeException('Не выбран тип CRM-сущности.');
}
$response['fields'] = CBPCrmAdvancedFindActivity::getCrmFieldsForUi($entity_type_id);
$response['success'] = true;
}
Метод getCrmFieldsForUi() собирает обычные и пользовательские поля,
определяет тип поля, множественность, значения списков и CRM-привязки.
Подгрузка значений поля
Списочные поля, стадии, валюты и пользовательские списки подгружаются под конкретное поле. Так форма не хранит лишние данные заранее.
if ($action === 'getFieldOptions') {
$entity_type_id = isset($_POST['entity_type_id']) ? (int) $_POST['entity_type_id'] : 0;
$field_name = isset($_POST['field_name']) ? trim((string) $_POST['field_name']) : '';
if ($entity_type_id <= 0 || $field_name === '') {
throw new RuntimeException('Не указан тип CRM-сущности или поле.');
}
$response['items'] = CBPCrmAdvancedFindActivity::getFieldOptionsForUi(
$entity_type_id,
$field_name
);
$response['success'] = true;
}
Для полей привязки к CRM в текущем действии есть отдельный action
searchCrmItems.