Devtoid

Кастомизация смарт-процессов через сервис локатор в Битрикс24

Подмена контейнера и фабрики

Пример кастомизации смарт-процесса через подмену контейнера

Точкой входа в новое API является контейнер. Подменить контейнер CRM можно в init.php или в .settings.php (общий или модуля)

<?php

// init.php
if (class_exists('\Bitrix\Main\DI\ServiceLocator')) {
    $serviceLocator = Bitrix\Main\DI\ServiceLocator::getInstance();
    $serviceLocator->addInstanceLazy('crm.service.container', [
        'className' => '\\Custom\\Crm\\Container',
    ]);
}

// .settings.php
return array(
    ....
    'services' => [
        'value' => [
            'crm.service.container' => [
                'className' => '\\Custom\\Crm\\Container',
            ],
        ],
        'readonly' => true,
    ],
);

Далее создаем подменный контейнер, в котором подменим фабрику для нужного смарт-процесса

<?php

namespace Custom\Crm;

use Bitrix\Crm\Service;
use Bitrix\Main\DI\ServiceLocator;
use Bitrix\Main\Loader;

Loader::requireModule('crm');

class Container extends Service\Container
{
    const TEST_SMART_PROCESS = 123; // ID смарт процесса

    public function getFactory(int $entityTypeId): ?Service\Factory
    {
        if ($entityTypeId == static::TEST_SMART_PROCESS) {

            // Идентификатор сервиса
            $identifier = static::getIdentifierByClassName(static::$dynamicFactoriesClassName, [$entityTypeId]);

            // Проверяем не создан ли уже объект класса
            if (ServiceLocator::getInstance()->has($identifier)) {
                return ServiceLocator::getInstance()->get($identifier);
            }

            // Попробуем получить объект класса
            $type = $this->getTypeByEntityTypeId($entityTypeId);
            if (!$type) {
                return null; // Не получилось, смарт-процесс удален
            }

            // Объект смарт-процесса получен, создаем фабрику и запоминаем ее
            $factory = new Factory($type);
            ServiceLocator::getInstance()->addInstance($identifier, $factory);

            return $factory;
        }

        return parent::getFactory($entityTypeId);
    }
}

Подмена только фабрики, без подмены контейнера

<?php

// init.php
if (class_exists('\Bitrix\Main\DI\ServiceLocator')) {
    $serviceLocator = Bitrix\Main\DI\ServiceLocator::getInstance();
    $serviceLocator->addInstanceLazy(
        "crm.service.factory.dynamic.123", // 123 - ID смарт процесса
        [
            'constructor' => static function () {
                \Bitrix\Main\Loader::requireModule('crm');
                $type = \Bitrix\Crm\Service\Container::getInstance()->getTypeByEntityTypeId(123);
                return new \Custom\Crm\Factory($type);
            },
        ]
    );
}

Непосредственно фабрика

<?php

namespace Custom\Crm;

use Bitrix\Crm\Service\Factory\Dynamic;
use Bitrix\Main;

Main\Loader::requireModule('crm');

class Factory extends Dynamic
{
    ...
}

 

Методы кастомизации смарт-процессов в фабрике будут в отдельном посте.

 

Источники:

  • https://bx24devbook.website.yandexcloud.net
  • https://nikaverro.ru/blog/bitrix/smartprotsessy-korobka-api/
  • https://dev.1c-bitrix.ru/api_d7/bitrix/crm/customization/index.php