PHP-код в бизнес-процессе - переменные, типы, отладка
Пишем код внутри бизнес-процесса: читаем переменные, записываем результат и отлаживаем то, что нигде на экран не выводится.
Решение
Читаем поля документа и переменные процесса:
// внутри действия «PHP-код»: $this - экземпляр процесса$rootActivity = $this->GetRootActivity();$documentId = $rootActivity->GetDocumentId();$responsible = $rootActivity->GetVariable('Responsible');$state = $rootActivity->GetStateTitle(); // текущее состояние процесса// имена переменных задаются в дизайнере и чувствительны к регистру// поля документа приходят подстановками из дизайнера, а не читаются напрямуюДействие с кодом выполняется внутри процесса, а не в контексте страницы. Данных запроса здесь нет вовсе, а всё нужное берётся из переменных процесса и полей документа.
Записываем значение в переменную процесса:
$rootActivity = $this->GetRootActivity();$rootActivity->SetVariable('Result', 'обработано');// переменная доступна всем следующим действиям процесса$rootActivity->SetVariable('ProcessedAt', date('d.m.Y H:i:s'));Переменная процесса - единственный способ передать значение дальше по схеме процесса. Обычная переменная PHP живёт до конца текущего действия и следующему шагу схемы не оставляет ничего.
Разбираемся с полями типа «список»:
// в переменной лежит код значения, а не его текст$status = $rootActivity->GetVariable('Status'); // например, APPROVEDif ($status === 'APPROVED') { // сравниваем с кодом, не с текстом $rootActivity->SetVariable('Result', 'согласовано');}Поля-списки хранят внутри себя коды значений. Сравнение с текстом значения в условии не сработает никогда, и это самая частая причина жалобы «условие не выполняется, хотя значение то самое».
Отлаживаем код процесса:
file_put_contents('/home/bitrix/www/upload/bp.log', date('c') . ' ' . print_r($rootActivity->GetVariable('Result'), true) . "\n", FILE_APPEND);// вывод на экран из процесса не виден: он выполняется вне страницыПечать на экран в процессе бесполезна: он выполняется в фоне или в обработчике сохранения документа. Запись в файл остаётся единственным способом увидеть, что там на самом деле происходит.
Действие с кодом должно оставаться по возможности коротким. Тяжёлые операции внутри процесса удлиняют сохранение документа для человека, который его правит, а при выполнении по расписанию надолго занимают агента. Долгую работу выносят в свой отдельный агент, а сам процесс только ставит задачу.
Код внутри процесса тяжело сопровождать: он лежит в базе, не попадает в репозиторий и не виден при поиске по проекту. Поэтому всё, что длиннее нескольких строк, выносят в свой класс действия или в обычный файл, а в процессе оставляют один вызов.
Ошибка в коде роняет весь запущенный экземпляр процесса целиком. Он останавливается в этой точке и дальше не идёт, поэтому проверки на пустые значения пишут явно: отсутствие поля у одного документа не должно останавливать всю схему.
Типичные проблемы
Значение не доходит до следующего действия.
Значение записано в обычную переменную PHP внутри действия. Передать его дальше по схеме можно только через переменную процесса.
Условие по полю-списку не срабатывает.
В условии сравнивается текст значения вместо его кода. В переменной процесса лежит именно код, а не человеческая подпись.
Код ничего не выводит.
Процесс выполняется вне страницы, и печать на экран уже никуда не попадает. Отладку в таком случае ведут записью в отдельный файл.
Процесс остановился без сообщения.
В коде действия произошла ошибка выполнения. Экземпляр процесса прекращает работу в этой точке и остаётся в ней навсегда.
Сохранение документа стало медленным.
Тяжёлый код внутри процесса выполняется прямо в момент сохранения документа. Долгие операции из процесса выносят в отдельный агент.
Частые вопросы
Можно ли обойтись без кода в процессе?
Штатных действий хватает для условий, задач и уведомлений. Код нужен там, где требуется обращение к своим данным или к внешней системе.
Как получить элемент списка, зная только его название?
Выборкой по инфоблоку списка внутри кода. Название не уникально, поэтому в условиях полагаются на код или идентификатор.
Почему код не видит подключённых модулей?
Модули подключают явно, как в любом своём коде. Процесс не поднимает ничего сверх ядра платформы.
Как проверить код, не запуская процесс целиком?
Вынести его в отдельный файл и запустить из консоли с теми же входными данными. Внутри процесса отладка всегда дороже.
Смежное
- Бизнес-процессы - оглавление подтемы
- Своё действие бизнес-процесса: папка, описание, форма настроек - когда кода в действии становится много
- Бизнес-процесс над элементом списка - чтение и запись данных документа
- Задача в бизнес-процессе: назначение, сроки, ответ участника - как процесс ждёт человека
- Модули и решения - устройство модулей платформы
- Бизнес-процесс не запускается или стоит: разбор причин - когда процесс встал целиком
- Свой тип пользовательского поля: регистрация, формы, значение - почему свой тип поля не виден процессу
- Свой модуль: структура, установка, обновления - как упаковать код проекта
- Поля документа в процессе: списки, файлы, запись обратно - что приходит в код из документа
- Запуск бизнес-процесса из кода: шаблон, документ, повторы - как запустить процесс своим кодом