How to auto-replace any block of actions, variables, conditions, constants in a business process of boxed Bitrix 24

How did I get the idea to implement this?

After the next update of the Bitrix 24 boxed portal in March 2023, type modification stopped working in business processes when assigning values ​​to string variables.

For example, when assigning the variable “Variable1“meanings”{{Начальная сумма > double}}|{{Валюта > user}}” in the block “Changing variables” business process, modifier ” > double” transforms us into a type of field “Money” (type 100|RUB) according to the rules for converting a string to “Number” – 100, and from the “Currency” field the modifier “> user” always gave the currency code – “RUB”. Thus, this transformation should assign the variable “Variable1” a value of the form “100|RUB”. And after the update it says “100|RUB|Российсий рубль“.

However, after the ill-fated update, and to this day, by the way, these modifiers stopped working, specifically when assigning a value to a variable of the “String” type; in all other cases, including the “Notification” action block, it works!

In order for this transformation to work in the business process after the update, it is necessary to “wrap” the modifiers in another function, since once again, modification does not work only with string variables.

I used the “trim()” function for this, and as a result we get the following entry:

 {{trim({{Начальная сумма > double}}&"|"&{{Валюта > user}})}}

This method of implementing modifiers works both “before” and “after” the ill-fated update.

Hence, I had the need to replace this record for one of the clients in more than four hundred business processes! At the same time, many business processes contain hundreds of actions in dozens of condition branches. The probability of missing such an entry, with exhausting manual editing, tends to 100%!

The procedure for implementing auto-replacement of something in one or all business processes

  1. We get the business process template(s) in the form of a multidimensional array.

  2. We use the search function according to the necessary criteria and modify the action.

Let's implement step 1 (get templates)

The Bitrix 24 documentation does not describe the functionality of obtaining business process templates in the form of data arrays; there is only a description that they are stored in this way. Therefore, help came from another useful article on Habr about the transfer of business processes.

So on to the code.

Receiving one or more business process templates:

$resFields = \CBPWorkflowTemplateLoader::GetList(
    [],
    ['ID' => 474], //для получения всех шаблонов, оставляем пустым
   // ['USER_ID' => 34], //для получения всех шаблонов, одного создателя
    false,
    false,
    ['ID', 'NAME', 'TEMPLATE', 'VARIABLES']); //нам нужны только шаблоны, 
//однако для фильтрации нужных значений понадобится типы переменных, 
//а для отладки ID и имена БП

Next we go through the result:

while ($arFields = $resFields->GetNext()) {
    if (!is_array($arFields)) {
        echo "Из базы ничего не пришло!";
        break;
    }
    //ниже 4 строчки которыми я убираю дополнительно пришедшие из БД дубликаты массивов
    unset($arFields['~ID']);
    unset($arFields['~NAME']);
    unset($arFields['~TEMPLATE']);
    unset($arFields['~VARIABLES']);
    //помещаем в отдельные массивы шаблоны и переменные БП
    $arTemplate = $arFields['TEMPLATE']; 
    $arVariables = $arFields['VARIABLES'];
    /*дальше я прохожусь функией по всему массиву, 
    т.к. я не знаю какова страутура многомерного массива, 
    какие названеи переменных и сколько раз им назначаются значения в БП
    callback функцию "changeNeedleStringInArray", приведу ниже */
    array_walk($arTemplate, 'changeNeedleStringInArray'); 
    $arNewFields['TEMPLATE'] = $arTemplate;
    //без поля "MODIFIER_USER" - сохранение не срабатывает, выдаёт ошибку совершенно на этот факт не указывающую
    $arNewFields["MODIFIER_USER"] = new \CBPWorkflowTemplateUser(CBPWorkflowTemplateUser::CurrentUser);
    \CBPWorkflowTemplateLoader::update($arFields['ID'], $arNewFields);
    //чистим память
    unset($arFields);
    unset($arNewFields);
    unset($arTemplate);
    unset($arVariables);
}
//выводим строки для проверки дебага результата
echo "<pre>";
if (!empty($convert)) {
    print_r(count($convert));
    print_r(PHP_EOL);
    print_r($convert);
}

Let's implement step 2 (search and modification)

We perform transformations in the 'changeNeedleStringInArray' function, I will have 3 examples below:
1. We fix the problem described at the beginning of the article.{{Начальная сумма > double}}|{{Валюта > user}}convert to {{trim({{Начальная сумма > double}}&"|"&{{Валюта > user}})}}

/*

*/
function changeNeedleStringInArray(&$val, $key)
{
    if (is_array($val)) {
        array_walk($val, 'changeNeedleStringInArray'); //заходим этой же функцией во вложенный массив
    } elseif (is_string($val)) {
        if (stripos($val, '|{=Document:CURRENCY_ID > user')  // ищем нужное значение в действии БП
            && !stripos($val, '{{=trim') //проверяем не сделано ли уже нужное нам преобразование
            && (isVarTypeString($key)) //проверяем тип переменной (нам надо менять только в строках)
        ) {
            $val = convertActivityValue($val, $key);
        }
    }
}
function isVarTypeString($key)
{
    global $arVariables;
    if ($arVariables[$key]['Type'] == 'string')
        return true;
    return false;

}

function convertActivityValue($str, $key)
{
    global $convert, $arFields;
    if (!stripos($str, "|")) //проверяем что найденна требуемая нам строка
        return $str;
    $arHelp = explode("|", $str);
    if (stripos($arHelp[0], "=")) {
        $resStr = "{{=trim(" . $arHelp[0] . "&\"|\"&" . $arHelp[1] . ")}}";
    } else {
        $resStr = "{{=trim(\"" . $arHelp[0] . "|\"&" . $arHelp[1] . ")}}";
    }
    $convert[$arFields['NAME']][$arFields['ID']][$key][] = $str;
    $convert[$arFields['NAME']][$arFields['ID'] . "_new"][$key][] = $resStr;
    return $resStr;
}
  1. With one of the updates, some REST requests became case-sensitive to the “ID” of objects in the passed parameters; now only lowercase “id” works. Accurately verified with comments removed in timeline: crm.timeline.comment.delete Since in some BPs I used REST calls via curl as asynchronous calls, after updates I had to make changes here too. We fix it '\"ID\"' on '\"id\"' V curl

function changeNeedleStringInArray(&$val, $key)
{
    if (is_array($val)) {
        array_walk($val, 'changeNeedleStringInArray'); //заходим этой же функцией во вложенный массив
    } elseif (is_string($val)) {
        if (stripos($val, 'curl')  // ищем нужное значение в действии БП
            && strpos($val, '\"ID\"') // ищем дополнительное нужное значение в действии БП
            && ($key == 'ExecuteCode') //проверяем тип переменной (нам надо менять только в PHP блоках)
        ) {
            $val = convertActivityValue($val, $key);
        }
    }
}
function convertActivityValue($str, $key)
{
    global $convert, $arFields;
    $resStr = str_replace('\"ID\"', '\"id\"', $str);
    $convert[$arFields['NAME']][$arFields['ID']][$key][] = $str;
    $convert[$arFields['NAME']][$arFields['ID'] . "_new"][$key][] = $resStr;
    return $resStr;
}
  1. BBCode stopped working in “Notifications” indicating colors by their name, like
    [color=red]Текст[/color] – the message is displayed without formatting
    But [color=#ff0000]Текст[/color] – it works quite well. Substitute:

function convertActivityValue($str, $key)
{
    global $convert, $arFields;
    $resStr = str_replace('red', '#db0000', $str);
    $convert[$arFields['NAME']][$arFields['ID']][$key][] = $str;
    $convert[$arFields['NAME']][$arFields['ID'] . "_new"][$key][] = $resStr;
    return $resStr;
}

function changeNeedleStringInArray(&$val, $key)
{
    if (is_array($val)) {
        array_walk($val, 'changeNeedleStringInArray'); //заходим этой же функцией во вложенный массив
    } elseif (is_string($val)) {
        if (stripos($val, '[color=red]')  // ищем нужное значение в действии БП
            && ($key == 'MessageSite') //проверяем тип переменной (нам надо менять только в Уведомлениях)
        ) {
            $val = convertActivityValue($val, $key);
        }
    }
}

Results

Thus, we have the opportunity to make any changes to business process templates in bulk. Edit templates not only from a beautiful web interface, but in the form of “hard code”. Also, based on this code, you can debug business process templates or dynamically change them.

I am sure that many B24 integrators are faced with similar changes in the operation of business processes.

Therefore, I think that this article has made our hard work significantly easier for us.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *