Битрикс КП. Копирование универсальных списков и бизнес-процессов
25.08.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::AddField().
Кстати, для получения значений свойства типа листинг использую обычную CIBlockProperty::GetPropertyEnum(). Так как у меня не было задачи обрабатывать что-то кроме строк и листинга, то остальные типы специально я не обрабатываю (такие как файл или картинка; пример обработки можно найти в коде детишек класса CList, где-то я там это видела).
На этот раз в публичке свойства появляются, и мы переходим к решению задачи копирования БП, привязанных к УС.
Копирование бизнес-процессов
Первым делом гугление приводит меня к теме
Поэтому идём "опасным" способом из темы - непосредственным тыканием базы данных. Да, можете меня расстреливать, но я была ограничена по времени исполнения задачи, поэтому попёрла напролом. Да и задача не самая стандартная.
Создаём ручками БП и смотрим что изменилось в таблице b_bp_workflow_template: добавилась строка, где поле ENTITY установлено в CIBlockDocument, а поле DOCUMENT_TYPE имеет значение iblock_#ID#, где #ID# - айдишка УС, где создавался БП.
Возвращаемся к инструменту копирования. На третьем шаге добавляем чекбокс "копировать также БП списка".
К стратегии добавляем пункты
-
1. выясняем какие БП привязаны к УС
2. копируем строку в таблице, переназначая DOCUMENT_TYPE для свежесозданного УС
Ссылки
6031