/
aleksandr.zubkov
/
UniversityScheduleBitrix
Обзор
Документация
Войти
/
aleksandr.zubkov
/
UniversityScheduleBitrix
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
developer
blocks/knowledge-base.php
435 строк
32 KB
Зубков Александр
Created cards and moc for cards
24 май 2026, 20:33
24 май 2026, 20:33
69f4346
Код
Авторство
О чём код?
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); /** * @global array $data * @global string $blockId */ use Bitrix\Main\Application; use Bitrix\Main\Loader; use Paraweb\Constructor\Localization\Loc; use Paraweb\Constructor\Helpers\BlockHelper; use Paraweb\Constructor\Helpers\LinkHelper; use Paraweb\Constructor\Helpers\StringHelper; Loc::loadMessages(__FILE__); Loader::includeModule('iblock'); $pageSize = $data['pageSize'] ?? 9; $request = Bitrix\Main\Application::getInstance()->getContext()->getRequest(); $currentPageUrl = $request->getRequestedPageDirectory(); $page = $request->get('page') ?? 1; $searchQuery = $request->get('search'); $directionQuery = $request->get('direction'); $categoryQuery = $request->get('category'); $elements = []; $categories = []; $directions = []; $paginationQuery = []; $filters = [ 'IBLOCK_ID' => $data['iblockId'], 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y' ]; if ($data['sectionId']) { $filters['SECTION_ID'] = $data['sectionId']; $filters['INCLUDE_SUBSECTIONS'] = 'Y'; } $categoryValues = []; $res = CIBlockElement::GetList(['PROPERTY_CATEGORY' => 'ASC'], array_merge($filters, ['!PROPERTY_CATEGORY' => false]), ['PROPERTY_CATEGORY']); while ($arFields = $res->GetNext()) { if ($arFields['CNT'] > 0) { $categoryValues[$arFields['PROPERTY_CATEGORY_ENUM_ID']] = $arFields['CNT']; } } $propertyEnums = CIBlockPropertyEnum::GetList(['DEF' => 'DESC', 'SORT' => 'ASC'], ['IBLOCK_ID' => $data['iblockId'], 'CODE' => 'CATEGORY', 'ID' => array_keys($categoryValues)]); while ($enumFields = $propertyEnums->GetNext()) { if ($categoryValues[$enumFields['ID']] > 0) { $categories[$enumFields['ID']] = $enumFields['VALUE']; } } $directionValues = []; $res = CIBlockElement::GetList(['PROPERTY_DIRECTION' => 'ASC'], array_merge($filters, ['!PROPERTY_DIRECTION' => false]), ['PROPERTY_DIRECTION']); while ($arFields = $res->GetNext()) { if ($arFields['CNT'] > 0) { $directionValues[$arFields['PROPERTY_DIRECTION_ENUM_ID']] = $arFields['CNT']; } } $propertyEnums = CIBlockPropertyEnum::GetList(['DEF' => 'DESC', 'SORT' => 'ASC'], ['IBLOCK_ID' => $data['iblockId'], 'CODE' => 'DIRECTION', 'ID' => array_keys($directionValues)]); while ($enumFields = $propertyEnums->GetNext()) { if ($directionValues[$enumFields['ID']] > 0) { $directions[$enumFields['ID']] = $enumFields['VALUE']; } } if ($directionQuery) { $filters['PROPERTY_DIRECTION'] = $directionQuery; $paginationQuery['direction'] = $directionQuery; } if ($categoryQuery) { $filters['PROPERTY_CATEGORY'] = $categoryQuery; $paginationQuery['category'] = $categoryQuery; } if ($searchQuery) { $filters['NAME'] = '%'.$searchQuery.'%'; $paginationQuery['search'] = $searchQuery; } $elementsCnt = \CIBlockElement::GetList([], $filters, [], false); $totalPages = (int)ceil($elementsCnt / $pageSize); $startPage = $page - 2 < 1 ? 1 : ($page - 2); $endPage = min($page + 2, $totalPages); $res = \CIBlockElement::GetList(['SORT' => 'DESC', 'NAME' => 'ASC'], $filters, false, ['nTopCount' => $pageSize, 'nOffset' => $pageSize * ($page - 1)], ['ID', 'CODE', 'DETAIL_PAGE_URL', 'NAME', 'PREVIEW_TEXT', 'PREVIEW_PICTURE', 'IBLOCK_ID', 'PROPERTY_*']); while ($obElement = $res->GetNextElement()) { $arItem = $obElement->GetFields(); if ($arItem['PREVIEW_PICTURE']) { $arItem['PREVIEW_PICTURE'] = CFile::GetFileArray($arItem['PREVIEW_PICTURE']); } $arItem['PROPERTIES'] = $obElement->GetProperties(); $arItem['DISPLAY_PROPERTIES'] = []; $properties = ["CATEGORY", "DIRECTION", "LINK", "FILE", "PRICE", "AUTHOR", "PUBLISHER", "YEAR", "MESSAGE"]; foreach ($properties as $pid) { $prop = &$arItem["PROPERTIES"][$pid]; if( (is_array($prop["VALUE"]) && count($prop["VALUE"])>0) || (!is_array($prop["VALUE"]) && $prop["VALUE"] <> '') ) { $arItem["DISPLAY_PROPERTIES"][$pid] = \CIBlockFormatProperties::GetDisplayValue($arItem, $prop); } \CIBlockFormatProperties::clearCache(); } if ($data['currentUrlForBase']) { $arItem['DETAIL_PAGE_URL'] = $currentPageUrl . $arItem['CODE']; } elseif ($data['baseUrl']) { $arItem['DETAIL_PAGE_URL'] = $data['baseUrl'] . $arItem['CODE']; } $elements[$arItem['ID']] = $arItem; }?> <section id="<?=BlockHelper::getAnchor($blockId)?>" class="app-section overflow-visible<?if ($data['margin']):?> <?=$data['margin']?><?endif;?>"> <div class="container"> <div class="app-section__outer"> <div class="app-section__inner"> <?if (!empty($data['title']) || !empty($data['description'])):?> <div class="app-section__head<?if ($data['centred']):?> _centred<?endif; if ($data['link']):?> _with-link<?endif;?>"> <?if ($data['title']):?> <h2><?= $data['title'] ?></h2> <?endif; if ($data['description']):?> <div class="app-section__subtitle"> <?=$data['description']?> </div> <?endif; if ($data['link']):?> <a class="button-secondary" href="<?=$data['link']?>" target="<?=LinkHelper::getTarget($data['link'])?>"> <span class="button-secondary__text"><?=$data['linkTitle']?></span> <span class="button-secondary__icon"> <svg class="_icon-arrow-right"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right"></use> </svg> </span> </a> <?endif;?> </div> <?endif;?> <div class="app-section__content"> <div class="form-block _margin-bottom"> <form class="form-block__controls js-update-url" id="knowledge-base-block-<?=$blockId?>-form" data-hx-get="<?=SITE_DIR?>ajax/knowledge-base.php?block=<?=$blockId?>&pageUrl=<?=$currentPageUrl?>" data-hx-target="#knowledge-base-block-<?=$blockId?>" data-hx-trigger="submit, change, input delay:500ms" data-hx-select="#knowledge-base-block-<?=$blockId?>" data-hx-swap="outerHTML" data-hx-push-url="true" data-hx-include="#knowledge-base-block-<?=$blockId?>-pagination"> <div class="form-block__wrapper"> <div class="form-block__search"> <div class="text-field"> <svg class="_icon-search text-field__icon"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#search" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#search"></use> </svg> <span class="text-field__label"><?=Loc::getMessage('knowledge-base.search')?></span> <input class="text-field__input" name="search" type="text" value="<?=$searchQuery?>" /> </div> <button class="news-search__button" type="submit"><span><?=Loc::getMessage('knowledge-base.searchButton')?></span></button> </div> <div class="form-block__custom"> <?if ($categories):?> <div class="form-block__item"> <span><?=Loc::getMessage('knowledge-base.category')?></span> <div class="dropdown select" data-dropdown-focus-trap="false" data-dropdown-close-on-click="data-dropdown-close-on-click" data-select-allow-empty="true"> <div class="dropdown__trigger"> <div class="text-field readonly"> <span class="text-field__label"><?=Loc::getMessage('knowledge-base.select')?></span> <input class="text-field__input" readonly="readonly" type="text" /> <span class="text-field__actions"> <span class="text-field__action" role="button" aria-label="Dropdown toggle" tabindex="0"> <svg class="_icon-chevron-down text-field__icon"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#chevron-down" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#chevron-down"></use> </svg> </span> </span> </div> </div> <div class="dropdown__content" role="dialog" aria-hidden="true" tabindex="-1" style="display: none" aria-haspopup="true"> <div class="card dropdown-card scrollable" data-simplebar="data-simplebar"> <div class="card__inner"> <div class="dropdown-card__content"> <div class="select__options"> <?foreach ($categories as $id => $category):?> <div class="select-option"> <label class="checkbox select-option__label" data-text="<?=$category?>"> <input type="checkbox" name="category" value="<?=$id?>"<?if ($id == $categoryQuery):?> checked="checked"<?endif;?> /> <span class="checkbox__icon"> <svg class="_icon-checkbox"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#checkbox" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#checkbox"></use> </svg> </span> <span class="checkbox__text"><?=$category?></span> </label> </div> <?endforeach;?> </div> <div class="select__empty"> <p><?=Loc::getMessage('knowledge-base.empty')?></p> </div> </div> </div> </div> </div> </div> </div> <?endif; if ($directions):?> <div class="form-block__item"> <span><?=Loc::getMessage('knowledge-base.direction')?></span> <div class="dropdown select" data-dropdown-focus-trap="false" data-dropdown-close-on-click="data-dropdown-close-on-click" data-select-allow-empty="true"> <div class="dropdown__trigger"> <div class="text-field readonly"> <span class="text-field__label"><?=Loc::getMessage('knowledge-base.select')?></span> <input class="text-field__input" readonly="readonly" type="text" /> <span class="text-field__actions"> <span class="text-field__action" role="button" aria-label="Dropdown toggle" tabindex="0"> <svg class="_icon-chevron-down text-field__icon"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#chevron-down" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#chevron-down"></use> </svg> </span> </span> </div> </div> <div class="dropdown__content" role="dialog" aria-hidden="true" tabindex="-1" style="display: none" aria-haspopup="true"> <div class="card dropdown-card scrollable" data-simplebar="data-simplebar"> <div class="card__inner"> <div class="dropdown-card__content"> <div class="select__options"> <?foreach ($directions as $id => $direction):?> <div class="select-option"> <label class="checkbox select-option__label" data-text="<?=$direction?>"> <input type="checkbox" name="direction" value="<?=$id?>"<?if ($id == $directionQuery):?> checked="checked"<?endif;?> /> <span class="checkbox__icon"> <svg class="_icon-checkbox"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#checkbox" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#checkbox"></use> </svg> </span> <span class="checkbox__text"><?=$direction?></span> </label> </div> <?endforeach;?> </div> <div class="select__empty"> <p><?=Loc::getMessage('knowledge-base.empty')?></p> </div> </div> </div> </div> </div> </div> </div> <?endif;?> </div> </div> </form> </div> <div class="flex-cols flex-cols-1" id="knowledge-base-block-<?=$blockId?>" data-animate-container> <div class="flex-cols flex-cols-3"> <?foreach ($elements as $key => $element): $link = $element['DISPLAY_PROPERTIES']['LINK']['VALUE'] ?: ($element['DISPLAY_PROPERTIES']['FILE']['FILE_VALUE']['SRC'] ?: $element['DETAIL_PAGE_URL']); $price = $element['DISPLAY_PROPERTIES']['PRICE']['VALUE']; $author = $element['DISPLAY_PROPERTIES']['AUTHOR']['VALUE']; $publisher = $element['DISPLAY_PROPERTIES']['PUBLISHER']['VALUE']; $year = $element['DISPLAY_PROPERTIES']['YEAR']['VALUE']; $category = $element['DISPLAY_PROPERTIES']['CATEGORY']['VALUE']; $message = $element['DISPLAY_PROPERTIES']['MESSAGE']['VALUE']; ?> <article class="contact-card _has-image _small-image _is-link"> <div class="contact-card__image<?if (!$element['PREVIEW_PICTURE']['SRC']):?> img-centred<?endif;?>"> <picture class="picture"> <img class="lazy" data-src="<?=$element['PREVIEW_PICTURE']['SRC'] ?? SITE_TEMPLATE_PATH . '/images/plug-2.jpg'?>" alt="<?=$element['NAME']?>" src="<?=SITE_TEMPLATE_PATH?>/images/gap.jpg" /> </picture> <?if ($category):?> <div class="contact-card__hash-tags"> <span class="contact-card__hash-tag"><?=$category?></span> </div> <?endif;?> </div> <?if ($link):?> <a class="contact-card__link" href="<?=$link?>" target="<?=LinkHelper::getTarget($link)?>"></a> <?endif;?> <div class="contact-card__content"> <div class="contact-card__info"> <div class="contact-card__headline"> <h4 class="contact-card__title"><?=$element['NAME']?></h4> <?if ($author):?> <a><?=$author?><?if ($year):?>, <?=$year?> г.<?endif;?></a> <?endif;?> <?if ($element['PREVIEW_TEXT']):?> <span><?=$element['PREVIEW_TEXT']?></span> <?endif;?> <?if ($price):?> <span class="grand-card__money"><?=$price?> ₽</span> <?endif;?> </div> </div> <?if ($link):?> <?if ($price):?> <a class="button-secondary" href="#grand-card-<?=$GLOBALS['BLOCK_ID']?>-<?=$key + 1?>" target="<?=LinkHelper::getTarget($link)?>"> <span class="button-secondary__text"><?=Loc::getMessage('knowledge-base.pay')?></span> <span class="button-secondary__icon"> <svg class="_icon-arrow-right"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right"></use> </svg> </span> </a> <?elseif(!empty($price) === false): ?> <a class="button-secondary" href="<?=$link?>" target="<?=LinkHelper::getTarget($link)?>"> <span class="button-secondary__text"><?=Loc::getMessage('knowledge-base.linkTitle')?></span> <span class="button-secondary__icon"> <svg class="_icon-arrow-right"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right"></use> </svg> </span> </a> <?endif?> <?endif;?> </div> </article> <div class="dialog-content" aria-hidden="aria-hidden" id="grand-card-<?=$GLOBALS['BLOCK_ID']?>-<?= $key + 1?>" style="display: none" tabindex="-1" data-dialog-width="90rem"> <article class="grand-card__dialog"> <div class="grand-card__dialog-image"> <picture class="picture"> <img class="lazy" data-src="<?=$element['PREVIEW_PICTURE']['SRC'] ?? SITE_TEMPLATE_PATH . '/images/plug-2.jpg'?>" alt="<?=$element['NAME']?>" src="<?=SITE_TEMPLATE_PATH?>/images/gap.jpg" /> </picture> </div> <div class="grand-card__dialog-content"> <div class="grand-card__dialog-wrapper"> <div class="grand-card__dialog-info"> <h4 class="grand-card__dialog-title"><?=$element['NAME']?></h4> <?if ($price):?> <span class="grand-card__money"><?=$price?> ₽</span> <?endif;?> <div class="grand-card__dialog-list"> <?if (!empty($author)):?> <div class="grand-card__dialog-item _fill"> <span><?=Loc::getMessage('knowledge-base.authors')?></span> <span><?=$author?></span> </div> <?endif; if (!empty($publisher)):?> <div class="grand-card__dialog-item"> <span><?=Loc::getMessage('knowledge-base.publisher')?></span> <span><?=$publisher?></span> </div> <?endif; if (!empty($category)):?> <div class="grand-card__dialog-item"> <span><?=Loc::getMessage('knowledge-base.category')?></span> <span><?=$category?></span> </div> <?endif; if (!empty($year)):?> <div class="grand-card__dialog-item"> <span><?=Loc::getMessage('knowledge-base.year')?></span> <span><?=$year?></span> </div> <?endif;?> </div> <?if (!empty($message)):?> <span style="color: red;"><?=$message?></span> <?endif;?> <?if (!empty($element['PREVIEW_TEXT'])):?> <span><?=$element['PREVIEW_TEXT']?></span> <?endif;?> </div> <button class="button-round" type="button" data-dialog-close-control="data-dialog-close-control"> <svg class="_icon-close"> <use xlink:href="<?= SITE_TEMPLATE_PATH ?>/sprite.svg#close" href="<?= SITE_TEMPLATE_PATH ?>/sprite.svg#close"></use> </svg> </button> </div> <?if (!empty($link)):?> <a class="button" href="<?=$link?>" target="<?=$link?>"> <span class="button__mot"> <span class="button__text"><?=Loc::getMessage('knowledge-base.buy')?></span> </span> <span class="button__round"></span> <span class="button__icon"> <svg class="_icon-arrow-right"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right"></use> </svg> </span> </a> <?endif;?> </div> </article> </div> <?endforeach;?> </div> <?if ($totalPages > 1):?> <form class="pagination _top-margin js-update-url" id="knowledge-base-block-<?=$blockId?>-pagination" data-hx-get="<?=SITE_DIR?>ajax/knowledge-base.php?block=<?=$blockId?>&pageUrl=<?=$currentPageUrl?><?=$paginationQuery ? '&' . http_build_query($paginationQuery) : ''?>" data-hx-target="#knowledge-base-block-<?=$blockId?>" data-hx-trigger="change" data-hx-select="#knowledge-base-block-<?=$blockId?>" data-hx-swap="outerHTML show:._scroll-trigger:top" data-hx-push-url="false" data-hx-include="#knowledge-base-block-<?=$blockId?>-form"> <button type="submit" style="display: none">Submit</button> <?if ($page > 1):?> <label> <div class="pagination__item _arrow"> <input name="page" value="<?=$page - 1?>" type="radio" /> <svg class="_icon-arrow-left-2"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-left-2" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-left-2"></use> </svg> </div> </label> <?endif;?> <div class="pagination__items"> <?while ($startPage <= $endPage):?> <label> <div class="pagination__item"> <input name="page" value="<?=$startPage?>" type="radio"<?if ($startPage == $page):?> checked="checked"<?endif;?> /> <span><?=$startPage?></span> </div> </label> <?$startPage++; endwhile;?> </div> <?if ($page < $totalPages):?> <label> <div class="pagination__item _arrow"> <input name="page" value="<?=$page + 1?>" type="radio" /> <svg class="_icon-arrow-right-2"> <use xlink:href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right-2" href="<?=SITE_TEMPLATE_PATH?>/sprite.svg#arrow-right-2"></use> </svg> </div> </label> <?endif;?> </form> <?endif;?> </div> </div> </div> </div> </div> </section>