diff --git a/.gitignore b/.gitignore index 6f37804..b9be986 100644 --- a/.gitignore +++ b/.gitignore @@ -1,29 +1,23 @@ -# 백업 및 임시 파일 (요청하신 부분) +# ========================================== +# 1. 공통 무시 설정 (OS, 에디터, 로그, 임시파일) +# ========================================== *.bak *.tmp *.temp *~ ~* - -# OS 자동 생성 시스템 파일 .DS_Store Thumbs.db desktop.ini - -# 로그 및 런타임 파일 *.log npm-debug.log* yarn-debug.log* yarn-error.log* - -# 환경 변수 및 비밀번호 (보안 필수) .env .env.local .env.development.local .env.test.local .env.production.local - -# IDE 및 편집기 설정 파일 .idea/ .vscode/ *.suo @@ -32,35 +26,42 @@ yarn-error.log* *.sln *.swp -# 1. 먼저 프로젝트 루트의 모든 파일과 폴더를 제외합니다. +# ========================================== +# 2. 프로젝트 최상위 화이트리스트 (전체 차단 후 허용) +# ========================================== +# 최상위 경로의 모든 파일과 폴더를 우선 제외합니다. /* -# 2. 필수 설정 파일들은 예외로 두어 Git 관리 대상에 포함합니다. +# 최상위 경로에서 추적할 파일만 예외로 허용합니다. !.gitignore !.env.example !docker-compose.yml -# 상위폴더 권한허용 +# web 폴더 내부로 Git이 접근할 수 있도록 허용합니다. !/web/ +#/web/* + +# ========================================== +# 3. web 폴더 내부 설정 +# ========================================== +# 🎯 conf.d 폴더와 그 내부의 파일(.ini 포함) 모두 추적 허용 +!/web/conf.d/ + +# html 폴더로 접근 허용 !/web/html/ + +# html 폴더 안의 모든 것을 기본적으로 무시합니다. /web/html/* -# 3. theme 폴더와 그 내부의 모든 것을 포함합니다. +# 🎯 html 폴더 안에서 실제로 추적할 폴더만 예외 처리 +# (이렇게 폴더 자체를 예외 처리하면 내부의 모든 파일과 하위 폴더가 자동으로 추적됩니다) !/web/html/theme/ -/web/html/theme/* -!/web/html/theme/*/ -/web/html/theme/basic/ - -# 4. extend 폴더와 그 내부의 모든 것을 포함합니다. +/web/html/theme/basic !/web/html/extend/ -/web/html/extend/* -!/web/html/extend/*/ -!/web/conf.d/ -/web/conf.d/* -!/web/conf.d/*/ - -# (선택) 만약 db 폴더나 web/data 등 docker 실행 파일들이 루트에 있다면 -# 위에서 /* 로 이미 제외되었기 때문에 안전하지만, 명시적으로 적어주어도 좋습니다. +# ========================================== +# 4. 명시적 제외 구역 +# ========================================== +# (참고: 상단의 /* 와 /web/html/* 로 이미 무시되었지만 확실히 명시) /db/ /web/html/data/ diff --git a/web/html/extend/.htaccess b/web/html/extend/.htaccess new file mode 100644 index 0000000..05196c0 --- /dev/null +++ b/web/html/extend/.htaccess @@ -0,0 +1 @@ +# .htaccess diff --git a/web/html/extend/clientip.extend.php b/web/html/extend/clientip.extend.php new file mode 100644 index 0000000..7628136 --- /dev/null +++ b/web/html/extend/clientip.extend.php @@ -0,0 +1,4 @@ +no_profile'); + +define('G5_USE_MEMBER_IMAGE_FILETIME', TRUE); + +// 썸네일 처리 방식, 비율유지 하지 않고 썸네일을 생성하려면 주석을 풀고 값은 false 입력합니다. ( true 또는 주석으로 된 경우에는 비율 유지합니다. ) +//define('G5_USE_THUMB_RATIO', false); \ No newline at end of file diff --git a/web/html/extend/firstgarden.php b/web/html/extend/firstgarden.php new file mode 100644 index 0000000..4bcc8d6 --- /dev/null +++ b/web/html/extend/firstgarden.php @@ -0,0 +1,224 @@ + 상품코드) +$annual_items = [ + '빅5' => '1744799759', + '일반' => '1744817586', +]; + + +// 퍼스트가든 관리페이지 adm 페이지로 전환 +// /adm/admin.menuXXX.php 파일이 없는 경우, 새 메뉴 그룹이 없기 때문에, 강제로 메뉴파일 배열을 추가 hook (gnuwiz) +if(! function_exists('add_admin_amenu_update') ) { + add_replace('admin_amenu', 'add_admin_amenu_update', 1, 1); + function add_admin_amenu_update($amenu) { + $amenu['998'] = ''; + return $amenu; + } +} + +// 관리자메뉴에 커스텀 메뉴를 동적으로 추가 hook (gnuwiz) +if(! function_exists('add_admin_menu_update') ) { + add_replace('admin_menu', 'add_admin_menu_update', 1, 1); + function add_admin_menu_update($menu) { + $menu['menu998'] = array(); + array_push($menu['menu998'], + array('998000', '퍼스트가든', G5_ADMIN_URL . '/fg_admin/bakery/bakery_stock.php', 'firstgarden'), + array('998010', '베이커리 재고관리', G5_ADMIN_URL . '/fg_admin/bakery/bakery_stock_adm.php', 'firstgarden'), + array('998020', '베이커리 목록관리', G5_ADMIN_URL . '/fg_admin/bakery/bakery_product_list.php', 'firstgarden'), + array('998210', 'VIP 명단관리', G5_ADMIN_URL . '/fg_admin/vip/vip_list.php', 'firstgarden'), + array('998220', 'VIP 구분관리', G5_ADMIN_URL . '/fg_admin/vip/vip_list_category.php', 'firstgarden'), + array('998310', '연간회원 명단관리', G5_ADMIN_URL . '/fg_admin/annual_member/annual_member_list.php', 'firstgarden'), + array('998320', '연간회원 구분관리', G5_ADMIN_URL . '/fg_admin/annual_member/annual_member_category.php', 'firstgarden'), + array('998411', '매표소주문확인', G5_ADMIN_URL.'/fg_admin/orderlist_ticket.php', 'firstgarden'), + array('998421', '혜윰주문확인', G5_ADMIN_URL.'/fg_admin/orderlist_hy.php', 'firstgarden'), + array('998431', 'B2B주문확인', G5_ADMIN_URL.'/fg_admin/orderlist_b2b.php', 'firstgarden'), + array('998412', '관리자주문확인', G5_ADMIN_URL . '/fg_admin/orderlist_admin.php', 'firstgarden'), + array('998413', '관지라월정산용', G5_ADMIN_URL . '/fg_admin/orderlist_admin_sum.php', 'firstgarden'), + ); + return $menu; + } +} + +// 새 글 작성 시 알림 +// add_event('write_update_after', 'curl_tele_sent' G5_HOOK_DEFAULT_PRIORITY, 5); + +// 텔레그램 메시지 보내기 +// 사용법 curl_tele_sent(메세지); +if(! function_exists('curl_tele_sent')) { + function curl_tele_sent($text){ + if(!$text){ + exit("No Data!!"); + } // end + + $ch = curl_init(); + $api_code = ""; // 900~ + $chat_id = ""; // 822~~ + $curl_url = "https://api.telegram.org/bot{$api_code}/sendMessage?chat_id={$chat_id}&text={$text}"; + @curl_setopt($ch, CURLOPT_URL, $curl_url); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + $exec = curl_exec($ch); + } // curl_tele_sent end +} + +// 주문이 실행되는 경우 연간회원권 주문인지 확인하고, 연간회원권이라면 회원정보 입력 페이지로 이동시킴 +if (!function_exists('add_annual_member')) { + function add_annual_member($od_id) { + global $g5, $annual_items; + + // 상품코드 배열만 추출 + $annu_item_code = array_values($annual_items); + + $sql = "SELECT it_id, ct_qty FROM {$g5['g5_shop_cart_table']} WHERE od_id = '{$od_id}'"; + $result = sql_query($sql); + + $total_qty = 0; + while ($row = sql_fetch_array($result)) { + if (in_array($row['it_id'], $annu_item_code)) { + $total_qty += (int)$row['ct_qty']; + } + } + + if ($total_qty > 0) { + send_annual_member_notice($od_id, $total_qty); + } + } + add_event('fg_orderformupdate_after', 'add_annual_member', G5_HOOK_DEFAULT_PRIORITY, 1); +} + +// SMS 발송 +function send_annual_member_notice($od_id, $qty) { + global $g5; + + $od = sql_fetch("SELECT od_name, od_hp, od_email FROM {$g5['g5_shop_order_table']} WHERE od_id = '{$od_id}'"); + + $link = G5_URL . "/manager/annu_member_insert.php?od_id={$od_id}"; + + $message = "주문하신 연간회원권 {$qty}건에 대한 회원정보 입력이 필요합니다.\n" + . "아래 링크를 통해 회원 정보를 입력해주세요:\n{$link}"; + + // SMS 발송 (예시) + annu_send_sms(preg_replace('/[^0-9]/', '', $od['od_hp']), $message); + + // 메일 발송 (예시) + /* + $subject = "연간회원권 회원정보 입력 안내"; + $body = "안녕하세요, {$od['od_name']}님.\n\n" + . "주문하신 연간회원권 {$qty}건에 대한 회원정보 입력이 필요합니다.\n" + . "아래 링크를 클릭하여 입력해주세요.\n\n" + . "{$link}\n\n감사합니다."; + send_mail($od['od_email'], $subject, $body); + *//* +} + +function annu_send_sms($phone, $message) { + global $config, $default, $g5; + + if (!$config['cf_sms_use'] || !$phone || !$message) { + return false; + } + + $recv_number = preg_replace("/[^0-9]/", "", $phone); + $send_number = preg_replace("/[^0-9]/", "", $default['de_admin_company_tel']); + + if (!$recv_number) { + return false; + } + + $sms_messages = [ + ['recv' => $recv_number, 'send' => $send_number, 'cont' => $message] + ]; + + $sms_count = 1; + + if ($sms_count > 0) { + if ($config['cf_sms_type'] == 'LMS') { + include_once(G5_LIB_PATH . '/icode.lms.lib.php'); + + $port_setting = get_icode_port_type($config['cf_icode_id'], $config['cf_icode_pw']); + if ($port_setting !== false) { + $SMS = new LMS; + $SMS->SMS_con($config['cf_icode_server_ip'], $config['cf_icode_id'], $config['cf_icode_pw'], $port_setting); + + foreach ($sms_messages as $sms) { + $strDest = [$sms['recv']]; + $strCallBack = $sms['send']; + $strCaller = iconv_euckr(trim($default['de_admin_company_name'])); + $strSubject = ''; + $strURL = ''; + $strData = iconv_euckr($sms['cont']); + $strDate = ''; + $nCount = count($strDest); + + $SMS->Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate, $nCount); + $SMS->Send(); + $SMS->Init(); + } + return true; + } + } else { + include_once(G5_LIB_PATH . '/icode.sms.lib.php'); + + $SMS = new SMS; + $SMS->SMS_con($config['cf_icode_server_ip'], $config['cf_icode_id'], $config['cf_icode_pw'], $config['cf_icode_server_port']); + + foreach ($sms_messages as $sms) { + $recv_number = $sms['recv']; + $send_number = $sms['send']; + $sms_content = iconv_euckr($sms['cont']); + + $SMS->Add($recv_number, $send_number, $config['cf_icode_id'], $sms_content, ""); + } + $SMS->Send(); + $SMS->Init(); + return true; + } + } + return false; +} + +*/ +// 전화번호에 하이픈 추가 +function add_hyphen($tel){ + $tel = preg_replace("/[^0-9]*/s","",$tel); //숫자이외 제거 + + if (substr($tel,0,2) =='02'){ + return preg_replace("/([0-9]{2})([0-9]{3,4})([0-9]{4})$/","\\1-\\2-\\3", $tel); + } else if(substr($tel,0,2) =='8' && substr($tel,0,2) =='15' || substr($tel,0,2) =='16'|| substr($tel,0,2) =='18' ) { + return preg_replace("/([0-9]{4})([0-9]{4})$/","\\1-\\2",$tel); // 지능망 번호이면 + } else { + return preg_replace("/([0-9]{3})([0-9]{3,4})([0-9]{4})$/","\\1-\\2-\\3" ,$tel); //핸드폰번호만 이용한다면 이것만있어도됨 + } + +} diff --git a/web/html/extend/g5_54version_update.extend.php b/web/html/extend/g5_54version_update.extend.php new file mode 100644 index 0000000..b3188ac --- /dev/null +++ b/web/html/extend/g5_54version_update.extend.php @@ -0,0 +1,69 @@ +'', 'cf_datetime'=>'', 'cf_phone'=>''); + +if (!empty($config['cf_sms_use'])) { + + $sms5 = sql_fetch("select * from {$g5['sms5_config_table']} ", false); + + // Demo 설정 + if (file_exists(G5_PATH.'/DEMO')) + { + // 받는 번호를 010-000-0000 으로 만듭니다. + $g5['sms5_demo'] = true; + + // 아이코드에 실제로 보내지 않고 가상(Random)으로 전송결과를 저장합니다. + $g5['sms5_demo_send'] = true; + } +} \ No newline at end of file diff --git a/web/html/extend/social_login.extend.php b/web/html/extend/social_login.extend.php new file mode 100644 index 0000000..8b8872b --- /dev/null +++ b/web/html/extend/social_login.extend.php @@ -0,0 +1,47 @@ +