Полный цикл в digital

Действие в виде PHP кода

Иногда возникает необходимость расширить стандартные возможности бизнес-процессов, а для этого в коробке есть большой набор инструментов, одним из которых является действие PHP код.

Преимущества:

  • Позволяет расширять возможности бизнес-процессов
  • Занимают минимальное время на разработку

Недостатки:

  • Некорректно описанный код может заблокировать процесс
  • При наличии активити в схеме бизнес-процесса, редактировать бизнес-процесс могут только сотрудники с правами на изменение физических файлов портала (административный доступ)
  • Большие активити с течением времени сложно поддерживать

Правила

В случае если вы решили писать активити старайтесь следовать правилам:

  1. Чем меньше кода тем проще его отладить, старайтесь использовать код который можно отладить и без активити.
  2. Оборачивайте код в try-catch блок ожидая Throwable. Таким образом вы предотвратите неожиданные и необъяснимые падения.
  3. Записывайте все что может быть важно. Успешное выполнение, ошибка или неожиданное поведение
  4. Не используйте код, который интерпретируется парсером битрикса, например {ID} автоматически заменяемый
  5. Не опирайтесь на глобальные переменные. Код может выполнять как на странице, так и на cron переменная с текущим пользователем может быть пуста или заполнена не тем сотрудником, идентификатора сайта может не быть

Логирование

Для того чтобы делать записи в журнал бизнес-процесса существует специальный сервис журналирования (TrackingService) и быстрая log-функция \CBPActivity::WriteToTrackingService. Так как любое действие (активити) является наследником этого класса, то обращаться к нему можно через $this.

Сигнатура метода:

/**
 * @param string $message      Message to log
 * @param int    $modifiedBy   Who modifier
 * @param int    $trackingType Tracking type
 * @type void
 */
\CBPActivity::WriteToTrackingService($message = "", $modifiedBy = 0, $trackingType = -1): void

Параметрами данного метода являются:

  • $message (string) текстовая строка, которая будет записана в журнал бизнес-процесса
  • $modifiedBy (int) идентификатор сотрудника, который будет записан в журнал. 0 — соответствует системе
  • $trackingType (enum) тип сообщения

Пример записи обычного сообщения в журнал:

$this->WriteToTrackingService(
	"Some message!",
	0,
	\CBPTrackingType::Report
);

Тоже самое в укороченном виде:

$this->WriteToTrackingService("Some message!");

Допустим, при создании бизнес-процесса пользователь вводит текст, который сохраняется в переменной Text. Чтобы вывести в лог значение этой переменной нужно просто в действии PHP код добавить вызов:

$rootActivity = $this->GetRootActivity();
$this->WriteToTrackingService($rootActivity->GetVariable("Text"));

Типы сообщений в логировании

Зарегистрированные типы сообщений хранятся константами в классе CBPTrackingType, однако констант в классе гораздо больше чем отображаемых в журнале сообщений.

Все типы сообщений в журнале отображаются одинаково, однако семантически лучше разделять их для возможного последующего использования в коде

Отображаемые сообщения:

  • \CBPTrackingType::Error ошибки в процессе работы
  • \CBPTrackingType::Report примечания в процессе работы
  • \CBPTrackingType::Custom сообщения неопределенного типа
  • \CBPTrackingType::FaultActivity критическая ошибка при работе действия

Возможные проблемы

В действиях бизнес-процесса часто необходимо взаимодействовать с окружением — переменными процесса, параметрами, константами, глобальными константами и переменными, полями документа. Самое очевидное, что приходит на ум всем — использовать подстановку переменных через стандартный редактор.

Представим самый обычный код:

$testMessage = "Entity id: {{Название компании}}";

$this->WriteToTrackingService($testMessage);

Код выглядит, запуститься и даже будет выдавать результат, однако в данном случае в нем кроется часовая бомба. В чем проблема? Представим грубо, что любая заменя это просто набор str_replace, т.е. переменные будут заменены как есть. Что произойдет если в заменяемой фразе будет кавычка? Например: в названии компании указано значение ООО "Супер сила"

Таким образом код выглядит следующим образом:

$testMessage = "Entity id: ООО "Супер сила"";

$this->WriteToTrackingService($testMessage)

Заметили синтаксическую ошибку? Именно — указанный фрагмент будет вызывать фатальную ошибку. Теперь когда вы поняли почему нельзя работать с автозаменой давайте разберем техники как этого обойти.

Шаблон активити

try
{
	// ... code here ...
}
catch( \Throwable $e )
{
	$this->WriteToTrackingService(
		sprintf("Error %s on line %s in file %s",
			$e->getMessage(),
			$e->getLine(),
			$e->getFile()
		),
		0,
		CBPTrackingType::FaultActivity
	);
}

Парсинг

Из курса по бизнес-процессам нам известно о существование таких элементов как парсер (выполняет автозамену) и калькулятор выражений (парсит и вычисляет значения). За парсинг значений отвечает метод \CBPActivity::parseValue($value, $convertToType = null), тогда у нас есть возможность использовать ее для своих нужд.

$this->ParseValue('{'.'=Document:TITLE}')

Правда тут есть одна неприятность: необходимо использовать не отображаемое значение, а реальное. Так например {{ID}} станет {=Document:ID}. Тогда {{Название компании}} станет {=Document:TITLE}.

Таким образом наш преобразованный код будет выглядеть так:

$testMessage = "Entity id: ".$this->ParseValue('{'.'=Document:TITLE}');

$this->WriteToTrackingService($testMessage);

Почему мы не написали ParseValue('{=Document:TITLE}')? Дело в том, что в таком случае сработала бы автозамена и мы получили такую же ошибку, как и ранее, поэтому мы сознательно разделили нашу запись чтобы автозамена значений битрикса не сработала.


Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!