Создание инфоблоков при создании модуля
Зачастую в своих решениях я использую инфоблоки. Это вообще мощный и полезный инструмент, думаю не в последнюю очередь именно ради таких абстракций, люди и используют CMS.
Очень часто в инфоблоках требуются какие-то специфичные свойства или настройки, или же просто надо как-то логически отделить свои инфоблоки от чужих, поэтому я создаю себе свои при установке модуля. К тому же это упрощает первичную настройку модуля для администратора сайта.
Как несложно догадаться, мы просто вызываем необходимые функции в DoInstall и DoUninstall. Ниже я приведу код используемых мною функций и пример их вызова.
Создание типа инфоблока
function AddIblockType($arFieldsIBT){ global $DB; CModule::IncludeModule("iblock"); $iblockType = $arFieldsIBT["ID"]; // Работа с типом инфоблока // проверяем наличие нужного типа инфоблока $db_iblock_type = CIBlockType::GetList(Array("SORT" => "ASC"), Array("ID" => $iblockType)); // если его нет - создаём if (!$ar_iblock_type = $db_iblock_type->Fetch()){ $obBlocktype = new CIBlockType; $DB->StartTransaction(); $resIBT = $obBlocktype->Add($arFieldsIBT); if (!$resIBT){ $DB->Rollback(); echo 'Error: '.$obBlocktype->LAST_ERROR.'
'; die(); }else{ $DB->Commit(); } }else{ return false; } return $iblockType; }
Создание инфоблока
// функция добавления инфоблока function AddIblock($arFieldsIB){ CModule::IncludeModule("iblock"); $iblockCode = $arFieldsIB["CODE"]; $iblockType = $arFieldsIB["TYPE"]; $ib = new CIBlock; // проверка на наличие создание/обновление $resIBE = CIBlock::GetList(Array(), Array('TYPE' => $iblockType, "CODE" => $iblockCode)); if ($ar_resIBE = $resIBE->Fetch()){ return false; // желаемый код занят }else{ $ID = $ib->Add($arFieldsIB); $iblockID = $ID; } return $iblockID; }
Создание свойства инфоблока
function AddProp($arFieldsProp){ CModule::IncludeModule("iblock"); $ibp = new CIBlockProperty; $propID = $ibp->Add($arFieldsProp); return $propID; }
Пример вызова
private function CreateIblocks(){ // для типа инфоблоков $arFieldsForType = Array( 'ID' => $this->IBLOCK_TYPE, 'SECTIONS' => 'Y', 'IN_RSS' => 'N', 'SORT' => 500, 'LANG' => Array( 'en' => Array( 'NAME' => 'vtest', ), 'ru' => Array( 'NAME' => GetMessage("VTEST_IBLOCK_TYPE_NAME"), ) ) ); // если создали тип инфоблока, создаём инфоблоки if ($this->AddIblockType($arFieldsForType)){ $arFieldsForIblock = Array( "ACTIVE" => "Y", "NAME" => GetMessage("VTEST_IBLOCK_NAME"), "CODE" => "vtest", "IBLOCK_TYPE_ID" => $arFieldsForType["ID"], "SITE_ID" => "s1", "GROUP_ID" => Array("2" => "R"), "FIELDS" => Array( "CODE" => Array( "IS_REQUIRED" => "Y", "DEFAULT_VALUE" => Array( "TRANS_CASE" => "L", "UNIQUE" => "Y", "TRANSLITERATION" => "Y", "TRANS_SPACE" => "-", "TRANS_OTHER" => "-" ) ) ) ); // если создали инфоблок, можем создать ему свойства if ($iblockID = $this->AddIblock($arFieldsForIblock)){ $arFieldsProp = Array( "NAME" => GetMessage("VTEST_IBLOCK_PROP"), "ACTIVE" => "Y", "SORT" => "100", "MULTIPLE" => "Y", "CODE" => "PROP", "PROPERTY_TYPE" => "S", "USER_TYPE" => "UserID", "IBLOCK_ID" => $iblockID ); $this->AddProp($arFieldsProp); }else{ CAdminMessage::ShowMessage(Array( "TYPE" => "ERROR", "MESSAGE" => GetMessage("VTEST_IBLOCK_NOT_INSTALLED"), "DETAILS" => "", "HTML" => true )); } }else{ CAdminMessage::ShowMessage(Array( "TYPE" => "ERROR", "MESSAGE" => GetMessage("VTEST_IBLOCK_TYPE_NOT_INSTALLED"), "DETAILS" => "", "HTML" => true )); } }
Для удаления достаточно удалить тип инфоблока, который можно зашить в код или записать в свойство модуля. Код будет выглядеть так:
function DelIblocks(){ global $DB; CModule::IncludeModule("iblock"); $DB->StartTransaction(); if (!CIBlockType::Delete($this->IBLOCK_TYPE)){ $DB->Rollback(); CAdminMessage::ShowMessage(Array( "TYPE" => "ERROR", "MESSAGE" => GetMessage("VTEST_IBLOCK_TYPE_DELETE_ERROR"), "DETAILS" => "", "HTML" => true )); } $DB->Commit(); }
Заключение
Это система была придумана мною и не сильно много дорабатывалась, если у вас есть предложения или замечания, я с радостью прочитаю их в комментариях.
Нерешённые проблемы
Конфликт кодов
Что если желаемый код занят? Сейчас я решил просто ничего не делать. Можно было бы предложить пользователю самому ввести имя или же в коде рекурсивно добавлять нижнее подчёркивание, но это не похоже на лучшее решение, ведь цель - упрощение жизни всем.
Комментарии
Дмитрий 04.10.2018 11:55
Анна 27.01.2019 15:33
А можно ли при установке модуля сразу добавлять и элементы в новый инфоблок?
попыталась создать функцию наподобие добавления свойств в инфоблок. Но почему-то не сработало(
function AddElement($arLoadProductArray){
global $DB;
CModule::IncludeModule("iblock");
$el = new CIBlockElement;
$elementId = $el->Add($arLoadProductArray);
return $elementId;
}
И затем в вызове там же, где вызывается функция добавления свойства, вызвала и добавление элемента
$arLoadProductArray = Array(
"MODIFIED_BY" => $GLOBALS['USER']->GetID(),
"IBLOCK_SECTION_ID" => false,
"IBLOCK_ID" => $iblockID,
"PROPERTY_VALUES"=> Array("KOD"=>"код"),
"NAME" => "Название",
"ACTIVE" => "N",
"PREVIEW_TEXT" => "текст анонса"
);
$this->AddElement($arLoadProductArray);
тип создается, инфоблок тоже, но не элемент
Василий 29.01.2019 10:17
Анна 29.01.2019 12:29
Забыла элементу символьный код прописать, а он по настройкам инфоблока обязателен, поэтому и не добавлялся