/** * 리스트 숏URL 생성 (+ 그누보드 qstr 지원, sca/wr_1/wr_2 제거) */ function msgv_store_url($area1 = '', $area2 = '', $theme = '', $qstr = '') { $area1 = trim((string)$area1); $area2 = trim((string)$area2); $theme = trim((string)$theme); $qstr = trim((string)$qstr); $sanitize = function($v){ return preg_replace('~[^0-9a-zA-Z_-]+~', '', $v); }; // ✅ 보정 규칙 if ($theme !== '' && $area1 === '' && $area2 === '') { // theme만 $area1 = 'all'; $area2 = 'all'; } if ($theme !== '' && $area1 !== '' && $area2 === '') { // area1+theme만 $area2 = 'all'; } if ($area2 !== '' && $area1 === '') { // area2만(방어) $area1 = 'all'; } $parts = ['stores']; if ($area1 !== '') $parts[] = $sanitize($area1); if ($area2 !== '') $parts[] = $sanitize($area2); if ($theme !== '') $parts[] = $sanitize($theme); $url = G5_URL . '/' . implode('/', $parts); // ✅ qstr 처리: sca/wr_1/wr_2는 URL path에 이미 들어가므로 제거 if ($qstr !== '') { $qs = ltrim($qstr, "?& \t\n\r\0\x0B"); // 앞에 ? & 제거 // parse_str로 배열화 $params = []; parse_str($qs, $params); // 제거할 키들 unset($params['sca'], $params['wr_1'], $params['wr_2']); // 값이 있는 것만 남기기 foreach ($params as $k => $v) { if (is_array($v)) { // 배열 파라미터는 비어있으면 제거 $v = array_filter($v, function($vv){ $vv = is_string($vv) ? trim($vv) : $vv; return !($vv === '' || $vv === null || $vv === false); }); if (empty($v)) unset($params[$k]); else $params[$k] = $v; } else { $vv = is_string($v) ? trim($v) : $v; if ($vv === '' || $vv === null || $vv === false) unset($params[$k]); else $params[$k] = $v; } } if (!empty($params)) { $url .= '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986); } } return $url; } /** 상세 숏URL */ function msgv_store_view_url($wr_id) { return G5_URL . '/stores/' . (int)$wr_id; } // 1) 지역(ca_name) slug -> 한글 function msgv_area_label($area1_slug) { global $msg_areas; $slug = trim((string)$area1_slug); if ($slug === '') return ''; return $msg_areas[$slug]['label'] ?? $slug; } // 2) 세부지역(wr_1) slug(콤마리스트) -> 한글 (all 처리 포함) function msgv_area2_label($area1_slug, $wr1_csv) { global $msg_areas; $area1_slug = trim((string)$area1_slug); $s = trim((string)$wr1_csv); if ($s === '') return ''; // 콤마 공백 통일 $s = preg_replace('~\s*,\s*~u', ',', $s); $subs = $msg_areas[$area1_slug]['subs'] ?? []; $out = []; foreach (explode(',', $s) as $tok) { $tok = trim($tok); if ($tok === '') continue; if ($tok === 'all') { // ✅ 전체 $out[] = '전체'; continue; } // subs는 ['slug'=>['label'=>..]] 또는 ['slug'=>'한글'] 둘다 대응 if (isset($subs[$tok])) { $out[] = is_array($subs[$tok]) ? ($subs[$tok]['label'] ?? $tok) : $subs[$tok]; } else { // 매핑 못 찾으면 원문 출력(안전) $out[] = $tok; } } return implode(', ', $out); } // 3) 테마(wr_2) slug(콤마리스트) -> 한글 function msgv_theme_label($wr2_csv) { global $msg_themes; $s = trim((string)$wr2_csv); if ($s === '') return ''; $s = preg_replace('~\s*,\s*~u', ',', $s); $out = []; foreach (explode(',', $s) as $tok) { $tok = trim($tok); if ($tok === '') continue; if (isset($msg_themes[$tok])) { $out[] = is_array($msg_themes[$tok]) ? ($msg_themes[$tok]['label'] ?? $tok) : $msg_themes[$tok]; } else { $out[] = $tok; } } return implode(', ', $out); } if (!function_exists('msgv_discount_pct')) { function msgv_discount_pct($orig, $sale){ $orig = (int)preg_replace('/\D/', '', (string)$orig); $sale = (int)preg_replace('/\D/', '', (string)$sale); if($orig <= 0 || $sale <= 0) return 0; if($sale >= $orig) return 0; return (int)round((1 - ($sale / $orig)) * 100); } } // 숫자화 if (!function_exists('msgv_to_int_price')) { function msgv_to_int_price($v){ return (int)preg_replace('/\D/', '', (string)$v); } } if (!function_exists('msgv_price')) { function msgv_price($v){ $v = (int)preg_replace('/\D/', '', (string)$v); return $v > 0 ? number_format($v).'원' : ''; } } function seo_area_label($sec1, $msg_areas){ if($sec1 === 'all' || $sec1 === '' || !isset($msg_areas[$sec1])) return '전체'; return $msg_areas[$sec1]['label'] ?? $sec1; } function seo_theme_label($sec3, $msg_themes){ if($sec3 === 'all' || $sec3 === '' || !isset($msg_themes[$sec3])) return '전체'; return $msg_themes[$sec3]['label'] ?? $sec3; } function seo_sub_label($sec1, $sec2, $msg_areas){ // sec2는 'all'이면 '전체' if($sec2 === 'all' || $sec2 === '') return '전체'; // 지역이 all이면 세부도 전체로 보는게 자연스러움 if($sec1 === 'all' || $sec1 === '' || !isset($msg_areas[$sec1])) return '전체'; if(isset($msg_areas[$sec1]['subs'][$sec2])){ $info = $msg_areas[$sec1]['subs'][$sec2]; if(is_array($info) && isset($info['label'])) return $info['label']; if(is_string($info) && $info !== '') return $info; } // 혹시 배열에 없으면 slug 그대로라도 보여주기 return $sec2; } Fatal error: Uncaught Error: Call to undefined function msgv_store_view_url() in /gosu77/www/extend/massage.config.php:384 Stack trace: #0 /gosu77/www/common.php(846): include_once() #1 /gosu77/www/bbs/_common.php(2): include_once('/gosu77/www/com...') #2 /gosu77/www/bbs/board.php(2): include_once('/gosu77/www/bbs...') #3 {main} thrown in /gosu77/www/extend/massage.config.php on line 384