Битрикс. Создание простого компонента. Часть 2 из 2

28.08.2018

Теги: $arParams$arResult.description.php.parameters.phpCMSWeb-разработкаБитриксИнфоблокКомпонентШаблонКомпонента

Создадим еще один компонент, который выводит на странице несколько случайных элементов инфоблока. В настройках можно выбрать тип инфоблока и сам инфоблок, из которого будут выбраны случайные элементы. Практической ценности не имеет, сделан исключительно в целях изучения Битрикс.

Создаем директорию local/components/tokmakov/iblock.random, внутри нее создаем следующие папки и файлы:

  • папка templates
  • файл .description.php
  • файл .parameters.php
  • файл component.php
[local]
    [components]
        [tokmakov]
            [iblock.random]
                [templates]
                    [.default]
                        template.php
                        style.css
                .description.php
                .parameters.php
                component.php

Описание компонента:

<?php
/*
 * Файл local/components/tokmakov/iblock.random/.description.php
 */
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();

$arComponentDescription = array(
    'NAME' => 'Случайные элементы', // название компонента
    'DESCRIPTION' => 'Выводит несколько случайных элементов инфоблока',
    'ICON' => '/images/icon.gif', // иконка компонента относительно папки компонента
    'CACHE_PATH' => 'Y', // показывать кнопку очистки кеша
    'SORT' => 40, // порядок сортировки в визуальном редакторе
    'COMPLEX' => 'N', // признак комплексного компонента
    'PATH' => array( // расположение компонента в визуальном редакторе
        'ID' => 'other_components', // идентификатор верхнего уровеня в редакторе
        'NAME' => 'Прочие компоненты', // название верхнего уровня в редакторе
        'CHILD' => array( // второй уровень в визуальном редакторе
            'ID' => 'other_iblock', // идентификатор второго уровня в редакторе
            'NAME' => 'Информационный блок' // название второго уровня в редакторе
        )
    )
);

Настройки компонента:

<?php
/*
 * Файл local/components/tokmakov/iblock.random/.parameters.php
 */
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();

// проверяем, установлен ли модуль «Информационные блоки»; если да — то подключаем его
if (!CModule::IncludeModule('iblock')) {
    return;
}

/*
 * Получаем массив всех типов инфоблоков — для возможности выбора
 */
$arIBlockType = CIBlockParameters::GetIBlockTypes();

/*
 * Получаем массив инфоблоков — для возможности выбора; фильтруем их по
 * выбранному типу и по активности
 */
$arInfoBlocks = array();
$arFilter = array('ACTIVE' => 'Y');
// если уже выбран тип инфоблока, выбираем инфоблоки только этого типа
if (!empty($arCurrentValues['IBLOCK_TYPE'])) {
    $arFilter['TYPE'] = $arCurrentValues['IBLOCK_TYPE'];
}
$rsIBlock = CIBlock::GetList(
    array('SORT' => 'ASC'),
    $arFilter
);
while($iblock = $rsIBlock->Fetch()) {
    $arInfoBlocks[$iblock['ID']] = '['.$iblock['ID'].'] '.$iblock['NAME'];
}

/*
 * Настройки компонента
 */
$arComponentParameters = array(
    'PARAMETERS' => array(
        // выбор типа инфоблока
        'IBLOCK_TYPE' => array(
            'PARENT' => 'BASE',
            'NAME' => 'Выберите тип инфоблока',
            'TYPE' => 'LIST',
            'VALUES' => $arIBlockType,
            'REFRESH' => 'Y',
        ),
        // выбор самого инфоблока
        'IBLOCK_ID' => array(
            'PARENT' => 'BASE',
            'NAME' => 'Выберите инфоблок',
            'TYPE' => 'LIST',
            'VALUES' => $arInfoBlocks,
        ),

        'ELEMENT_COUNT' => array(
            'PARENT' => 'BASE',
            'NAME' => 'Количество случайных элементов',
            'TYPE' => 'STRING',
            'DEFAULT' => '4',
        ),

        // шаблон ссылки на страницу элемента
        'ELEMENT_URL' => array(
            'PARENT' => 'URL_TEMPLATES',
            'NAME' => 'URL, ведущий на страницу с содержимым элемента',
            'TYPE' => 'STRING',
            'DEFAULT' => '#SITE_DIR#/#IBLOCK_CODE#/item/id/#ELEMENT_ID#/'
        ),

        // настройки кэширования
        'CACHE_TIME'  =>  array(
            'DEFAULT'=>3600
        ),
    ),
);

Существуют особые параметры, которые стандартизованы и которые нет необходимости описывать полностью. Достаточно указать, что они есть. Например,

"SET_TITLE" => array(),
"CACHE_TIME" => array(),

Первый из указанных параметров указывает, следует ли компоненту установить заголовок страницы, а второй — все настройки, связанные с кешированием.

Исходный код компонента:

<?php
/*
 * Файл local/components/tokmakov/iblock.element/component.php
 */
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();

/** @var CBitrixComponent $this */
/** @var array $arParams */
/** @var array $arResult */
/** @var string $componentPath */
/** @var string $componentName */
/** @var string $componentTemplate */
/** @global CDatabase $DB */
/** @global CUser $USER */
/** @global CMain $APPLICATION */

if (!CModule::IncludeModule('iblock')) {
    ShowError('Модуль «Информационные блоки» не установлен');
    return;
}

if (!isset($arParams['CACHE_TIME'])) {
    $arParams['CACHE_TIME'] = 3600;
}

// тип инфоблока, откуда будем получать случайные элементы
$arParams['IBLOCK_TYPE'] = trim($arParams['IBLOCK_TYPE']);
// идентификатор инфоблока, откуда будем получать случайные элементы
$arParams['IBLOCK_ID'] = intval($arParams['IBLOCK_ID']);

// шаблон ссылки на страницу с содержимым элемента
$arParams['ELEMENT_URL'] = trim($arParams['ELEMENT_URL']);

// количество случаных элементов
$arParams['ELEMENT_COUNT'] = intval($arParams['ELEMENT_COUNT']);
if ($arParams['ELEMENT_COUNT'] <= 0) {
    $arParams['ELEMENT_COUNT'] = 4;
}

/*
 * На самом деле мы будем получать не один случайный набор элементов инфоблока, а
 * четыре разных набора, каждый из которых содержит случайные элементы. И каждый из
 * этих наборов сохраним в кеш. Так посетителю сайта будет казаться, что он видит
 * случайный набор элементов, а на самом деле это один из четырех закешированных
 * наборов.
 */ 
if ($this->StartResultCache(false, rand(1,4))) {

    /*
     * Получаем случайные элементы из БД, если их еще нет в кэше
     */

    // какие поля элементов выбираем
    $arSelect = array(
        'ID',
        'CODE',
        'IBLOCK_ID',
        'NAME',
        'PREVIEW_PICTURE',
        'DETAIL_PAGE_URL',
        'PREVIEW_TEXT',
        'PREVIEW_TEXT_TYPE',
        'SHOW_COUNTER'
    );

    // условия выборки элементов инфоблока
    $arFilter = array(
        'IBLOCK_ID' => $arParams['IBLOCK_ID'],
        'IBLOCK_ACTIVE' => 'Y',
        'ACTIVE' => 'Y',
        'ACTIVE_DATE' => 'Y'
    );
    // случайная сортировка
    $arSort = array(
        'RAND' => 'ASC',
    );
    // выбираем только несколько элементов
    $arLimit = array(
        'nTopCount' => $arParams['ELEMENT_COUNT']
    );
    // выполняем запрос к базе данных
    $rsElements = CIBlockElement::GetList(
        $arSort,
        $arFilter,
        false,
        $arLimit,
        $arSelect
    );

    // устанавливаем шаблон пути для элемента, вместо того, который
    // указан в настройках информационного блока
    $rsElements->SetUrlTemplates($arParams['ELEMENT_URL'], '');

    $arResult['ITEMS'] = array();
    while ($arItem = $rsElements->GetNext()) {

        // получаем SEO-свойства очередного элемента
        $ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues(
            $arItem['IBLOCK_ID'],
            $arItem['ID']
        );
        $arItem['IPROPERTY_VALUES'] = $ipropValues->getValues();

        $arItem['PREVIEW_PICTURE'] =
            (0 < $arItem['PREVIEW_PICTURE'] ? CFile::GetFileArray($arItem['PREVIEW_PICTURE']) : false);
        if ($arItem['PREVIEW_PICTURE']) {
            $arItem['PREVIEW_PICTURE']['ALT'] =
                $arItem['IPROPERTY_VALUES']['ELEMENT_PREVIEW_PICTURE_FILE_ALT'];
            if ($arItem['PREVIEW_PICTURE']['ALT'] == '') {
                $arItem['PREVIEW_PICTURE']['ALT'] = $arItem['NAME'];
            }
            $arItem['PREVIEW_PICTURE']['TITLE'] =
                $arItem['IPROPERTY_VALUES']['ELEMENT_PREVIEW_PICTURE_FILE_TITLE'];
            if ($arItem['PREVIEW_PICTURE']['TITLE'] == '') {
                $arItem['PREVIEW_PICTURE']['TITLE'] = $arItem['NAME'];
            }
        }

        $arResult['ITEMS'][] = $arItem;
    }
    
    if (empty($arResult['ITEMS'])) { // не удалось получить случайные элементы
        $this->AbortResultCache();
    }
    
    $this->IncludeComponentTemplate();

}
bool CBitrixComponent::StartResultCache(
   int cacheTime,
   string additionalCacheID,
   string cachePath
)

Метод поддержки внутреннего кеширования компонента. Возвращает true в случае, если кеш недействителен, или false в противном случае.

Если кеш действителен, метод отправляет на экран его содержимое, заполняет $arResult и возвращает false. Если кеш недействителен, метод возвращает true, начинается кеширование и кеш сохраняется при вызове методов

  • CBitrixComponent::IncludeComponentTemplate()
  • или
  • CBitrixComponent::ShowComponentTemplate()

сразу после подключения шаблона компонента.

Параметры

  • cacheTime — Время кеширования в секундах. Если этот параметр равен false, то время кеширования берется из входного параметра $arParams['CACHE_TIME']. Необязательный.
  • additionalCacheID — Кеш зависит от текущего сайта (SITE_ID), имени компонента, имени шаблона, входных параметров $arParams. Если кеш должен зависеть от каких-либо дополнительных параметров, то их необходимо передать сюда в виде строки. По умолчанию параметр равен false, т.е. кеш зависит только от текущего сайта SITE_ID, имени компонента, имени шаблона и входных параметров $arParams. Необязательный.
  • cachePath — Путь к файлу кеша относительно папки кешей. Необязательный.

Шаблон компонента:

<?php
/*
 * Файл local/components/tokmakov/iblock.random/templates/.default/template.php
 */
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();

/** @var array $arParams */
/** @var array $arResult */
/** @global CMain $APPLICATION */
/** @global CUser $USER */
/** @global CDatabase $DB */
/** @var CBitrixComponentTemplate $this */
/** @var string $templateName */
/** @var string $templateFile */
/** @var string $templateFolder */
/** @var string $componentPath */
/** @var CBitrixComponent $component */
?>

<section id="iblock-random-items">
<?php foreach ($arResult['ITEMS'] as $arItem): /* случайные элементы инфоблока */ ?>
    <article>
        <a href="<?= $arItem['DETAIL_PAGE_URL']; ?>">
            <img src="<?= $arItem['PREVIEW_PICTURE']['SRC']; ?>"
                 alt="<?= $arItem['PREVIEW_PICTURE']['ALT']; ?>"
                 title="<?= $arItem['PREVIEW_PICTURE']['TITLE']; ?>" />
        </a>
        <h4><a href="<?= $arItem['DETAIL_PAGE_URL']; ?>"><?= $arItem['NAME']; ?></a></h4>
        <p>Просмотров: <?= $arItem['SHOW_COUNTER'] ? $arItem['SHOW_COUNTER'] : 0; ?></p>
    </article>
<?php endforeach; ?>
</section>

Файл стилей компонента:

/*
 * Файл local/components/tokmakov/iblock.random/templates/.default/style.css
 */
#iblock-random-items {
    overflow: hidden;
    margin: 15px 0;
    background: #f5f5f5;
    border: 1px solid #d1d1d1;
    border-radius: 10px;
    padding: 10px;
}
    #iblock-random-items > article {
        float: left;
        width: 24%;
        box-sizing: border-box;
        border: 1px solid #d1d1d1;
        padding: 10px;
        border-radius: 10px;
        background: #fff;
        margin-right: 1.33333%;
    }
    #iblock-random-items > article:last-child {
        margin-right: 0;
    }
        #iblock-random-items > article > h4 {
            margin: 5px 0 5px 0;
            font-size: 14px;
            min-height: 30px;
            line-height: 15px;
        }
        #iblock-random-items > article > p {
            margin: 0;
            font-size: 12px;
            color: #999;
        }

Пример вызова компонента:

<?php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
?>
<h1>Случайные элементы</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...
</p>
<?php
$APPLICATION->IncludeComponent(
    "tokmakov:iblock.random",
    "",
    Array(
        "CACHE_TIME" => "3600",
        "CACHE_TYPE" => "Y",
        "ELEMENT_COUNT" => "4",
        "ELEMENT_URL" => "#SITE_DIR#/#IBLOCK_CODE#/item/id/#ELEMENT_ID#/",
        "IBLOCK_ID" => "5",
        "IBLOCK_TYPE" => "content"
    )
);
?>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...
</p>
<?php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>

Поиск: $arParams • $arResult • .description.php • .parameters.php • CMS • Web-разработка • Битрикс • Компонент • Шаблон компонента • Элемент инфоблока

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.