Compare commits

...
Author SHA1 Message Date
whitedot de7063192e chore: 5.6.391 버전과 쇼핑몰 분류 표시 수정 배포 안내 준비 2026-09-15 06:19:00 +00:00
whitedot e2d215c368 fix: 쇼핑몰 5단계 분류 경로와 서브메뉴 표시 일관성 보완
PC·basic 테마 breadcrumb를 5단계로 확장하고 기존 위치와 스타일을 유지한다. PC·모바일 서브메뉴는 5단계가 있으면 해당 목록만, 없으면 4단계 형제 목록만 표시한다.

검증: 8개 분류 경로와 네 스킨의 메뉴·선택 상태, Chromium 목록·상세 단계별 레이아웃 검사, PHP 5.2 및 현재 PHP 구문 검사 통과.
2026-09-15 06:19:00 +00:00
12 changed files with 280 additions and 220 deletions
+1
View File
@@ -73,6 +73,7 @@ cd gnuboard5
## 문서 및 지원
- [5.6.391 쇼핑몰 분류 표시 수정 안내](docs/release-5.6.391.md)
- [5.6.39 보안 업데이트 및 필수 DB업그레이드 안내](docs/release-5.6.39.md)
- [5.6.37 SIRK 전용 카카오페이 연동 종료 및 기존 거래 지원](docs/sirk-kakaopay-retirement.md)
+26
View File
@@ -0,0 +1,26 @@
# 그누보드(영카트) 5.6.391 배포 안내
배포일: 2026-09-15. 변경 기준은 5.6.39입니다.
쇼핑몰 4·5단계 분류의 현재 경로와 서브메뉴 표시를 보완하는 버그 수정 버전입니다.
## 변경 사항
- PC 기본 스킨과 basic 테마의 breadcrumb에 4·5단계 분류 경로를 표시합니다. 모든 단계에서 기존 위치와 스타일을 유지합니다.
- PC·모바일 기본 스킨과 basic 테마의 서브메뉴는 선택한 4단계에 사용 중인 5단계가 있으면 5단계 목록만 표시하고, 없으면 4단계 형제 목록만 표시합니다.
- 5단계에서는 같은 부모 아래의 5단계 형제 목록과 현재 선택을 표시합니다.
- 공통 전체 분류 트리의 기존 3단계 구조는 유지하고 현재 경로에 필요한 깊은 단계만 추가 조회합니다.
## 업데이트 방법
1. 기존 소스와 사용자 수정 파일을 백업합니다.
2. 5.6.39 설치본에 전체 소스 또는 `gnuboard5.6.391.patch.zip`을 반영합니다. 공통 라이브러리와 스킨 파일을 함께 업데이트합니다. 사용자 수정 스킨은 변경 내용을 비교하여 병합합니다.
3. 4·5단계 분류의 breadcrumb, 하위 분류 유무에 따른 메뉴, 현재 선택 표시를 확인합니다.
이번 버전의 추가 DB 마이그레이션과 삭제 대상 파일은 없습니다. 5.6.39보다 오래된 설치본은 [5.6.39 보안 업데이트 및 DB업그레이드 안내](release-5.6.39.md)를 포함한 선행 업데이트를 적용해야 합니다.
## 검증
8개 분류 경로에서 PC·basic 테마의 목록/상세 breadcrumb와 네 스킨의 메뉴·선택 상태를 확인했습니다. Chromium에서 1·3·4·5단계 전환 시 breadcrumb 위치·높이와 메뉴·상품 정렬 영역 위치가 동일함을 확인했습니다. 변경된 운영 PHP 7개 파일은 현재 PHP와 PHP 5.2 구문 검사를 통과했습니다.
분류 데이터 대역을 사용한 회귀 검사이며 실제 운영 DB와 모든 사용자 스킨을 검증한 결과는 아닙니다.
+41 -1
View File
@@ -82,9 +82,49 @@ function get_shop_navigation_data($is_cache, $ca_id, $ca_id2='', $ca_id3=''){
}
}
// 공통 전체 분류 트리는 기존 3단계 구조를 유지하고 현재 경로의 깊은 단계만 조회한다.
for ($depth = 4; $depth <= 5 && strlen($ca_id) >= $depth * 2; $depth++) {
$parent = substr($ca_id, 0, ($depth - 1) * 2);
$result = sql_query(get_shop_category_sql($parent, $depth * 2));
while ($row = sql_fetch_array($result)) {
$row['url'] = shop_category_url($row['ca_id']);
$datas[$depth - 1][] = $row;
}
}
return $datas;
}
// 4·5단계에서는 선택 경로의 5단계를 우선 표시하고, 없으면 4단계 형제를 표시한다.
function get_shop_category_menu_groups($ca_id)
{
$length = strlen($ca_id);
$groups = array();
if ($length >= 8) {
$queries = array(
array('5단계 분류', substr($ca_id, 0, 8), 10),
array('4단계 분류', substr($ca_id, 0, 6), 8),
);
} else {
$queries = array(array('하위 분류', $ca_id, $length + 2));
}
foreach ($queries as $query) {
$rows = array();
$result = sql_query(get_shop_category_sql($query[1], $query[2]));
while ($row = sql_fetch_array($result)) $rows[] = $row;
if (!$rows && $length < 8) {
$query[0] = '현재 단계 분류';
$result = sql_query(get_shop_category_sql(substr($ca_id, 0, -2), $length));
while ($row = sql_fetch_array($result)) $rows[] = $row;
}
if ($rows) {
$groups[] = array('label' => $query[0], 'categories' => $rows);
break;
}
}
return $groups;
}
function get_shop_category_by($is_cache, $case, $value){
if( $case === 'ca_id' ){
@@ -268,4 +308,4 @@ function get_shop_item_options($it_id, $subject, $no)
}
return $str;
}
}
+17 -36
View File
@@ -1,44 +1,25 @@
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
if (!defined('_GNUBOARD_')) exit;
$str = '';
$exists = false;
$ca_id_len = strlen($ca_id);
$len2 = $ca_id_len + 2;
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$ca_id%' and length(ca_id) = $len2 and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
// 하위 분류가 없으면 현재 분류를 포함한 같은 단계의 사용 중인 분류를 표시한다.
if (!sql_num_rows($result)) {
$parent_ca_id = substr($ca_id, 0, -2);
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$parent_ca_id%' and length(ca_id) = $ca_id_len and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
}
while ($row=sql_fetch_array($result)) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = ($row['ca_id'] === $ca_id) ? ' class="sct_ct_here" aria-current="page"' : '';
$str .= '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.$row['ca_name'].' <span class="prd_cnt">'.$row2['cnt'].'</span></a></li>';
$exists = true;
}
if ($exists) {
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
$category_groups = get_shop_category_menu_groups($ca_id);
if ($category_groups) {
add_stylesheet('<link rel="stylesheet" href="'.G5_SHOP_CSS_URL.'/style.css">', 0);
?>
<!-- 상품분류 1 시작 { -->
<aside id="sct_ct_1" class="sct_ct">
<h2>현재 상품 분류와 관련된 분류</h2>
<ul>
<?php echo $str; ?>
<?php foreach ($category_groups as $category_group) { ?>
<ul aria-label="<?php echo $category_group['label']; ?>">
<?php foreach ($category_group['categories'] as $row) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = '';
if ($row['ca_id'] === $ca_id) {
$current_attr = ' class="sct_ct_here" aria-current="page"';
} elseif (strpos($ca_id, $row['ca_id']) === 0) {
$current_attr = ' class="sct_ct_here sct_ct_parent"';
}
echo '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.get_text($row['ca_name']).' <span class="prd_cnt">'.$row2['cnt'].'</span></a></li>';
} ?>
</ul>
<?php } ?>
</aside>
<!-- } 상품분류 1 끝 -->
<?php }
<?php }
+17 -36
View File
@@ -1,44 +1,25 @@
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
if (!defined('_GNUBOARD_')) exit;
$str = '';
$exists = false;
$ca_id_len = strlen($ca_id);
$len2 = $ca_id_len + 2;
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$ca_id%' and length(ca_id) = $len2 and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
// 하위 분류가 없으면 현재 분류를 포함한 같은 단계의 사용 중인 분류를 표시한다.
if (!sql_num_rows($result)) {
$parent_ca_id = substr($ca_id, 0, -2);
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$parent_ca_id%' and length(ca_id) = $ca_id_len and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
}
while ($row=sql_fetch_array($result)) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = ($row['ca_id'] === $ca_id) ? ' class="sct_ct_here" aria-current="page"' : '';
$str .= '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.$row['ca_name'].' ('.$row2['cnt'].')</a></li>';
$exists = true;
}
if ($exists) {
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
$category_groups = get_shop_category_menu_groups($ca_id);
if ($category_groups) {
add_stylesheet('<link rel="stylesheet" href="'.G5_SHOP_SKIN_URL.'/style.css">', 0);
?>
<!-- 상품분류 1 시작 { -->
<aside id="sct_ct_1" class="sct_ct">
<h2>현재 상품 분류와 관련된 분류</h2>
<ul>
<?php echo $str; ?>
<?php foreach ($category_groups as $category_group) { ?>
<ul aria-label="<?php echo $category_group['label']; ?>">
<?php foreach ($category_group['categories'] as $row) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = '';
if ($row['ca_id'] === $ca_id) {
$current_attr = ' class="sct_ct_here" aria-current="page"';
} elseif (strpos($ca_id, $row['ca_id']) === 0) {
$current_attr = ' class="sct_ct_here sct_ct_parent"';
}
echo '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.get_text($row['ca_name']).' ('.$row2['cnt'].')</a></li>';
} ?>
</ul>
<?php } ?>
</aside>
<!-- } 상품분류 1 끝 -->
<?php }
<?php }
+10 -37
View File
@@ -1,24 +1,9 @@
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
$navi_datas = $ca_ids = array();
$is_item_view = (isset($it_id) && isset($it) && isset($it['it_id']) && $it_id === $it['it_id']) ? true : false;
if( !$is_item_view && $ca_id ){
$navi_datas = get_shop_navigation_data(true, $ca_id);
$ca_ids = array(
'ca_id' => substr($ca_id,0,2),
'ca_id2' => substr($ca_id,0,4),
'ca_id3' => substr($ca_id,0,6),
);
} else if( $is_item_view && isset($it) && is_array($it) ) {
$navi_datas = get_shop_navigation_data(true, $it['ca_id']);
$ca_ids = array(
'ca_id' => substr($it['ca_id'],0,2),
'ca_id2' => substr($it['ca_id'],0,4),
'ca_id3' => substr($it['ca_id'],0,6)
);
}
$is_item_view = (isset($it_id, $it['it_id']) && $it_id === $it['it_id']);
$navigation_ca_id = $is_item_view ? $it['ca_id'] : $ca_id;
$navi_datas = $navigation_ca_id ? get_shop_navigation_data(true, $navigation_ca_id) : array();
$location_class = array();
if($is_item_view){
@@ -27,7 +12,7 @@ if($is_item_view){
$location_class[] = 'is_list is_right'; // view_location는 리스트 말고 상품보기에서만 표시
}
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
// add_stylesheet('css 구문', 출력순서);
add_stylesheet('<link rel="stylesheet" href="'.G5_SHOP_CSS_URL.'/style.css">', 0);
add_javascript('<script src="'.G5_JS_URL.'/shop.category.navigation.js"></script>', 10);
?>
@@ -37,26 +22,14 @@ add_javascript('<script src="'.G5_JS_URL.'/shop.category.navigation.js"></script
<i class="dividing-line fa fa-angle-right" aria-hidden="true"></i>
<?php if ( is_array($navi_datas) && $navi_datas ){ ?>
<?php if( isset($navi_datas[0]) && $navi_datas[0] ){ ?>
<select class="shop_hover_selectbox category1">
<?php foreach((array) $navi_datas[0] as $data ){ ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>" <?php if($ca_ids['ca_id'] === $data['ca_id']) echo 'selected'; ?>><?php echo $data['ca_name']; ?></option>
<?php } ?>
</select>
<?php } ?>
<?php if( isset($navi_datas[1]) && $navi_datas[1] ){ ?>
<?php foreach ($navi_datas as $depth => $categories) {
$selected_ca_id = substr($navigation_ca_id, 0, ($depth + 1) * 2);
if ($depth > 0) { ?>
<i class="dividing-line fa fa-angle-right" aria-hidden="true"></i>
<select class="shop_hover_selectbox category2">
<?php foreach((array) $navi_datas[1] as $data ){ ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>" <?php if($ca_ids['ca_id2'] === $data['ca_id']) echo 'selected'; ?>><?php echo $data['ca_name']; ?></option>
<?php } ?>
</select>
<?php } ?>
<?php if( isset($navi_datas[2]) && $navi_datas[2] ){ ?>
<i class="dividing-line fa fa-angle-right" aria-hidden="true"></i>
<select class="shop_hover_selectbox category3">
<?php foreach((array) $navi_datas[2] as $data ){ ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>" <?php if($ca_ids['ca_id3'] === $data['ca_id']) echo 'selected'; ?>><?php echo $data['ca_name']; ?></option>
<select class="shop_hover_selectbox category<?php echo $depth + 1; ?>" aria-label="<?php echo $depth + 1; ?>단계 분류">
<?php foreach ($categories as $data) { ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>"<?php if ($selected_ca_id === $data['ca_id']) echo ' selected'; ?>><?php echo get_text($data['ca_name']); ?></option>
<?php } ?>
</select>
<?php } ?>
+44
View File
@@ -0,0 +1,44 @@
// 실행: NODE_PATH=<Playwright 경로>/node_modules CHROME_PATH=<Chromium 실행 파일> node tests/shop_category_layout.js
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const {execFileSync} = require('child_process');
const {chromium} = require('playwright');
const root = path.dirname(__dirname);
const read = file => fs.readFileSync(path.join(root, file), 'utf8');
const fixtures = JSON.parse(execFileSync('php', [path.join(__dirname, 'shop_category_navigation.php'), '--json'], {encoding:'utf8'}));
(async () => {
const browser = await chromium.launch({headless:true, ...(process.env.CHROME_PATH ? {executablePath:process.env.CHROME_PATH} : {}), args:['--no-sandbox']});
try {
for (const skin of ['skin/shop/basic', 'theme/basic/skin/shop/basic']) {
for (const view of ['list', 'item']) {
const page = await browser.newPage({viewport:{width:1920, height:1080}});
let baseline;
for (const id of ['10', '101010', '10101010', '1010101010']) {
let html = fixtures[skin][id].replace(/<script>[\s\S]*?<\/script>/g, '');
if (view === 'list') html = html.replace('view_location', 'is_list is_right');
await page.setContent('<style>'+read(skin.startsWith('theme/') ? 'theme/basic/css/default_shop.css' : 'css/default_shop.css')+'\n'+read(skin+'/style.css')+'</style><div id="container"><div class="shop-content"><div id="wrapper_title">상품리스트</div><div class="sct_admin"><a>분류 관리</a></div><div id="sct">'+html+'<div id="sct_sortlst">상품 정렬</div></div></div></div>');
await page.addScriptTag({content:read('js/jquery-1.12.4.min.js')});
await page.addScriptTag({content:read('js/shop.category.navigation.js')});
await page.evaluate(() => new Promise(resolve => jQuery(() => {
jQuery('select.shop_hover_selectbox').shop_select_to_html();
resolve();
})));
const layout = await page.evaluate(() => {
const nav = document.getElementById('sct_location');
const rect = nav.getBoundingClientRect();
return {top:rect.top, height:rect.height, position:getComputedStyle(nav).position,
menuTop:document.getElementById('sct_ct_1').getBoundingClientRect().top,
sortTop:document.getElementById('sct_sortlst').getBoundingClientRect().top};
});
if (!baseline) baseline = layout;
assert.deepStrictEqual(layout, baseline, skin+' '+view+' '+id+' 단계 변경 시 레이아웃 유지');
assert.strictEqual(await page.locator('.shop_select_to_html').count(), id.length / 2);
assert.strictEqual(await page.locator('#sct_ct_1 ul').count(), 1);
}
await page.close();
}
}
console.log('PC·basic 테마 목록/상세: 1·3·4·5단계 breadcrumb 위치·높이와 메뉴·정렬 영역 위치 동일');
} finally { await browser.close(); }
})().catch(error => { console.error(error); process.exitCode = 1; });
+79
View File
@@ -0,0 +1,79 @@
<?php
// 실행: php tests/shop_category_navigation.php [--json]
// DB 대신 분류 조회 대역을 사용하여 실제 공통 함수와 스킨을 실행한다.
define('_GNUBOARD_', true);
define('G5_SHOP_CSS_URL', '/css');
define('G5_SHOP_SKIN_URL', '/skin');
define('G5_SHOP_URL', '/shop');
define('G5_JS_URL', '/js');
$g5 = array('g5_shop_category_table'=>'categories', 'g5_shop_item_table'=>'items', 'title'=>'분류');
$fixture_ids = array('10','20','1010','1020','101010','101020','10101010','10101020','1010101010','1010101020');
function run_replace($name, $data, $cache) { return $data; }
function shop_category_url($id) { return '/shop/list.php?ca_id='.$id; }
function get_text($text) { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); }
function add_stylesheet($html, $priority) {}
function add_javascript($html, $priority) {}
function sql_query($sql) {
global $fixture_ids;
preg_match("/ca_id like '([^']*)%'/", $sql, $prefix);
preg_match("/length\(ca_id\) = '?([0-9]+)/", $sql, $length);
$result = (object)array('rows'=>array(), 'index'=>0);
foreach ($fixture_ids as $id) {
if ((!isset($prefix[1]) || strpos($id, $prefix[1]) === 0) && strlen($id) == $length[1]) {
$result->rows[] = array('ca_id'=>$id, 'ca_name'=>'분류 '.$id);
}
}
return $result;
}
function sql_fetch_array($result) { return isset($result->rows[$result->index]) ? $result->rows[$result->index++] : false; }
function sql_fetch($sql) { return array('cnt'=>3); }
function expect_category($condition, $message) { if (!$condition) throw new RuntimeException($message); }
require dirname(__DIR__).'/lib/shop.data.lib.php';
$artifacts = array();
$cases = array(
'10'=>array(array('1010','1020')),
'20'=>array(array('10','20')),
'1010'=>array(array('101010','101020')),
'101010'=>array(array('10101010','10101020')),
'101020'=>array(array('101010','101020')),
'10101010'=>array(array('1010101010','1010101020')),
'10101020'=>array(array('10101010','10101020')),
'1010101010'=>array(array('1010101010','1010101020')),
);
foreach ($cases as $code=>$expected) {
$ca_id = (string)$code;
$groups = get_shop_category_menu_groups($ca_id);
$actual = array();
foreach ($groups as $group) {
$ids = array();
foreach ($group['categories'] as $row) $ids[] = $row['ca_id'];
$actual[] = $ids;
}
expect_category($actual === $expected, $ca_id.' 메뉴 단계');
foreach (array('skin/shop/basic', 'theme/basic/skin/shop/basic') as $skin) {
foreach (array(false, true) as $item_view) {
$it_id = $item_view ? 'item' : '';
$it = $item_view ? array('it_id'=>'item', 'ca_id'=>$ca_id) : array();
ob_start(); include dirname(__DIR__).'/'.$skin.'/navigation.skin.php'; $nav = ob_get_clean();
preg_match_all('/value="([0-9]+)"[^>]* selected/', $nav, $selected);
$path = array();
for ($depth=1; $depth<=strlen($ca_id)/2; $depth++) $path[] = substr($ca_id, 0, $depth*2);
expect_category($selected[1] === $path, $skin.' '.$ca_id.' breadcrumb 현재 경로');
$artifacts[$skin][$ca_id] = $nav;
}
}
foreach (array('skin/shop/basic', 'theme/basic/skin/shop/basic', 'mobile/skin/shop/basic', 'theme/basic/mobile/skin/shop/basic') as $skin) {
ob_start(); include dirname(__DIR__).'/'.$skin.'/listcategory.skin.php'; $menu = ob_get_clean();
preg_match_all('/href="\/shop\/list.php\?ca_id=([0-9]+)"/', $menu, $links);
$flattened = array(); foreach ($expected as $group) $flattened = array_merge($flattened, $group);
expect_category($links[1] === $flattened, $skin.' '.$ca_id.' 메뉴 링크');
preg_match_all('/aria-current="page" href="\/shop\/list.php\?ca_id=([0-9]+)"/', $menu, $selected);
expect_category($selected[1] === (in_array($ca_id, $flattened, true) ? array($ca_id) : array()), $skin.' 현재 메뉴 표시');
$artifacts[$skin][$ca_id] = (isset($artifacts[$skin][$ca_id]) ? $artifacts[$skin][$ca_id] : '').$menu;
}
}
// 5단계 전체 트리를 전역 메뉴에 추가하지 않았는지 확인한다.
$tree = get_shop_category_array(true);
expect_category(!isset($tree['10']['1010']['101010']['10101010']), '공통 분류 트리 호환성');
if (isset($argv[1]) && $argv[1] === '--json') echo json_encode($artifacts);
else echo "8개 분류 경로: PC·테마 breadcrumb 목록/상세 및 4개 스킨 메뉴·선택 상태 통과\n";
@@ -1,44 +1,25 @@
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
if (!defined('_GNUBOARD_')) exit;
$str = '';
$exists = false;
$ca_id_len = strlen($ca_id);
$len2 = $ca_id_len + 2;
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$ca_id%' and length(ca_id) = $len2 and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
// 하위 분류가 없으면 현재 분류를 포함한 같은 단계의 사용 중인 분류를 표시한다.
if (!sql_num_rows($result)) {
$parent_ca_id = substr($ca_id, 0, -2);
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$parent_ca_id%' and length(ca_id) = $ca_id_len and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
}
while ($row=sql_fetch_array($result)) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = ($row['ca_id'] === $ca_id) ? ' class="sct_ct_here" aria-current="page"' : '';
$str .= '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.$row['ca_name'].' <span class="prd_cnt">'.$row2['cnt'].'</span></a></li>';
$exists = true;
}
if ($exists) {
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
$category_groups = get_shop_category_menu_groups($ca_id);
if ($category_groups) {
add_stylesheet('<link rel="stylesheet" href="'.G5_SHOP_CSS_URL.'/style.css">', 0);
?>
<!-- 상품분류 1 시작 { -->
<aside id="sct_ct_1" class="sct_ct">
<h2>현재 상품 분류와 관련된 분류</h2>
<ul>
<?php echo $str; ?>
<?php foreach ($category_groups as $category_group) { ?>
<ul aria-label="<?php echo $category_group['label']; ?>">
<?php foreach ($category_group['categories'] as $row) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = '';
if ($row['ca_id'] === $ca_id) {
$current_attr = ' class="sct_ct_here" aria-current="page"';
} elseif (strpos($ca_id, $row['ca_id']) === 0) {
$current_attr = ' class="sct_ct_here sct_ct_parent"';
}
echo '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.get_text($row['ca_name']).' <span class="prd_cnt">'.$row2['cnt'].'</span></a></li>';
} ?>
</ul>
<?php } ?>
</aside>
<!-- } 상품분류 1 끝 -->
<?php }
<?php }
@@ -1,44 +1,25 @@
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
if (!defined('_GNUBOARD_')) exit;
$str = '';
$exists = false;
$ca_id_len = strlen($ca_id);
$len2 = $ca_id_len + 2;
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$ca_id%' and length(ca_id) = $len2 and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
// 하위 분류가 없으면 현재 분류를 포함한 같은 단계의 사용 중인 분류를 표시한다.
if (!sql_num_rows($result)) {
$parent_ca_id = substr($ca_id, 0, -2);
$sql = " select ca_id, ca_name from {$g5['g5_shop_category_table']} where ca_id like '$parent_ca_id%' and length(ca_id) = $ca_id_len and ca_use = '1' order by ca_order, ca_id ";
$result = sql_query($sql);
}
while ($row=sql_fetch_array($result)) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = ($row['ca_id'] === $ca_id) ? ' class="sct_ct_here" aria-current="page"' : '';
$str .= '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.$row['ca_name'].' ('.$row2['cnt'].')</a></li>';
$exists = true;
}
if ($exists) {
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
$category_groups = get_shop_category_menu_groups($ca_id);
if ($category_groups) {
add_stylesheet('<link rel="stylesheet" href="'.G5_SHOP_SKIN_URL.'/style.css">', 0);
?>
<!-- 상품분류 1 시작 { -->
<aside id="sct_ct_1" class="sct_ct">
<h2>현재 상품 분류와 관련된 분류</h2>
<ul>
<?php echo $str; ?>
<?php foreach ($category_groups as $category_group) { ?>
<ul aria-label="<?php echo $category_group['label']; ?>">
<?php foreach ($category_group['categories'] as $row) {
$row2 = sql_fetch(" select count(*) as cnt from {$g5['g5_shop_item_table']} where (ca_id like '{$row['ca_id']}%' or ca_id2 like '{$row['ca_id']}%' or ca_id3 like '{$row['ca_id']}%') and it_use = '1' ");
$current_attr = '';
if ($row['ca_id'] === $ca_id) {
$current_attr = ' class="sct_ct_here" aria-current="page"';
} elseif (strpos($ca_id, $row['ca_id']) === 0) {
$current_attr = ' class="sct_ct_here sct_ct_parent"';
}
echo '<li><a'.$current_attr.' href="'.shop_category_url($row['ca_id']).'">'.get_text($row['ca_name']).' ('.$row2['cnt'].')</a></li>';
} ?>
</ul>
<?php } ?>
</aside>
<!-- } 상품분류 1 끝 -->
<?php }
<?php }
+10 -37
View File
@@ -1,24 +1,9 @@
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
$navi_datas = $ca_ids = array();
$is_item_view = (isset($it_id) && isset($it) && isset($it['it_id']) && $it_id === $it['it_id']) ? true : false;
if( !$is_item_view && $ca_id ){
$navi_datas = get_shop_navigation_data(true, $ca_id);
$ca_ids = array(
'ca_id' => substr($ca_id,0,2),
'ca_id2' => substr($ca_id,0,4),
'ca_id3' => substr($ca_id,0,6),
);
} else if( $is_item_view && isset($it) && is_array($it) ) {
$navi_datas = get_shop_navigation_data(true, $it['ca_id']);
$ca_ids = array(
'ca_id' => substr($it['ca_id'],0,2),
'ca_id2' => substr($it['ca_id'],0,4),
'ca_id3' => substr($it['ca_id'],0,6)
);
}
$is_item_view = (isset($it_id, $it['it_id']) && $it_id === $it['it_id']);
$navigation_ca_id = $is_item_view ? $it['ca_id'] : $ca_id;
$navi_datas = $navigation_ca_id ? get_shop_navigation_data(true, $navigation_ca_id) : array();
$location_class = array();
if($is_item_view){
@@ -27,7 +12,7 @@ if($is_item_view){
$location_class[] = 'is_list is_right'; // view_location는 리스트 말고 상품보기에서만 표시
}
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
// add_stylesheet('css 구문', 출력순서);
add_stylesheet('<link rel="stylesheet" href="'.G5_SHOP_CSS_URL.'/style.css">', 0);
add_javascript('<script src="'.G5_JS_URL.'/shop.category.navigation.js"></script>', 10);
?>
@@ -37,26 +22,14 @@ add_javascript('<script src="'.G5_JS_URL.'/shop.category.navigation.js"></script
<i class="dividing-line fa fa-angle-right" aria-hidden="true"></i>
<?php if ( is_array($navi_datas) && $navi_datas ){ ?>
<?php if( isset($navi_datas[0]) && $navi_datas[0] ){ ?>
<select class="shop_hover_selectbox category1">
<?php foreach((array) $navi_datas[0] as $data ){ ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>" <?php if($ca_ids['ca_id'] === $data['ca_id']) echo 'selected'; ?>><?php echo $data['ca_name']; ?></option>
<?php } ?>
</select>
<?php } ?>
<?php if( isset($navi_datas[1]) && $navi_datas[1] ){ ?>
<?php foreach ($navi_datas as $depth => $categories) {
$selected_ca_id = substr($navigation_ca_id, 0, ($depth + 1) * 2);
if ($depth > 0) { ?>
<i class="dividing-line fa fa-angle-right" aria-hidden="true"></i>
<select class="shop_hover_selectbox category2">
<?php foreach((array) $navi_datas[1] as $data ){ ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>" <?php if($ca_ids['ca_id2'] === $data['ca_id']) echo 'selected'; ?>><?php echo $data['ca_name']; ?></option>
<?php } ?>
</select>
<?php } ?>
<?php if( isset($navi_datas[2]) && $navi_datas[2] ){ ?>
<i class="dividing-line fa fa-angle-right" aria-hidden="true"></i>
<select class="shop_hover_selectbox category3">
<?php foreach((array) $navi_datas[2] as $data ){ ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>" <?php if($ca_ids['ca_id3'] === $data['ca_id']) echo 'selected'; ?>><?php echo $data['ca_name']; ?></option>
<select class="shop_hover_selectbox category<?php echo $depth + 1; ?>" aria-label="<?php echo $depth + 1; ?>단계 분류">
<?php foreach ($categories as $data) { ?>
<option value="<?php echo $data['ca_id']; ?>" data-url="<?php echo $data['url']; ?>"<?php if ($selected_ca_id === $data['ca_id']) echo ' selected'; ?>><?php echo get_text($data['ca_name']); ?></option>
<?php } ?>
</select>
<?php } ?>
+1 -1
View File
@@ -2,7 +2,7 @@
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
define('G5_VERSION', '그누보드5');
define('G5_GNUBOARD_VER', '5.6.39');
define('G5_GNUBOARD_VER', '5.6.391');
// 그누보드5.4.5.5 버전과 영카트5.4.5.5.1 버전을 합쳐서 그누보드5.4.6 버전에서 시작함 (kagla-210617)
// G5_YOUNGCART_VER 이 상수를 사용하는 곳이 있으므로 주석 처리 해제함
// 그누보드5.4.6 이상 버전 부터는 영카트를 그누보드에 포함하여 배포하므로 영카트5의 버전은 의미가 없습니다.