Работа с элементами

Взаимодействие с элементами смарт-процессов осуществляется через фабрики (Bitrix\Crm\Service\Factory), получать которые необходимо из контейнера \Bitrix\Crm\Service\Container. Это означает что перед выполнением любой операции необходимо сначала получить контейнер, затем получить необходимую фабрику и уже после выполнить действие.

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

Здесь и ниже, мы будем предполагать что работаем с существующим смарт-процессом, который имеет ENTITY_TYPE_ID равный 184. Перед дальнейшей работой необходимо получить фабрику элементов смарт-процессов.

use \Bitrix\Crm\Service;

/**
 * @var Service\Container
 */
$container = Service\Container::getInstance();

/**
 * @var Service\Factory\Dynamic
 */
$factory = $container->getFactory( 184 );

Получение списка полей

Для получения списка полей смарт-процесса используется метод getFieldsCollection, он возвращает экземпляр Bitrix\Crm\Field\Collection с описанием всех полей элемента смарт-процесса

// ...$factory

$fieldsCollection = $factory->getFieldsCollection();

foreach ($fieldsCollection as $field)
{
    /**
     * @var $field \Bitrix\Crm\Field
     * 
     * $field->getTitle()
     * $field->getName()
     */
}

Поиск элементов

Для поиска элементов в каждой фабрике существуют методы getItems и getItemsFilteredByPermissions, которые отождествляют собой прямой доступ к элементам и доступ с учетом прав пользователя.

Прямой поиск

Метод getItems, по параметрам аналогичен ORM методу getList, однако вместо массива массивов, возвращает массив объектов (Bitrix\Crm\Item\Dynamic).

Например: найдем все элементы исходного смарт-процесса, которые содержат букву “a”


$elementsWithA = $factory->getItems([
    'filter' => [
        '%TITLE' => 'a'
    ]
]);

foreach ($elementsWithA as $element)
{
    echo $element->getTitle();
}

С учетом прав

Для поиска элементов смарт-процесса с учетом прав необходимо использовать метод getItemsFilteredByPermissions, который принимает следующие параметры:

  • $parameters - массив, аналогичный getList
  • $userId - идентификатор текущего пользователя (если не передан - будет учитываться текущий)
  • $operation - уровень прав, который проверяется (по-умолчанию чтение)

Например: найдем все элементы исходного смарт-процесса, которые содержат букву “B” доступных пользователю ID:123


$elementsWithA = $factory->getItemsFilteredByPermissions(
    [
        'filter' => [
            '%TITLE' => 'B'
        ]
    ],
    123
);

foreach ($elementsWithA as $element)
{
    echo $element->getTitle();
}

Операции

В этом разделе изложена справочная информация по низкоуровневым возможностям системы. Если вам необходимо выполнить создание/обновление (сохранение), удаление или конвертацию элемента воспользуйтесь операциями. Некоторый код расположенный ниже не удовлетворяет критериям:

  • Прозрачности (вы не сможете отследить все места и доп.действия с элементом)
  • Расширяемости (вы не сможете быстро переопределить или дополнить доп.действиями)
  • Консистентности (код ниже не гарантирует корректную работу системы в некоторых частях (поиск, права, таймлайн и т.п.))

Сохранение

Прочитайте примечание к разделу ‘Операция’ прежде чем продолжить чтение.

Оба совершаемых действия (созданию и обновлению) над элементом в объектном подходе обеспечивается методом save, который вызывается на объекте-наследнике Bitrix\Crm\Item, отсюда следует что каждое действие можно провести как минимум 2 путями помимо указанных выше операций.

Вариант с низкоуровневым созданием элемента смарт-процесса:

$item = $factory->getItemByEntityObject(
    $factory->getDataClass()::createObject()
);

$item->setTitle('My first element');
// Setup other fields with $item->set* methods

$saveResult = $item->save();

if ( $saveResult->isSuccess() )
{
    /**
     * Success result
     * $item->getId();
     */
}
else
{
    /**
     * Some errors
     * Get error with:
     * $saveResult->getErrors();
     *
     * Get error messages:
     * $saveResult->getErrorMessages();
     */
}

Почему данный вариант не подходит для использования разработчиком? Это самое низкоуровневое сохранение элемента, в котором не происходит следующих действий:

  1. Установка значений по-умолчанию
  2. Проверки прав
  3. Установки связей
  4. Отправки push уведомлений
  5. Запуска бизнес-процессов и автоматизаций
  6. Перерасчета прав
  7. Обновление поискового индекса
  8. Учета статистики
  9. Формирования timeline

Вариант с более продвинутым созданием объекта:

$initialFields = [
    'TITLE' => 'My first element'
];

$item = $factory->createItem($initialFields);

// Setup other fields with $item->set* methods

$saveResult = $item->save();

if ( $saveResult->isSuccess() )
{
    /**
     * Success result
     * $item->getId();
     */
}
else
{
    /**
     * Some errors
     * Get error with:
     * $saveResult->getErrors();
     *
     * Get error messages:
     * $saveResult->getErrorMessages();
     */
}

Почему данный вариант не подходит для использования разработчиком? Это самое низкоуровневое сохранение элемента, в котором не происходит следующих действий:

  1. Установка значений по-умолчанию
  2. Проверки прав
  3. Установки связей
  4. Отправки push уведомлений
  5. Запуска бизнес-процессов и автоматизаций
  6. Перерасчета прав
  7. Обновление поискового индекса
  8. Учета статистики
  9. Формирования timeline

Рекомендуемый вариант с использованием операций:

$initialFields = [
    'TITLE' => 'My first element'
];

$item = $factory->createItem($initialFields);

// Setup other fields with $item->set* methods

$saveOperation = $factory->getAddOperation($item);

$operationResult = $saveOperation->launch();

if ( $operationResult->isSuccess() )
{
    /**
     * Operation success!
     */
}
else
{
    /**
     * Some errors
     * Get error with:
     * $operationResult->getErrors();
     *
     * Get error messages:
     * $operationResult->getErrorMessages();
     */
}

Использование операций это рекомендуемый способ по сохранению элемента в полном объеме. Указанная операция создает элемент, для обновления элемента необходимо получить операцию редактирования (getUpdateOperation).

Удаление

Прочитайте примечание к разделу ‘Операция’ прежде чем продолжить чтение.

Существует несколько способов удаления элемента: низкоуровневый delete и операция по удалению элемента.

Вариант с прямым удалением элемент:

/**
 * @item instanceof Bitrix\Crm\Item
 */

$deleteResult = $item->delete();

if ( $deleteResult->isSuccess() )
{
    /**
     * Item deleted
     */
}
else
{
     /**
     * Some errors
     * Get error with:
     * $deleteResult->getErrors();
     *
     * Get error messages:
     * $deleteResult->getErrorMessages();
     */
}

Почему данный вариант не подходит для использования разработчиком? Несмотря на то что элемент смарт-процесса фактически удаляется, согласованность данных не обеспечивается, а это значит что не происходит следующих действий:

  1. Очистки товарных позиций
  2. Очистки записей о правах
  3. Очистка связей с событиями
  4. Очистки действий
  5. Очистки связей с чатами
  6. Очистки счетчиков и т.д.

Рекомендуемый вариант с использованием операций:

/**
 * @item instanceof Bitrix\Crm\Item
 */

$deleteOperation = $factory->getDeleteOperation($item);

$operationResult = $deleteOperation->launch();

if ( $operationResult->isSuccess() )
{
    /**
     * Operation success!
     */
}
else
{
    /**
     * Some errors
     * Get error with:
     * $operationResult->getErrors();
     *
     * Get error messages:
     * $operationResult->getErrorMessages();
     */
}

Использование операций это рекомендуемый способ по корректному удалению элемента.