пятница, 22 августа 2014 г.

Битрикс КП. Копирование универсальных списков и бизнес-процессов.

Прикатило мне очередное интересное задание от насяльникама. Необходимо написать инструмент, позволяющий копировать универсальные списки для социальных групп (без контента, только схему). А также и бизнес-процессы принадлежащие этому списку.
Хто здесь? 0_0
Прикинуться куском обоев не получилось, поэтому пришлось делать. И писать статью, иначе я всё забуду.

Сегодня на обсуждении:
  1. копирование универсальных списков для социальных групп
  2. копирование бизнес-процессов этих списков
Обсуждаемый инструмент можно найти в конце статьи. Правда, вы сами должны понимать, что за сотворённое вами с его помощью я ответственности не несу =)

Далее:
  • БП - бизнес-процесс
  • УС - универсальный список (в рамках статьи подразумеваются УС для социальных групп)
  • ИБ - инфоблок
  • КП - корпоративный портал
  • СГ - социальная группа

Что такое УС?

Во-первых, чтобы понять что именно от меня хотят, мне понадобилось некоторое время. КП вообще для меня пока такие дебри =)
Дабы показать работу мысли, буду описывать всё как было.

Сначала выпрашиваем у админа тестовый  адресочек и ставим там КП с наполнением.
Потом пытаемся узнать, что такое УС. Потыкав админку, я поняла, что это тупо инфоблок и что работать с ним можно как с инфоблоком определённого типа. На копирование БП пока забиваем, приоритет был поставлен на списки.
На тестовой странице получаем список всех ИБ,  понимаем что тип УС для социальных групп - это lists_socnet. Заодно замечаем присутствие поля SOCNET_GROUP_ID, значение которого равно айдишке СГ; логично, правда?

Пробую создать для определённой СГ инфоблок стандартной привычной нам функцией CIBlock::Add(). Получаю созданный УС, который показывается в паблике СГ на редактирование. А уж создание свойств ручками - это потом, уже непосредственно в инструменте.


Окрылённая успехом, начинаю создавать сам инструмент. Как по-человечески работать с формами я уже не помню, поэтому всё на аджаксе.

Планирование шагов инструмента


Первый шаг - получение списка СГ. Из них пользователь выбирает ту группу, из которой надо будет скопировать УС. Делается это функцией CSocNetGroup::GetList() модуля socialnetwork.

Второй шаг - получение УС для указанной на первом шаге группы. Делается это стандартной бля инфоблоков функцией с настроенным фильтром.
CIBlock::GetList(false, array('IBLOCK_TYPE_ID' => 'lists_socnet', 'SOCNET_GROUP_ID' => $chosen_id));

На третьем шаге опять показываем список СГ, только с возможностью множественного выбора. Пользователь отмечает те группы, куда надо склонировать указанный на втором шаге УС.

Дальнейшая стратегия вполне логична:
  1. получаем список полей и свойств УС
  2. для каждой указанной на третьем шаге СГ создаём инфоблок-УС
  3. для каждого созданного УС создаём такие же свойства как у исходного списка с помощью обычного для инфоблоков класса работы со свойствами CIBlockProperty
  4. на каждом шаге логгируем действия, чтобы потом красиво показать последовательность действий =)

CList

Реализуем, запускаем, смотрим в админку - все красиво создалось, и радостно потираем лапки. Теперь лезем в публичку и понимаем, что свойства для УС там не показываются.

Начинаю археологические раскопки. Находится класс CList с кучей детишек. Матерюсь изысканными ругательствами, смотрю как происходит работа со списками.
А принципиально происходит то же самое, что и при работе с инфоблоками, только со своей надстройкой, прописывающей свои финтифлюшки в базу. Обсуждать зачем это сделано я сейчас не буду, хотя очень интересно. На мои жалобы по этому поводу коллега Максим сказал: "видимо, это сделано для решения неочевидных нам задач".  На что получил ответ, что в битриксе эту фразу можно применить практически к любому решению =)

Итого после разбирательств меняю код пункта три из стратегии: для создания свойств использую CList::AddField().
Кстати, для получения значений свойства типа листинг использую обычную CIBlockProperty::GetPropertyEnum(). Так как у меня не было задачи обрабатывать что-то кроме строк и листинга, то остальные типы специально я не обрабатываю (такие как файл или картинка; пример обработки можно найти в коде детишек класса CList, где-то я там это видела).

На этот раз в публичке свойства появляются, и мы переходим к решению задачи копирования БП, привязанных к УС.

Копирование бизнес-процессов

Первым делом гугление приводит меня к теме Копирование бизнес-процессов полностью и отдельных элементов. Тема с экспортом мне не нравится, мудрёно, да и для сотни УС делать экспорт ручками грустно, а программно - это разбираться ещё пару дней =) Подсказка куда двигаться честным способом: есть CBPWorkflowTemplateLoader::GetList(),но разбираться очень не хотелось. 

Поэтому идём "опасным" способом из темы - непосредственным тыканием базы данных. Да, можете меня расстреливать, но я была ограничена по времени исполнения задачи, поэтому попёрла напролом. Да и задача не самая стандартная.

Создаём ручками БП и смотрим что изменилось в таблице b_bp_workflow_template: добавилась строка, где поле ENTITY установлено в CIBlockDocument, а поле DOCUMENT_TYPE имеет значение iblock_#ID#, где #ID# - айдишка УС, где создавался БП.

Возвращаемся к инструменту копирования. На третьем шаге добавляем чекбокс "копировать также БП списка".

К стратегии добавляем пункты
  1. выясняем какие БП привязаны к УС
  2. копируем строку в таблице, переназначая DOCUMENT_TYPE для свежесозданного УС

В итоге получили инструмент-франкенштейн. Работает =)

 

Ссылки

Копирование бизнес-процессов полностью и отдельных элементов...
Инструмент копирования (zip) у меня лежал прямо в корне с доступом для админов


Комментариев нет:

Отправить комментарий