← Назад к справке

Пользовательские действия

Форма настроек

Как устроена форма настроек пользовательского действия бизнес-процесса: 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.

Источники