Создание простого компонента в d7
Готовый код можно скачать в моем репозитории на GitFlic. Что меняется при использовании нового ядра d7? Весь набор файлов остается прежним, добавляется только файл class.php
, в котором и будет располагаться вся логика.
Работа файла class.php
Файл подключается автоматически, в нем необходимо объявить класс с произвольным именем, как класс наследник от CBitrixComponent. Пример объявления класса:
class CIblocList extends CBitrixComponent {
}
В этом классе уже доступны две переменные (объявлять их не нужно):
$this->arParams
$this->arResult
И предопределенные методы, которые срабатывают автоматически, а ызываются в порядке следования:
onPrepareComponentParams(); // обработка массива $arParams
onIncludeComponentLang(); // подключение языковых файлов
executeComponent(); // аналог конструктора
В своем компоненте я разместил следующий код в методе executeComponent()
:
public function executeComponent()
{
try {
$this->checkModules();
$this->getResult();
}
catch (SystemException $e) {
ShowError($e->getMessage());
}
}
- $this->checkModules() - мы проверяем подключен ли модуль Инфоблоков Битрикс
- $this->getResult() - подготавливаем массив $arResult и подключаем шаблон. Это основной блок кода
Это уже не огромная простыня кода, где ещё надо самостоятельно делить на блоки код чтобы начать что-то понимать. Все вполне наглядно и помещается в один экран:
.description.php
glavnyj.slajder/.description.php<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
$arComponentDescription = array(
// название компонента
'NAME' => 'Главный слайдер на странице',
// описание компонента
'DESCRIPTION' => 'Выводит главный слайдер в шапке страницы',
// путь к иконке компонента относительно папки компонента
'ICON' => '/images/eaddlist.gif',
// показывать кнопку очистки кеша
'CACHE_PATH' => 'Y',
// порядок сортировки в визуальном редакторе
'SORT' => 30,
// признак комплексного компонента
'COMPLEX' => 'N',
// расположение компонента в визуальном редакторе
'PATH' => array(
// идентификатор верхнего уровеня в редакторе
'ID' => 'slajder',
// название верхнего уровня в редакторе
'NAME' => 'Слайдеры',
// в элементе может быть задана подчиненная ветка дерева с той же структурой, что и родительская ветка
'CHILD' => '',
)
);
.parameters.php
glavnyj.slajder/.parameters.php<?
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
// проверяем установку модуля «Информационные блоки»
if (!CModule::IncludeModule('iblock')) {
return;
}
// получаем массив всех типов инфоблоков для возможности выбора
$arIBlockType = CIBlockParameters::GetIBlockTypes();
// пустой массив для вывода
$arInfoBlocks = array();
// выбираем активные инфоблоки
$arFilterInfoBlocks = array('ACTIVE' => 'Y');
// сортируем по озрастанию поля сортировка
$arOrderInfoBlocks = array('SORT' => 'ASC');
// если уже выбран тип инфоблока, выбираем инфоблоки только этого типа
if (!empty($arCurrentValues['IBLOCK_TYPE'])) {
$arFilterInfoBlocks['TYPE'] = $arCurrentValues['IBLOCK_TYPE'];
}
// метод выборки информационных блоков
$rsIBlock = CIBlock::GetList($arOrderInfoBlocks, $arFilterInfoBlocks);
// перебираем и выводим в адмику доступные информационные блоки
while ($obIBlock = $rsIBlock->Fetch()) {
$arInfoBlocks[$obIBlock['ID']] = '[' . $obIBlock['ID'] . '] ' . $obIBlock['NAME'];
}
// настройки компонента, формируем массив $arParams
$arComponentParameters = array(
// название кастомной группы не обязательный параметр
"GROUPS" => array(
"TEST" => array(
"NAME" => 'Тест'
),
),
// основной массив с параметрами
'PARAMETERS' => array(
// выбор типа инфоблока
'IBLOCK_TYPE' => array( // ключ массива $arParams в component.php
'PARENT' => 'TEST', // название группы
'NAME' => 'Выберите тип инфоблока', // название параметра
'TYPE' => 'LIST', // тип элемента управления, в котором будет устанавливаться параметр
'VALUES' => $arIBlockType, // входные значения
'REFRESH' => 'Y', // перегружать настройки или нет после выбора (N/Y)
'DEFAULT' => 'news', // значение по умолчанию
'MULTIPLE' => 'N', // одиночное/множественное значение (N/Y)
),
// выбор самого инфоблока
'IBLOCK_ID' => array(
'PARENT' => 'BASE',
'NAME' => 'Выберите родительский инфоблок',
'TYPE' => 'LIST',
'VALUES' => $arInfoBlocks,
'REFRESH' => 'Y',
"DEFAULT" => '',
"ADDITIONAL_VALUES" => "Y",
),
// настройки кэширования
'CACHE_TIME' => array(
'DEFAULT' => 3600
),
),
);
class.php
glavnyj.slajder/class.php<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
// класс для работы с языковыми файлами
use Bitrix\Main\Localization\Loc;
// класс для всех исключений в системе
use Bitrix\Main\SystemException;
// класс для загрузки необходимых файлов, классов, модулей
use Bitrix\Main\Loader;
// основной класс, является оболочкой компонента унаследованного от CBitrixComponent
class CIblocList extends CBitrixComponent
{
// выполняет основной код компонента, аналог конструктора (метод подключается автоматически)
public function executeComponent()
{
try {
// подключаем метод проверки подключения модуля «Информационные блоки»
$this->checkModules();
// подключаем метод подготовки массива $arResult
$this->getResult();
} catch (SystemException $e) {
ShowError($e->getMessage());
}
}
// подключение языковых файлов (метод подключается автоматически)
public function onIncludeComponentLang()
{
Loc::loadMessages(__FILE__);
}
// проверяем установку модуля «Информационные блоки» (метод подключается внутри класса try...catch)
protected function checkModules()
{
// если модуль не подключен
if (!Loader::includeModule('iblock'))
// выводим сообщение в catch
throw new SystemException(Loc::getMessage('IBLOCK_MODULE_NOT_INSTALLED'));
}
// обработка массива $arParams (метод подключается автоматически)
public function onPrepareComponentParams($arParams)
{
// время кеширования
if (!isset($arParams['CACHE_TIME'])) {
$arParams['CACHE_TIME'] = 3600;
} else {
$arParams['CACHE_TIME'] = intval($arParams['CACHE_TIME']);
}
// возвращаем в метод новый массив $arParams
return $arParams;
}
// подготовка массива $arResult (метод подключается внутри класса try...catch)
protected function getResult()
{
// если нет валидного кеша, получаем данные из БД
if ($this->startResultCache()) {
// Запрос к инфоблоку через класс ORM
$res = \Bitrix\Iblock\Elements\ElementSlajderglavnyjTable::getList([
'select' => ["ID", "NAME", "IBLOCK_ID", "ID_2_ZAGOLOVOK_" => "ID_2_ZAGOLOVOK", "ID_2_TEXT_" => "ID_2_TEXT", "ID_2_ZAGOLOVOKHOVER_" => "ID_2_ZAGOLOVOKHOVER", "ID_2_TEXTHOVER_" => "ID_2_TEXTHOVER", "ID_2_KARTINKA_" => "ID_2_KARTINKA", "ID_2_HREF_" => "ID_2_HREF", "PREVIEW_PICTURE"],
"filter" => ["ACTIVE" => "Y"],
"order" => ["SORT" => "ASC"]
]);
// Формируем массив arResult
while ($arItem = $res->fetch()) {
$arItem["PREVIEW_PICTURE"] = CFile::GetFileArray($arItem["PREVIEW_PICTURE"]);
$arItem["ID_2_KARTINKA_VALUE"] = CFile::GetFileArray($arItem["ID_2_KARTINKA_VALUE"]);
$this->arResult[] = $arItem;
}
// кэш не затронет весь код ниже, он будут выполняться на каждом хите, здесь работаем с другим $arResult, будут доступны только те ключи массива, которые перечислены в вызове SetResultCacheKeys()
if (isset($this->arResult)) {
// ключи $arResult перечисленные при вызове этого метода, будут доступны в component_epilog.php и ниже по коду, обратите внимание там будет другой $arResult
$this->SetResultCacheKeys(
array()
);
// подключаем шаблон и сохраняем кеш
$this->IncludeComponentTemplate();
} else { // если выяснилось что кешировать данные не требуется, прерываем кеширование и выдаем сообщение «Страница не найдена»
$this->AbortResultCache();
\Bitrix\Iblock\Component\Tools::process404(
Loc::getMessage('PAGE_NOT_FOUND'),
true,
true
);
}
}
}
}
template.php
glavnyj.slajder/template/.default/template.php<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); ?>
<section>
<div class="container product_slider">
<div class="swiper mySwiper4">
<div class="swiper-wrapper">
<? foreach ($arResult as $arElement) : ?>
<?
// ссылки для экшенов и название кнопки
$arButtons = CIBlock::GetPanelButtons(
// идентификатор инфоблока, которому принадлежит элемент
$arElement["IBLOCK_ID"],
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// идентификатор раздела инфоблока (при наличии)
0,
// массив, содержащий локализацию названий
array("SECTION_BUTTONS" => false, "SESSID" => false)
);
// экшен изменения элемента
$this->AddEditAction(
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// ссылка из $arButtons на изменение эллемента
$arButtons["edit"]["edit_element"]["ACTION_URL"],
// название кнопки
$arButtons["edit"]["edit_element"]["TEXT"]
);
// экшен добавления элемента
$this->AddEditAction(
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// ссылка из $arButtons на изменение эллемента
$arButtons["edit"]["add_element"]["ACTION_URL"],
// название кнопки
$arButtons["edit"]["add_element"]["TEXT"]
);
// экшен удаления элемента
$this->AddDeleteAction(
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// ссылка из $arButtons на изменение эллемента
$arButtons["edit"]["delete_element"]["ACTION_URL"],
// название кнопки
$arButtons["edit"]["delete_element"]["TEXT"],
array("CONFIRM" => "Удалить?")
); ?>
<?
// проверка на администратора для вывода экшенов
if ($USER->IsAdmin() && $APPLICATION->GetShowIncludeAreas()) {
echo '<div class="swiper-slide" id="' . $this->GetEditAreaId($arElement["ID"]) . '">';
} else {
echo '<div class="swiper-slide">';
} ?>
<div class="product">
<div class="item">
<div class="row">
<div class="col-8 title"><?= $arElement["ID_2_ZAGOLOVOK_VALUE"] ?></div>
<div class="col-4 image"><img src="<?= "/local/templates/hmarketing/img/svg/icons/" . preg_replace('#[a-z]{3,4}$#', 'svg', $arElement["PREVIEW_PICTURE"]["ORIGINAL_NAME"], 1) ?>" alt="<?= $arElement["PREVIEW_PICTURE"]["DESCRIPTION"] ?>" width="40" height="40"></div>
<div class="col-12 tekst"><?= $arElement["ID_2_TEXT_VALUE"] ?></div>
<div class="col-12 button">Узнать больше<span class="icon-arrow-right"></div>
</div>
</div>
<div class="hover swiper-lazy" data-background="<?= $arElement["ID_2_KARTINKA_VALUE"]["SRC"] ?>">
<div class="row">
<div class="col-12 title"><?= $arElement["ID_2_ZAGOLOVOKHOVER_VALUE"] ?></div>
<div class="col-12 tekst"><?= $arElement["ID_2_TEXTHOVER_VALUE"] ?></div>
<div class="col-12 button"><a href="<?= $arElement["ID_2_HREF_VALUE"] ?>">Жми подробнее... <span class="icon-arrow-right"></span></a></div>
</div>
</div>
</div>
<? echo '</div>'; ?>
<? endforeach ?>
</div>
<div class="slider-nav">
<div class="swiper-prev"></div>
<div class="swiper-indicators"></div>
<div class="swiper-next"></div>
</div>
</div>
</div>
</section>