В Битрикс24 все чаще используются смарт-процессы в решении многих задач. Чтобы кастомизировать логику работы со смарт-процессами нужно реализовать подмену сервис-контейнера смарт-процессов. Для этого и разработана данная библиотека.
Установка
Библиотека b24/devtools устанавливается через composer:
composer require b24/devtools
Подмена Сервис контейнера
В Битриксе при определенных действиях происходят различные события на элементах смарт-процесса. Чтобы как-то изменить поведение смарт-процесса при определенном событии и существует подмена сервис контейнера. Для реализации подмены необходимо получить символьный код элементах смарт-процесса. Его можно найти в таблице b_crm_dynamic_type.
Внутрь контейнера передаётся массив, где ключом будет символьный код смарт-процесса, а значением неймспейс нашего класса фабрики для этого смарт-процесса.
Этот код можно разместить в init.php:
Use B24\Devtools\Crm\Replacement\Container;
new Container([
TEST' => FactoryTest::class
);
Фабрика смарт-процесса должна в свою очередь наследоваться от
Bitrix\Crm\Service\Factory\Dynamic
Пример фабрики для смарт-процесса TEST:
use Bitrix\Crm\Service\Context;
use Bitrix\Crm\Service\Operation;
use Bitrix\Crm\Service\Factory\Dynamic;
class FactoryTest extends Dynamic
{
public function getAddOperation(Item $item, Context $context = null): Operation\Add
{
$operation = parent::getAddOperation($item, $context);
$operation->addAction(
Operation::ACTION_BEFORE_SAVE,
new AddHandler()
);
return $operation;
}
}
AddHandler - это обработчик события на добавление, который вызовется ДО добавления элемента в базу. Этот обработчик должен наследовать Bitrix\Crm\Service\Operation\Action
use B24\Devtools\Crm\ResultOperationTrait;
use Bitrix\Crm\Service\Operation;
use Bitrix\Crm\Item;
class AddHandler extends Operation\Action
{
use ResultOperationTrait;
public function process(Item $item): Result
{
return $this
->error('Ошибка 1')
->error('Ошибка 2')
->result();
}
}
В этом обработчике используется trait ResultOperationTrait. В него завёрнут ООП подход для работы с Result, который должен вернуть обработчик.
error() – записывает ошибку в Result и возвращает самого себя же.
result() – возвращает результат.
Таким образом можно собрать несколько ошибок и отдать пользователю
Упрощённая работа с сущностью смарт-процесса
В Битрикс 24 довольно много придётся писать код, чтобы получить ID смарт-процесса и собрать для него фабрику. Что предлагает Битрикс24:
$factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory(152);
То есть нужно заранее знать ID смарт-процесса, а это не очень хорошо, т.к. смарт-процесс может добавляться через миграцию, а также на разных площадках (тестовая, продакшен) могут отличаться ID смарт-процессов. Чтобы этого избежать нужно использовать код смарт-процесса:
$smart = new B24\Devtools\Crm\Smart\SmartProcess('SYMBOL_CODE');
$factory = $smart->getFactory();
Кроме того, в конструктор класса SmartProcess можно передать и значение типа сущности, например \CCrmOwnerType::Deal. Поэтому можно делать даже так:
$smart = new B24\Devtools\Crm\Smart\SmartProcess(\CCrmOwnerType::Deal);
Так же у этого класса есть различные методы:
$smart->getFactory(); // Вернёт фабрику сущности
$smart->getFactoryId(); // ID сущности
$smart->getEntityName(); // Название объекта сущности, CRM_2 (например)
$smart->compileClass(); // Отдаст неймспейс класса ORM смарт-процесса
$smart->getContainer(); // Отсюда же можно вытащить сервис контейнер
$smart->getRelationManager(); // RelationManager
Метод $smart->getEntityName() пригодится для написания миграций для смарт-процесса
Отрывок из миграции:
$pvz = new SmartProcess('PVZ');
$name = $pvz->getEntityName();
$helper = $this->getHelperManager();
$helper->UserTypeEntity()->saveUserTypeEntity([
'ENTITY_ID' => $ name,
………
]);
Работа со связями crm
В Битрикс 24 есть различные связи между сущностями crm (см. таблицу b_crm_entity_relation). В библиотеке реализованы различные методы для работы со связями.
// Чтение связей //
$children = \B24\Devtools\Crm\Relation\Manager::searchChildren(\CCrmOwnerType::Quote, 1)
->getAll(); // Массив из Bitrix\Crm\ItemIdentifier всех привязанных детей к Предложению.
В Bitrix\Crm\ItemIdentifier хранится ID элемента и EntiryTypeIdсмарт-процесса
$children = \B24\Devtools\Crm\Relation\Manager::searchChildren(\CCrmOwnerType::Quote, 1)
->withEntityTypeId(152); // Массив ID всех привязанных детей-элементов смартпроцесса с ID 152
$children = \B24\Devtools\Crm\Relation\Manager::searchChildren(\CCrmOwnerType::Quote, 1)
->withOne(function (\Bitrix\Crm\ItemIdentifier $identifier) {
return $identifier; // если вернуть просто $identifier, тогда Вернёт массив из ItemIdentifier
return $identifier->getEntityId(); // Вернёт массив из ID элементов в ItemIdentifier
});
// Если заменить метод searchChildren на searchParents, то будут искаться родители //
// Обновление связей //
\B24\Devtools\Crm\Relation\Manager::update(\CCrmOwnerType::Quote, 1, 152, 1)
->isParent() // Например если в связи надо отвязать родителя (Предложения) и привязать к другому Предложению
->on(\CCrmOwnerType::Quote, 2) // Привязываем к Предложению с ID = 2
->replace(); // Замена
// Удаление какой-то одной связи //
\B24\Devtools\Crm\Relation\Manager::deleteOne(
parentEntityTypeId: \CCrmOwnerType::Quote,
parentEntityId: 1,
childEntityTypeId: 152,
childEntityId: 1
);
// У Предложения с ID = 1 удаляем все связи со смарт-процессом, у которого ID = 152
\B24\Devtools\Crm\Relation\Manager::deleteWithType(
parentEntityTypeId: \CCrmOwnerType::Quote,
parentEntityId: 1,
childEntityTypeId: 152,
);
// Создание связей
// Создаст у Предложения с ID = 1 связь (ребёнка) со смарт-процессом с ID = 152 //
\B24\Devtools\Crm\Relation\Manager::create(
parentEntityTypeId: \CCrmOwnerType::Quote,
parentEntityId: 1,
childEntityTypeId: 152,
childEntityId: 1
);
Работа с денежными полями
Очень часто приходится работать с денежными сущностями в Битрикс24. Например, чтобы избежать такого кода:
$moneyField = '155|USD';
$rateToRub = 93.22;
[$price, $currency] = explode('|', $moneyField);
$newPrice = round($price * $rateToRub, 2);
$newMoneyField = $newPrice . '|RUB';
echo $newMoneyField; // 14449.1|RUB
Был придуман B24\Devtools\Data\MoneyField хэлпер для работы с денежными единицами. Код превращается в:
$moneyField = '155|USD';
$rateToRub = 93.22;
$money = B24\Devtools\Data\MoneyField::parse($moneyField)
->math(function (&$price) use ($rateToRub) {
$price = $price * $rateToRub;
})
->setCurrency('RUB')
->round(2);
echo (string) $money; // 14449.1|RUB
Работа с Пользовательскими полями для смарт-процессов и сущностей CRM
У смарт-процессов могут быть пользовательские поля с типом «Список», у этого списка есть поля ID, XML_ID, Значение
И чтобы задать смарт-процессу какое-то значение списка в это поле нужно передавать ID этого значения.
Хелпер B24\Devtools\Data\UserField упрощает получение значения пользовательских полей:
$smart = new B24\Devtools\Crm\Smart\SmartProcess('TEST');
$userField = new \B24\Devtools\Data\UserField($smart);
$userField->getUserFields('UF_TYPE_LIST');
$idPickup = $userField->getUserFieldsValue([
'XML_ID' => 'PICKUP_PVZ'
])['ID'];
// getUserFields - Загружает пользовательское поле, эта функция бросает исключение если не нашлось такое поле у сущности
// и возвращает массив с данными этого пользовательского поля
// getUserFieldsValue - Вернёт массив значений по фильтру
// Кроме того, если задать объекту UserField $userField->isOne = false тогда вернутся несколько объектов по фильтру
Так же этот хелпер может учитывать не только сущности смарт-процессов, но и другие сущности CRM, например сделок:
$userField = new \B24\Devtools\Data\UserField('CRM_DEAL');
Преобразование массивов и строк в camelCase и обратно
В Битриксе есть стандарт написания ключей в массиве - SNAKE_KEYS, но иногда нужно чтобы ключи были в более привычном виде camelCase.
В пакете есть 2 хелпера, которые преобразуют ключи массивов или строк в camelCase или SNAKE_KEYS.
Например есть массив данных:
$arr = [
'CONTACTS' => [
[
'NAME' => 'Имя',
'LAST_NAME' => 'Фамилия'
]
]
];
Вызываем хелпер \B24\Devtools\Data\ArrayHelper с методом arrayToCamelCase
$arr = \B24\Devtools\Data\ArrayHelper::arrayToCamelCase($arr);
Массив превратится в такой:
Array
(
[contacts] => Array
(
[0] => Array
(
[name] => Имя
[lastName] => Фамилия
)
)
)
Чтобы вернуть обратно массив с прежними ключами, нужно вызвать метод arrayToUnderScore
$arr = \B24\Devtools\Data\ArrayHelper::arrayToUnderScore($arr);
Этот Хелпер работает вокруг хелпера \B24\Devtools\Data\StringHelper, который тоже самое делает со строками.
$string = 'LAST_NAME';
$string = \B24\Devtools\Data\StringHelper::stringToCamelCase($string); // lastName
$string = ' lastName ';
$string = \B24\Devtools\Data\StringHelper::stringToCamelCase($string); // LAST_NAME
Работа с инфоблоком через символьный код API
Битрикс позволяет работать с инфоблоком как с сущностью ORM D7. Если у инфоблока задан символьный код API, например, REGION, то его ORM класс будет называться:
\Bitrix\Iblock\Elements\Element\RegionTable
В библиотеке реализован хелпер, который соберёт сам название класса:
$iblock = new \B24\Devtools\Data\Iblock('REGION');
$class = $iblock->getClassName(); //Bitrix\Iblock\Elements\Element\RegionTable
И далее можно с ним работать как с ORM:
$class::getList();
Можно ещё короче:
$res = \B24\Devtools\Data\Iblock::generateClassName('REGION')::getList()->fetch();
Ссылка на репозиторий с данным пакетом- Установка
- Подмена Сервис контейнера
- Упрощённая работа с сущностью смарт-процесса
- Работа со связями crm
- Работа с денежными полями
- Работа с Пользовательскими полями для смарт-процессов и сущностей CRM
- Преобразование массивов и строк в camelCase и обратно
- Работа с инфоблоком через символьный код API