@version(2) {{-- 테마 내장 메인페이지 — 대문(메인 형태)에서 상품·게시글·카테고리 섹션을 렌더링한다. --}} {{-- 레이아웃 설정의 "메인 구성" 반복 필드로 조립하고, 비워두면 기본 구성을 쓴다. --}} @php // 커머스 스킨 공용 헬퍼(가격 표기)는 커머스 컨트롤러가 로드한다. // 대문은 다른 모듈이므로 여기서 직접 불러 둔다. 커머스 미설치면 그냥 넘어간다. if (!function_exists('shop_item_price')) { $hr_helper_file = \RX_BASEDIR . 'modules/commerce/helpers.php'; if (is_file($hr_helper_file)) { require_once $hr_helper_file; } } if (!function_exists('hr_home_price')) { // 상품 가격 한 줄 표기: 헬퍼가 있으면 통화 규칙을 따르고, 없으면 숫자만 찍는다 function hr_home_price($hr_amount) { if (function_exists('shop_money')) { return shop_money((int)$hr_amount); } return number_format((int)$hr_amount); } } if (!function_exists('hrh_flat_text')) { // 배너 문구를 한 줄 텍스트로: 줄바꿈 태그를 공백으로 풀고 태그를 걷어낸다 // (@php 문자열에 꺾쇠를 직접 쓰면 템플릿 컴파일이 깨지므로 chr 로 만든다) function hrh_flat_text($hrh_t) { $hrh_lt = chr(60); $hrh_gt = chr(62); $hrh_t = preg_replace('/' . $hrh_lt . 'br[^' . $hrh_gt . ']*' . $hrh_gt . '/i', ' ', (string)$hrh_t); return trim(strip_tags($hrh_t)); } } if (!function_exists('hr_home_cmp_off')) { // 할인율 큰 순서 function hr_home_cmp_off($hrh_a, $hrh_b) { $hrh_ap = (int)($hrh_a->price ?? 0); $hrh_bp = (int)($hrh_b->price ?? 0); $hrh_ao = $hrh_ap > 0 ? ($hrh_ap - (int)($hrh_a->sale_price ?? 0)) / $hrh_ap : 0; $hrh_bo = $hrh_bp > 0 ? ($hrh_bp - (int)($hrh_b->sale_price ?? 0)) / $hrh_bp : 0; if ($hrh_ao === $hrh_bo) { return 0; } return $hrh_ao < $hrh_bo ? 1 : -1; } } if (!function_exists('hr_home_cmp_rank')) { // 랭킹: 구매수 → 조회수 → 최신 순 function hr_home_cmp_rank($hrh_a, $hrh_b) { $hrh_av = (int)($hrh_a->buy_count ?? 0); $hrh_bv = (int)($hrh_b->buy_count ?? 0); if ($hrh_av !== $hrh_bv) { return $hrh_av < $hrh_bv ? 1 : -1; } $hrh_av = (int)($hrh_a->view_count ?? 0); $hrh_bv = (int)($hrh_b->view_count ?? 0); if ($hrh_av !== $hrh_bv) { return $hrh_av < $hrh_bv ? 1 : -1; } return (int)$hrh_a->item_srl < (int)$hrh_b->item_srl ? 1 : -1; } } if (!function_exists('hr_home_cmp_buy')) { function hr_home_cmp_buy($hr_a, $hr_b) { $hr_av = (int)($hr_a->buy_count ?? 0); $hr_bv = (int)($hr_b->buy_count ?? 0); if ($hr_av === $hr_bv) { return 0; } return $hr_av < $hr_bv ? 1 : -1; } } // 상점 mid — 헤더와 같은 규칙 (설정값 우선, 없으면 첫 커머스 모듈) $hrh_shop_mid = trim((string)($hr->shop_mid ?? '')); if ($hrh_shop_mid === '') { foreach (ModuleModel::getMidList((object)['module' => 'commerce'], ['mid']) ?: [] as $hrh_row) { $hrh_shop_mid = (string)($hrh_row->mid ?? ''); break; } } // 섹션 구성 — 설정이 비어 있으면 기본 구성 $hrh_sections = []; foreach (array_values((array)($hr->home_sections ?? [])) as $hrh_srow) { $hrh_srow = (array)$hrh_srow; if (empty($hrh_srow['stype'])) { continue; } $hrh_sections[] = [ 'stype' => (string)$hrh_srow['stype'], 'title' => trim((string)($hrh_srow['title'] ?? '')), 'source' => trim((string)($hrh_srow['source'] ?? '')), 'count' => max(2, min(12, (int)($hrh_srow['count'] ?? 8))), ]; } if (!count($hrh_sections)) { $hrh_sections = [ ['stype' => 'categories', 'title' => '', 'source' => '', 'count' => 10], ['stype' => 'daily', 'title' => '', 'source' => '', 'count' => 1], ['stype' => 'promos', 'title' => '', 'source' => '', 'count' => 4], ['stype' => 'items_recommend', 'title' => '', 'source' => '', 'count' => 8], ['stype' => 'banner', 'title' => '', 'source' => '2', 'count' => 1], ['stype' => 'ranking', 'title' => '', 'source' => '', 'count' => 6], ['stype' => 'items_new', 'title' => '', 'source' => '', 'count' => 8], ['stype' => 'banner', 'title' => '', 'source' => '3', 'count' => 1], ['stype' => 'items_sale', 'title' => '', 'source' => '', 'count' => 8], ['stype' => 'posts', 'title' => '', 'source' => 'notice,board', 'count' => 6], ]; } // 중간 배너 스트립 재료 — 레이아웃 비주얼(커머스 배너 승계 포함)을 그대로 쓴다 $hrh_banners = []; foreach ((is_array($hr_visuals ?? null) ? $hr_visuals : []) as $hrh_bv) { $hrh_bv = (array)$hrh_bv; if (!empty($hrh_bv['image'])) { $hrh_banners[] = $hrh_bv; } } // 상품 풀 — 상품 섹션이 하나라도 있으면 한 번만 조회 $hrh_pool = []; $hrh_need_items = false; foreach ($hrh_sections as $hrh_sec) { if (strpos($hrh_sec['stype'], 'items_') === 0 || $hrh_sec['stype'] === 'daily' || $hrh_sec['stype'] === 'ranking') { $hrh_need_items = true; } } if ($hrh_need_items && $hrh_shop_mid !== '') { $hrh_out = executeQuery('commerce.getItemList', (object)[ 'status_list' => 'sale,soldout', 'sort_index' => 'item_srl', 'order_type' => 'desc', 'list_count' => 120, ]); if ($hrh_out->toBool() && !empty($hrh_out->data)) { $hrh_rows = is_array($hrh_out->data) ? $hrh_out->data : [$hrh_out->data]; $hrh_now = date('YmdHis'); foreach ($hrh_rows as $hrh_it) { if (empty($hrh_it->item_srl)) { continue; } if (!empty($hrh_it->sale_start) && $hrh_now < $hrh_it->sale_start) { continue; } if (!empty($hrh_it->sale_end) && $hrh_now > $hrh_it->sale_end) { continue; } $hrh_it->item_name = \Context::replaceUserLang((string)$hrh_it->item_name); $hrh_pool[] = $hrh_it; } } } // 카테고리 — 카테고리 섹션이 있을 때만 $hrh_cats = []; foreach ($hrh_sections as $hrh_sec) { if ($hrh_sec['stype'] !== 'categories') { continue; } $hrh_cout = executeQuery('commerce.getCategoryList', (object)['is_active' => 'Y']); if ($hrh_cout->toBool() && !empty($hrh_cout->data)) { foreach ((is_array($hrh_cout->data) ? $hrh_cout->data : [$hrh_cout->data]) as $hrh_cat) { if (empty($hrh_cat->category_srl) || (int)($hrh_cat->parent_srl ?? 0) !== 0) { continue; } $hrh_cat->title = \Context::replaceUserLang((string)$hrh_cat->title); $hrh_cats[] = $hrh_cat; } } break; } // 게시판 최신 글 — posts 섹션마다 조회 (source 에 게시판 mid, 비우면 첫 게시판) if (!function_exists('hr_home_posts')) { function hr_home_posts($hrh_mid, $hrh_count) { if ($hrh_mid === '') { foreach (ModuleModel::getMidList((object)['module' => 'board'], ['mid']) ?: [] as $hrh_brow) { $hrh_mid = (string)($hrh_brow->mid ?? ''); break; } } if ($hrh_mid === '') { return ['mid' => '', 'rows' => []]; } $hrh_binfo = ModuleModel::getModuleInfoByMid($hrh_mid); if (!is_object($hrh_binfo) || empty($hrh_binfo->module_srl)) { return ['mid' => $hrh_mid, 'rows' => []]; } $hrh_dargs = new stdClass; $hrh_dargs->module_srl = (int)$hrh_binfo->module_srl; $hrh_dargs->list_count = $hrh_count; $hrh_dargs->sort_index = 'list_order'; $hrh_dargs->order_type = 'asc'; $hrh_dargs->statusList = ['PUBLIC']; $hrh_dmodel = getModel('document'); $hrh_dout = $hrh_dmodel->getDocumentList($hrh_dargs); $hrh_rows = []; foreach ((array)($hrh_dout->data ?? []) as $hrh_doc) { $hrh_rows[] = $hrh_doc; } // 게시판 스킨 설정의 제목(hr_board_title)은 module_info 에 합쳐지지 않으므로 직접 읽는다 $hrh_skin_vars = ModuleModel::getModuleSkinVars((int)$hrh_binfo->module_srl); $hrh_skin_title = ''; if (is_array($hrh_skin_vars) && isset($hrh_skin_vars['hr_board_title'])) { $hrh_sv = $hrh_skin_vars['hr_board_title']; $hrh_skin_title = is_object($hrh_sv) ? (string)($hrh_sv->value ?? '') : (string)$hrh_sv; } $hrh_title = trim($hrh_skin_title); if ($hrh_title === '') { $hrh_title = (string)($hrh_binfo->board_title ?? ''); } if ($hrh_title === '') { $hrh_title = (string)($hrh_binfo->browser_title ?? $hrh_mid); } return ['mid' => $hrh_mid, 'rows' => $hrh_rows, 'board_title' => \Context::replaceUserLang($hrh_title)]; } } @endphp
{{ $lang->ssh_daily_sub }}