Если некоторый код используется довольно часто и на разных проектах, имеет смысл его вынести в отдельный модуль. Не редко для работы модуля используются инфоблоки, которые существенно упрощают работу с данными. Чтобы установка модуля была довольно простой, удобно создавать инфоблоки в момент установки модуля. Для этого создаётся полная сборка модуля, которая может программно выполнять нужные операции с данными в момент установки.
Основной файл с описанием установки модуля находится в папке install модуля:
/install/index.php
Файл содержит класс, в котором есть методы DoInstall() а так же DoUninstall(). Каждый из этих методов вызывается в свою очередь когда производится установка либо удаление модуля. Таким образом, мы можем создать дополнительные методы, которые будут выполнять создание инфоблока, и других данных, и вызываться этот метод будет в DoInstall(). Аналогично и с удалением данных, через метод DoUninstall().
Для примера, создадим инфоблок с кодом custom_iblock_type.
public function AddIblockType(){
global $DB;
CModule::IncludeModule("iblock");
// код для типа инфоблоков
$iblockTypeCode = 'custom_iblock_type';
// проверяем на уникальность
$db_iblock_type = CIBlockType::GetList(
Array("SORT" => "ASC"),
Array("ID" => $iblockTypeCode)
);
// если его нет - создаём
if (!$ar_iblock_type = $db_iblock_type->Fetch()){
$obBlocktype = new CIBlockType;
$DB->StartTransaction();
// массив полей для нового типа инфоблоков
$arIBType = Array(
'ID' => $iblockTypeCode,
'SECTIONS' => 'Y',
'IN_RSS' => 'N',
'SORT' => 500,
'LANG' => Array(
'en' => Array(
'NAME' => GetMessage("IB_TYPE_NAME"),
),
'ru' => Array(
'NAME' => GetMessage("IB_TYPE_NAME"),
)
)
);
// создаём новый тип для инфоблоков
$resIBT = $obBlocktype->Add($arIBType);
if (!$resIBT){
$DB->Rollback();
echo 'Error: '.$obBlocktype->LAST_ERROR;
die();
} else {
$DB->Commit();
}
} else {
return false;
}
return $arIBType;
}
Вызов метода addIblockType() следует выполнить в методе DoInstall().
$this->AddIblockType();
Таким образом, будет произведено создание нового типа инфоблоков.
Вызов этого метода так же следует прописать в методе DoInstall(), и стоит обратить внимание что эта операция должна идти уже после того, как был создан новый тип инфоблока с кодом custom_iblock_type.
<?
// функция для создания инфоблока
public function AddIblock(){
CModule::IncludeModule("iblock");
$iblockCode = 'my_custom_ib_code'; // символьный код для инфоблока
$iblockType = 'custom_iblock_type'; // код типа инфоблоков
$ib = new CIBlock;
// проверка на уникальность
$resIBE = CIBlock::GetList(
Array(),
Array(
'TYPE' => $iblockType,
"CODE" => $iblockCode
)
);
if ($ar_resIBE = $resIBE->Fetch()){
return false;
} else {
$arFieldsIB = Array(
"ACTIVE" => "Y",
"NAME" => 'Название инфоблока',
"CODE" => $iblockCode,
"IBLOCK_TYPE_ID" => $iblockType,
"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" => "-"
)
)
)
);
return $ib->Add($arFieldsIB);
}
}
На этом этапе, мы уже создали тип инфоблока, а также сам инфоблок. В такой же логической последовательности мы теперь можем создать свойство для нашего инфоблока.
При создании свойства необходимо передать IBLOCK_ID инфоблока, который был недавно создан. Так программно свойство будет привязано к конкретному информационному блоку.
public function AddProp($IBLOCK_ID){
CModule::IncludeModule("iblock");
// массив полей для нового свойства
$arFieldsProp = Array(
"NAME" => GetMessage("MY_IBLOCK_PROP"),
"ACTIVE" => "Y",
"SORT" => "100",
"MULTIPLE" => "Y",
"CODE" => "PROP",
"PROPERTY_TYPE" => "S",
"USER_TYPE" => "UserID",
"IBLOCK_ID" => $IBLOCK_ID
);
$ibp = new CIBlockProperty;
// создаём свойство
$propID = $ibp->Add($arFieldsProp);
return $propID;
}
В DoInstall() вызов метода будет выглядеть следующим образом:
public function DoInstall(){
global $APPLICATION;
$this->AddIblockType();
$IBLOCK_ID = $this->AddIblock();
$this->AddProp($IBLOCK_ID);
}
Разумеется, вы можете оформить функции по-своему, так, чтобы вам было более удобно создавать множество свойств и инфоблоков. Здесь код указан исключительно для примера. Как мы знаем, модуль должен уметь как создавать инфоблоки, так и удалять все данные за собой.
В этом случае достаточно удалить тип информационного блока, при удалении которого, автоматом удалятся так же всё содержимое этого типа инфоблоков. Вызывать этот метод следует в методе DoUninstall().
// удаление данных инфоблоков
public 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();
}
Когда мы производим удаление модуля из админ-части, автоматом будет вызван метод DoUninstall(), в котором и следует обратиться к методу DelIblocks().
public function DoUninstall(){
$this->DelIblocks();
}
Метод может обращаться и к другим функциям, которые к примеру, выполняют какие-либо операции с файлами.
В заключении хотелось бы отметить подводные камни при создании данных. В методе мы прописываем символьные коды, которые будут использоваться при создании типа инфоблока. Может возникнуть ситуация что данный тип уже существует. Поэтому в некотором роде это может вызвать проблемы при создании.
Ты где-то $arFieldsIB потерял в создании инфоблока
Точно, спасибо, исправил.
Undefined variable '$iblockType'
public function AddIblockType(){ global $DB; CModule::IncludeModule("iblock"); // код для типа инфоблоков $iblockTypeCode = 'custom_iblock_type'; // проверяем на уникальность $db_iblock_type = CIBlockType::GetList( Array("SORT" => "ASC"), Array("ID" => $iblockTypeCode) ); // если его нет - создаём if (!$ar_iblock_type = $db_iblock_type->Fetch()){ $obBlocktype = new CIBlockType; $DB->StartTransaction(); // массив полей для нового типа инфоблоков $arIBType = Array( 'ID' => $iblockTypeCode, 'SECTIONS' => 'Y', 'IN_RSS' => 'N', 'SORT' => 500, 'LANG' => Array( 'en' => Array( 'NAME' => GetMessage("IB_TYPE_NAME"), ), 'ru' => Array( 'NAME' => GetMessage("IB_TYPE_NAME"), ) ) ); // создаём новый тип для инфоблоков $resIBT = $obBlocktype->Add($arIBType); if (!$resIBT){ $DB->Rollback(); echo 'Error: '.$obBlocktype->LAST_ERROR; die(); } else { $DB->Commit(); } } else { return false; } return $iblockType; }Спасибо, подправил, на return $iblockType; в конце функции