@version(2) @load('../../assets/fonts.css') @load('./css/layout.css') @load('./js/layout.js') @load('./lang') @php /* 화면에서 계산하지 않는다. 필요한 값을 여기서 모두 만들어 둔다 */ $hs_cfg = clone $layout_info; foreach (get_object_vars($hs_cfg) as $hs_key => $hs_val) { if (is_string($hs_val) && strpos($hs_val, '$user_lang->') !== false) { $hs_cfg->$hs_key = Context::replaceUserLang($hs_val); } } $hs_logo = trim((string)($hs_cfg->logo_image ?? '')); $hs_logo_text = trim((string)($hs_cfg->logo_text ?? '')) ?: (string)(Context::get('site_title') ?: 'ATELIER'); $hs_tagline = trim((string)($hs_cfg->tagline ?? '')); $hs_head_tel = trim((string)($hs_cfg->head_tel ?? '')); $hs_point = trim((string)($hs_cfg->point_color ?? '')) ?: '#b08d57'; $hs_width = (int)($hs_cfg->content_width ?? 1280) ?: 1280; if (strlen($hs_point) !== 7 || $hs_point[0] !== '#' || !ctype_xdigit(substr($hs_point, 1))) { $hs_point = '#b08d57'; } $hs_rgb = array_map('hexdec', str_split(substr($hs_point, 1), 2)); $hs_lin = []; foreach ($hs_rgb as $hs_c) { $hs_c = $hs_c / 255; $hs_lin[] = $hs_c <= 0.03928 ? $hs_c / 12.92 : pow(($hs_c + 0.055) / 1.055, 2.4); } $hs_lum = 0.2126 * $hs_lin[0] + 0.7152 * $hs_lin[1] + 0.0722 * $hs_lin[2]; $hs_on_brand = (1.05 / ($hs_lum + 0.05)) >= (($hs_lum + 0.05) / 0.0552) ? '#ffffff' : '#12100e'; $hs_text_rgb = $hs_rgb; for ($hs_i = 0; $hs_i < 40; $hs_i++) { $hs_lin = []; foreach ($hs_text_rgb as $hs_c) { $hs_c = $hs_c / 255; $hs_lin[] = $hs_c <= 0.03928 ? $hs_c / 12.92 : pow(($hs_c + 0.055) / 1.055, 2.4); } if ((0.9 + 0.05) / (0.2126 * $hs_lin[0] + 0.7152 * $hs_lin[1] + 0.0722 * $hs_lin[2] + 0.05) >= 4.7) { break; } foreach ($hs_text_rgb as $hs_k => $hs_c) { $hs_text_rgb[$hs_k] = (int)floor($hs_c * 0.94); } } $hs_brand_text = vsprintf('#%02x%02x%02x', $hs_text_rgb); $hs_reserve_url = trim((string)($hs_cfg->reserve_url ?? '')); /* 메뉴 항목은 객체가 아니라 배열이다. 링크 문구 키는 link 다 */ $hs_gnb = array_values((array)($gnb->list ?? [])); $hs_footer_menu = array_values((array)($footer_menu->list ?? [])); /* 페이지 유형. 사이트맵 메뉴 클래스에 m 또는 s 를 적어 메뉴별로 정한다 */ $hs_selected_class = ''; foreach ($hs_gnb as $hs_item) { if (empty($hs_item['selected']) && empty($hs_item['open'])) { continue; } $hs_selected_class = (string)($hs_item['class'] ?? ''); foreach ((array)($hs_item['list'] ?? []) as $hs_sub) { if (!empty($hs_sub['selected'])) { $hs_selected_class = (string)($hs_sub['class'] ?? '') ?: $hs_selected_class; } } break; } $hs_is_main = false; foreach (preg_split('/\s+/', trim($hs_selected_class)) as $hs_token) { if ($hs_token === 'm') { $hs_is_main = true; break; } if ($hs_token === 's') { break; } } /* 사이트 대문은 메뉴 클래스를 적지 않아도 메인으로 본다 */ if (trim($hs_selected_class) === '') { $hs_site = \Context::get('site_module_info'); $hs_current = \Context::get('current_module_info'); $hs_home_mid = is_object($hs_site) ? (string)($hs_site->mid ?? '') : ''; $hs_now_mid = is_object($hs_current) ? (string)($hs_current->mid ?? '') : ''; $hs_is_main = $hs_home_mid !== '' && $hs_now_mid === $hs_home_mid; } /* 로그인 상태. 적립금과 쿠폰은 회원의 것이라 드나들 문이 있어야 한다 */ $hs_member = \Context::get('logged_info'); $hs_is_login = is_object($hs_member) && !empty($hs_member->member_srl); $hs_member_name = $hs_is_login ? (string)($hs_member->nick_name ?: $hs_member->user_name) : ''; $hs_login_url = getUrl('', 'act', 'dispMemberLoginForm'); $hs_logout_url = getUrl('', 'act', 'dispMemberLogout'); $hs_signup_url = getUrl('', 'act', 'dispMemberSignUpForm'); /* 내 예약. 예약 모듈이 붙어 있을 때만 문을 연다 */ $hs_my_url = ''; $hs_rsv_list = \ModuleModel::getMidList((object)['module' => 'reservation']); if (is_array($hs_rsv_list) && count($hs_rsv_list)) { $hs_rsv_first = reset($hs_rsv_list); $hs_rsv_mid = (string)($hs_rsv_first->mid ?? ''); if ($hs_rsv_mid !== '') { $hs_my_url = getUrl('', 'mid', $hs_rsv_mid, 'act', 'dispReservationMy'); } } /* 슬라이더. 한 줄에 하나씩, 이미지 | 작은문구 | 큰문구 | 링크 */ $hs_slides = []; foreach (preg_split('/\R/', (string)($hs_cfg->hero_slides ?? '')) as $hs_line) { $hs_line = trim($hs_line); if ($hs_line === '') { continue; } $hs_parts = array_map('trim', explode('|', $hs_line)); if (($hs_parts[0] ?? '') === '') { continue; } /* 슬라이드는 한 줄에 하나다. 문구 안에 진짜 줄바꿈을 넣으면 슬라이드가 쪼개진다. 그래서 문구에서는 \n 두 글자를 줄바꿈 표시로 쓰고 여기서 풀어 준다. */ $hs_slides[] = [ 'image' => $hs_parts[0], 'eyebrow' => $hs_parts[1] ?? '', 'headline' => str_replace('\n', "\n", $hs_parts[2] ?? ''), 'link' => $hs_parts[3] ?? '', ]; } $hs_hero_interval = max(0, (int)($hs_cfg->hero_interval ?? 6)); $hs_hero_height = in_array((string)($hs_cfg->hero_height ?? 'full'), ['full', 'tall', 'half'], true) ? (string)$hs_cfg->hero_height : 'full'; $hs_intro_title = trim((string)($hs_cfg->section_intro_title ?? '')); $hs_intro_text = trim((string)($hs_cfg->section_intro_text ?? '')); $hs_intro_sign = trim((string)($hs_cfg->section_intro_sign ?? '')); $hs_cta_title = trim((string)($hs_cfg->cta_title ?? '')); $hs_cta_image = trim((string)($hs_cfg->cta_image ?? '')); /* 소셜 주소. 이름 | 주소 */ $hs_sns = []; foreach (preg_split('/\R/', (string)($hs_cfg->footer_sns ?? '')) as $hs_line) { $hs_line = trim($hs_line); if ($hs_line === '') { continue; } $hs_parts = array_map('trim', explode('|', $hs_line)); if (count($hs_parts) < 2 || $hs_parts[1] === '') { continue; } $hs_sns[] = ['name' => $hs_parts[0], 'url' => $hs_parts[1]]; } $hs_footer_biz = trim((string)($hs_cfg->footer_biz ?? '')); $hs_footer_copyright = trim((string)($hs_cfg->footer_copyright ?? '')) ?: ('(c) ' . date('Y') . ' ' . $hs_logo_text); /* 시작 페이지 모듈에 볼 만한 내용이 있는가. 태그만 걷어내면 줄바꿈과 빈칸이 남아 빈 껍데기가 생긴다. 공백류까지 지우고 본다. 이 판정은 템플릿 출력식이 아니라 여기서 한다. 출력식 안에서는 특수문자가 파서와 부딪힌다. */ $hs_has_page = trim(preg_replace('/\s+/u', '', html_entity_decode(strip_tags((string)$content), ENT_QUOTES, 'UTF-8'))) !== ''; /* 첫 화면에 얹는 자료. 메인이 아니면 아예 읽지 않는다 */ $hs_services = []; $hs_staff = []; $hs_branches = []; $hs_gallery = []; if ($hs_is_main) { $hs_has_reservation = class_exists('\Zittme\Modules\Reservation\Models\Staff'); $hs_has_branch = class_exists('\Zittme\Modules\Branch\Models\Branch'); /* 지점 이름은 디자이너 카드에도 쓴다. 한 번만 읽어 둔다 */ $hs_branch_map = []; $hs_branch_mid = ''; if ($hs_has_branch) { $hs_branch_map = \Zittme\Modules\Branch\Models\Branch::getOpenList(); $hs_mid_list = \ModuleModel::getMidList((object)['module' => 'branch']); if (is_array($hs_mid_list) && count($hs_mid_list)) { $hs_first = reset($hs_mid_list); $hs_branch_mid = (string)($hs_first->mid ?? ''); } } if ($hs_has_reservation && (string)($hs_cfg->show_services ?? 'Y') === 'Y') { $hs_out = executeQueryArray('reservation.getResourceList', (object)['status' => 'open']); if ($hs_out->toBool() && is_array($hs_out->data)) { foreach ($hs_out->data as $hs_row) { foreach (['title', 'summary', 'category'] as $hs_field) { $hs_row->$hs_field = Context::replaceUserLang((string)($hs_row->$hs_field ?? '')); } $hs_services[trim((string)$hs_row->category)][] = $hs_row; } } } if ($hs_has_reservation && (string)($hs_cfg->show_staff ?? 'Y') === 'Y') { foreach (\Zittme\Modules\Reservation\Models\Staff::getList(0, 'active') as $hs_person) { $hs_bsrl = (int)($hs_person->branch_srl ?? 0); $hs_person->branch_name = isset($hs_branch_map[$hs_bsrl]) ? (string)$hs_branch_map[$hs_bsrl]->name : ''; $hs_person->initial = mb_substr((string)$hs_person->name, 0, 1); $hs_staff[] = $hs_person; } } if ((string)($hs_cfg->show_branches ?? 'Y') === 'Y' && $hs_has_branch) { foreach ($hs_branch_map as $hs_bsrl => $hs_branch) { $hs_hours = \Zittme\Modules\Branch\Models\Branch::getTodayHours($hs_bsrl); $hs_branches[] = [ 'name' => (string)$hs_branch->name, 'summary' => (string)$hs_branch->summary, 'address' => trim($hs_branch->address . ' ' . $hs_branch->address_detail), 'tel' => (string)$hs_branch->tel, 'open_now' => \Zittme\Modules\Branch\Models\Branch::isOpenNow($hs_bsrl), 'hours' => $hs_hours ? ($hs_hours->open_time . ' - ' . $hs_hours->close_time) : lang('hs_closed_today'), 'href' => $hs_branch_mid !== '' ? getUrl('', 'mid', $hs_branch_mid, 'act', 'dispBranchView', 'branch_srl', $hs_bsrl) : '', ]; } } /* 룩북. 게시판을 정해 두면 그쪽을 먼저 쓰고, 없으면 설정에 적은 사진을 쓴다 */ $hs_gallery_mid = trim((string)($hs_cfg->gallery_mid ?? '')); if ($hs_gallery_mid === '') { foreach (preg_split('/\R/', (string)($hs_cfg->lookbook_images ?? '')) as $hs_line) { $hs_line = trim($hs_line); if ($hs_line === '') { continue; } $hs_parts = array_map('trim', explode('|', $hs_line)); if (($hs_parts[0] ?? '') === '') { continue; } $hs_gallery[] = [ 'title' => $hs_parts[1] ?? '', 'href' => ($hs_parts[2] ?? '') ?: $hs_parts[0], 'thumb' => $hs_parts[0], ]; } } if ($hs_gallery_mid !== '') { $hs_gallery_module = \ModuleModel::getModuleInfoByMid($hs_gallery_mid); if (is_object($hs_gallery_module) && !empty($hs_gallery_module->module_srl)) { $hs_docs = \DocumentModel::getDocumentList((object)[ 'module_srl' => (int)$hs_gallery_module->module_srl, 'sort_index' => 'list_order', 'list_count' => max(1, (int)($hs_cfg->gallery_count ?? 8)), ]); if (is_object($hs_docs) && !empty($hs_docs->data)) { foreach ($hs_docs->data as $hs_doc) { $hs_gallery[] = [ 'title' => $hs_doc->getTitle(40), 'href' => $hs_doc->getPermanentUrl(), 'thumb' => $hs_doc->getThumbnail(600, 800, 'crop'), ]; } } } } if (count($hs_gallery) > 5) { $hs_gallery = array_slice($hs_gallery, 0, count($hs_gallery) - count($hs_gallery) % 5); } } @endphp