/
aleksandr.zubkov
/
UniversityScheduleBitrix
Обзор
Документация
Войти
/
aleksandr.zubkov
/
UniversityScheduleBitrix
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
developer
blocks/schedule.php
392 строки
19 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 Bitrix\Highloadblock as HL; 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'); Loader::includeModule('highloadblock'); function toColor($str) { return match ($str) { 'Пастельный голубой' => '#9ed8f2', 'Мятно-бирюзовый' => '#7fd6c2', 'Пастельный жёлтый' => '#b7e4a8', 'Пудрово-розовый' => '#f8b7b7', 'Светлый серо-голубой' => '#cfd7dc', 'Нежно-синий' => '#a9c7f5', 'Мягкий зелёный' => '#a8e6bf', 'Тёплый жёлтый' => '#ffe08a', 'Мягкий коралловый' => '#f6a6a6', 'Персиково-оранжевый' => '#f3b783', 'Светло-зелёный' => '#b7e4a8', default => '#9ed231', // или другое значение по умолчанию }; } $request = Application::getInstance()->getContext()->getRequest(); $locationsQuery = $request->get('location'); $selectedDay = $request->get('tab'); $elements = []; $locations = []; $dayWeeks = []; $filters = [ 'IBLOCK_ID' => $data['iblockId'], 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y' ]; if ($data['sectionId']) { $filters['SECTION_ID'] = $data['sectionId']; $filters['INCLUDE_SUBSECTIONS'] = 'Y'; } $locationValues = []; $locationFilter = []; $dayFilter = []; if ($selectedDay) { $dayFilter = ['PROPERTY_DAYWEEK' => $selectedDay]; } if ($locationsQuery) { $filters['PROPERTY_LOCATIONENUM'] = $locationsQuery; } if ($selectedDay) { $filters = array_merge($filters, $dayFilter); } $baseFiltersForCount = [ 'IBLOCK_ID' => $data['iblockId'], 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y' ]; if ($data['sectionId']) { $baseFiltersForCount['SECTION_ID'] = $data['sectionId']; $baseFiltersForCount['INCLUDE_SUBSECTIONS'] = 'Y'; } $res = CIBlockElement::GetList(['PROPERTY_LOCATIONENUM' => 'ASC'], array_merge($filters, ['!PROPERTY_LOCATIONENUM' => false]), ['PROPERTY_LOCATIONENUM']); while ($arFields = $res->GetNext()) { if ($arFields['CNT'] > 0) { $locationValues[$arFields['PROPERTY_LOCATIONENUM_ENUM_ID']] = $arFields['CNT']; } } $propertyEnums = CIBlockPropertyEnum::GetList(['DEF' => 'DESC', 'SORT' => 'ASC'], ['IBLOCK_ID' => $data['iblockId'], 'CODE' => 'LOCATIONENUM', 'ID' => array_keys($locationValues)]); while ($enumFields = $propertyEnums->GetNext()) { if ($locationValues[$enumFields['ID']] > 0) { $locations[$enumFields['ID']] = $enumFields['VALUE']; } } $res = CIBlockElement::GetList(['PROPERTY_LOCATIONENUM' => 'ASC'], array_merge($baseFiltersForCount, ['!PROPERTY_LOCATIONENUM' => false]), ['PROPERTY_LOCATIONENUM']); while ($arFields = $res->GetNext()) { if ($arFields['CNT'] > 0) { $locationValues[$arFields['PROPERTY_LOCATIONENUM_ENUM_ID']] = $arFields['CNT']; } } $propertyEnums = CIBlockPropertyEnum::GetList( ['SORT' => 'ASC'], ['IBLOCK_ID' => $data['iblockId'], 'CODE' => 'DAYWEEK'] ); while ($enumFields = $propertyEnums->GetNext()) { $dayWeeks[$enumFields['ID']] = $enumFields['VALUE']; } $elementsCnt = \CIBlockElement::GetList([], $filters, [], false); $res = \CIBlockElement::GetList(['SORT' => 'DESC', 'NAME' => 'ASC'], $filters, false, [], ['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 = ["TIME", "COLOR", "POOL", "EMPLOYEE", "SCHEDULE", "LOCATIONENUM"]; 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['baseUrl']) { $arItem['DETAIL_PAGE_URL'] = $data['baseUrl'] . $arItem['CODE']; } $elements[$arItem['ID']] = $arItem; } ?> <style> .vgmu-person-card { overflow: hidden; left: 0; transition: all 0.5s ease; } .vgmu-person-card>* { position: relative; z-index: 2; } .vgmu-person-card::before { content: ""; position: absolute; top: 0; left: 0; width: 1%; height: 100%; background-color: var(--class-color, #078877); } .vgmu-class-card__time { display: inline-flex; width: fit-content; padding: 7px 11px; border-radius: 999px; font-size: 14px; line-height: 1; font-weight: 600; color: rgba(0, 0, 0, 0.73); background: var(--class-color, #078877); } /* Бабблы с временем / днями */ .vgmu-class-card__days, .vgmu-class-card__schedule-times { display: flex; flex-wrap: wrap; gap: 7px; } .vgmu-class-card__day { display: inline-flex; width: fit-content; padding: 6px 9px; border: none; border-radius: 999px; background: #f4f6f6; color: #2c2c2c; font-size: 13px; line-height: 1; font-family: inherit; cursor: pointer; transition: 0.2s ease; } .vgmu-person-card:hover { transform: translateY(-5px); /* Эффект подъема */ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); /* Тень */ } /* --- ИСЧЕЗНОВЕНИЕ ПОЛОСКИ ПРИ НАВЕДЕНИИ НА КАРТОЧКУ --- */ .vgmu-person-card:hover::before { display: none; /* Это прячет полоску */ } .vgmu-person-card:hover .vgmu-class-card__time { background-color: transparent; } </style> <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; ?> </div> <? endif; ?> <div class="app-section__content"> <div class="form-block _margin-bottom"> <form class="form-block__controls js-update-url" id="schedule-<?=$blockId?>-form" data-hx-get="<?=SITE_DIR?>ajax/schedule.php?block=<?=$blockId?>&pageUrl=<?=$currentPageUrl?>" data-hx-target="#schedule-<?=$blockId?>" data-hx-trigger="submit, change, input delay:500ms" data-hx-select="#schedule-<?=$blockId?>" data-hx-swap="outerHTML" data-hx-push-url="true"> <div class="form-block__custom"> <? if ($locations): ?> <div class="form-block__item"> <span><?=Loc::getMessage('schedule.location')?></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('schedule.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 ($locations as $id => $location):?> <div class="select-option"> <label class="checkbox select-option__label" data-text="<?=$location?>"> <input type="checkbox" name="location" value="<?=$id?>"<?if ($id == $locationsQuery):?> 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"><?=$location?></span> </label> </div> <?endforeach;?> </div> <div class="select__empty"> <p><?=Loc::getMessage('schedule.empty')?></p> </div> </div> </div> </div> </div> </div> </div> <? endif; ?> </div> </form> </div> <div class="u-cols u-cols-lg-3 u-cols-md-1 u-cols-sm-1 u-gap-4" id="schedule-<?=$blockId?>" data-animate-container> <?foreach ($elements as $key => $element): $link = $element['DISPLAY_PROPERTIES']['LINK']['VALUE'] ?: ($element['DISPLAY_PROPERTIES']['FILE']['FILE_VALUE']['SRC'] ?: $element['DETAIL_PAGE_URL']); $time = $element['DISPLAY_PROPERTIES']['TIME']['VALUE']; $day = $element['DISPLAY_PROPERTIES']['DAYWEEK']['VALUE']; $color = $element['DISPLAY_PROPERTIES']['COLOR']['VALUE']; $location = $element['DISPLAY_PROPERTIES']['LOCATIONENUM']['VALUE']; $pool = $element['DISPLAY_PROPERTIES']['POOL']['VALUE']; $employee = null; if (!empty($element['DISPLAY_PROPERTIES']['EMPLOYEE']['VALUE'])) { $employeeIblockId = $element['DISPLAY_PROPERTIES']['EMPLOYEE']['LINK_IBLOCK_ID']; $employeeId = $element['DISPLAY_PROPERTIES']['EMPLOYEE']['VALUE']; $filter = [ 'IBLOCK_ID' => $employeeIblockId, 'ACTIVE' => 'Y' ]; if (is_array($employeeId)) { $filter['ID'] = reset($employeeId); } else { $filter['ID'] = $employeeId; } $dbRes = \CIBlockElement::GetList( [], $filter, false, false, ['ID', 'NAME', 'PREVIEW_PICTURE'] ); $properties = ["LINK","SECOND_PICTURE"]; 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 ($arItem = $dbRes->Fetch()) { if ($arItem['PREVIEW_PICTURE']) { $arItem['PREVIEW_PICTURE'] = CFile::GetFileArray($arItem['PREVIEW_PICTURE']); } $employee = $arItem; } if ($element['DISPLAY_PROPERTIES']['SCHEDULE']['VALUE']){ $times = []; $timesEntity = HL\HighloadBlock::wakeUp($element['DISPLAY_PROPERTIES']['SCHEDULE']['USER_TYPE_SETTINGS']['ENUM'])->getEntityDataClass(); $res = $timesEntity::query() ->addSelect('*') ->addFilter('ID', $element['DISPLAY_PROPERTIES']['SCHEDULE']['VALUE']) ->exec(); while ($row = $res->fetch()) { $times[$row['ID']] = $row; } $image = $employee['DISPLAY_PROPERTIES']['SECOND_PICTURE']['FILE_VALUE']['SRC'] ?: $employee['PREVIEW_PICTURE']['SRC']; foreach ($element['DISPLAY_PROPERTIES']['SCHEDULE']['VALUE'] as $i => $tm): if ($times[$tm]): if ($element['DISPLAY_PROPERTIES']['SCHEDULE']['DESCRIPTION'][$i]):?> <article class="person-card<?if ($image):?> _has-image<?endif;?> vgmu-person-card " style="--class-color:<?= toColor($color) ?>;"> <div class="person-card__logo"> <picture class="picture"> <img class="lazy" data-src="<?=$image ?: SITE_TEMPLATE_PATH . '/images/smart-logo.svg'?>" alt="<?=$arItem['NAME']?>" src="<?=SITE_TEMPLATE_PATH?>/images/gap.jpg" /> </picture> </div> <div class="person-card__content"> <div class="vgmu-class-card__info"> <div class="vgmu-class-card__meta"> <div class="vgmu-class-card__time . person-card__title"><?=$element['DISPLAY_PROPERTIES']['SCHEDULE']['DESCRIPTION'][$i]?></div> <div class="vgmu-class-card__day"><?= $times[$tm]['UF_DW'] ?></div> </div> </div> <a href="<?=$employee['DISPLAY_PROPERTIES']['LINK']['DISPLAY_VALUE'] ?: $employee['DETAIL_PAGE_URL']?>"> <h5 class="person-card__title"><?=$element['NAME']?> <?=$selectedDay?></h5> </a> <a class="person-card__subtitle"><?=$oldArItem['NAME'] ?: $employee['NAME']?></a> <a class="person-card__subtitle"><?=$location?><?if($pool):?>, дорожка: <?=$pool?> <?endif?></a> </div> </article> <?endif; endif; endforeach; } } endforeach;?> </div> </div> </div> </div> </div> </section>