PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/common.lib.php

https://github.com/rokmc820/g4dtd
PHP | 1583 lines | 1283 code | 135 blank | 165 comment | 149 complexity | 0905affef696c3ed809f3b16a68c429a MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. if (!defined('_GNUBOARD_')) exit;
  3. /*************************************************************************
  4. **
  5. ** 일반 함수 모음
  6. **
  7. *************************************************************************/
  8. // 마이크로 타임을 얻어 계산 형식으로 만듦
  9. function get_microtime()
  10. {
  11. list($usec, $sec) = explode(" ",microtime());
  12. return ((float)$usec + (float)$sec);
  13. }
  14. /**
  15. * @brief 디버그 메시지 출력
  16. * XpressEngine의 코드 차용. http://xpressengien.com/
  17. **/
  18. function debugPrint($debug_output = null) {
  19. $bt = debug_backtrace();
  20. if(is_array($bt)) $first = array_shift($bt);
  21. $file_name = $first['file'];
  22. $line_num = $first['line'];
  23. $debug_file = $g4['path'].'/data/_debug_message.php';
  24. $debug_output = sprintf("[%s %s:%d]\n%s\n",
  25. date('Y-m-d H:i:s'),
  26. $file_name,
  27. $line_num,
  28. print_r($debug_output, true)
  29. );
  30. $debug_output = '<?php exit(); ?>'.str_repeat('=', 40)."\n".$debug_output.str_repeat('-', 40)."\n\n";
  31. $fp = @fopen($debug_file, 'a');
  32. if(!$fp) return;
  33. fwrite($fp, $debug_output);
  34. fclose($fp);
  35. }
  36. // 현재페이지, 총페이지수, 한페이지에 보여줄 행, URL
  37. function get_paging($write_pages, $cur_page, $total_page, $url, $add="")
  38. {
  39. $str = "";
  40. if ($cur_page > 1) {
  41. $str .= "<a href='" . $url . "1{$add}'>처음</a>";
  42. //$str .= "[<a href='" . $url . ($cur_page-1) . "'>이전</a>]";
  43. }
  44. $start_page = ( ( (int)( ($cur_page - 1 ) / $write_pages ) ) * $write_pages ) + 1;
  45. $end_page = $start_page + $write_pages - 1;
  46. if ($end_page >= $total_page) $end_page = $total_page;
  47. if ($start_page > 1) $str .= " &nbsp;<a href='" . $url . ($start_page-1) . "{$add}'>이전</a>";
  48. if ($total_page > 1) {
  49. for ($k=$start_page;$k<=$end_page;$k++) {
  50. if ($cur_page != $k)
  51. $str .= " &nbsp;<a href='$url$k{$add}'><span>$k</span></a>";
  52. else
  53. $str .= " &nbsp;<strong>$k</strong> ";
  54. }
  55. }
  56. if ($total_page > $end_page) $str .= " &nbsp;<a href='" . $url . ($end_page+1) . "{$add}'>다음</a>";
  57. if ($cur_page < $total_page) {
  58. //$str .= "[<a href='$url" . ($cur_page+1) . "'>다음</a>]";
  59. $str .= " &nbsp;<a href='$url$total_page{$add}'>맨끝</a>";
  60. }
  61. $str .= "";
  62. return $str;
  63. }
  64. // 변수 또는 배열의 이름과 값을 얻어냄. print_r() 함수의 변형
  65. function print_r2($var)
  66. {
  67. ob_start();
  68. print_r($var);
  69. $str = ob_get_contents();
  70. ob_end_clean();
  71. $str = preg_replace("/ /", "&nbsp;", $str);
  72. echo nl2br("<span style='font-family:Tahoma, 굴림; font-size:9pt;'>$str</span>");
  73. }
  74. // 메타태그를 이용한 URL 이동
  75. // header("location:URL") 을 대체
  76. function goto_url($url)
  77. {
  78. echo "<meta http-equiv=\"content-type\" content=\"text/html; charset={$g4['charset']}\">";
  79. echo "<script type='text/javascript'> location.replace('$url'); </script>";
  80. exit;
  81. }
  82. // 세션변수 생성
  83. function set_session($session_name, $value)
  84. {
  85. if (PHP_VERSION < '5.3.0')
  86. session_register($session_name);
  87. // PHP 버전별 차이를 없애기 위한 방법
  88. $$session_name = $_SESSION["$session_name"] = $value;
  89. }
  90. // 세션변수값 얻음
  91. function get_session($session_name)
  92. {
  93. return $_SESSION[$session_name];
  94. }
  95. // 쿠키변수 생성
  96. function set_cookie($cookie_name, $value, $expire)
  97. {
  98. global $g4;
  99. setcookie(md5($cookie_name), base64_encode($value), $g4['server_time'] + $expire, '/', $g4['cookie_domain']);
  100. }
  101. // 쿠키변수값 얻음
  102. function get_cookie($cookie_name)
  103. {
  104. return base64_decode($_COOKIE[md5($cookie_name)]);
  105. }
  106. // 경고메세지를 경고창으로
  107. function alert($msg='', $url='')
  108. {
  109. global $g4;
  110. if (!$msg) $msg = '올바른 방법으로 이용해 주십시오.';
  111. echo "<meta http-equiv=\"content-type\" content=\"text/html; charset={$g4['charset']}\">";
  112. echo "<script type='text/javascript'>alert('$msg');";
  113. if (!$url)
  114. echo "history.go(-1);";
  115. echo "</script>";
  116. if ($url)
  117. goto_url($url);
  118. exit;
  119. }
  120. // 경고메세지 출력후 창을 닫음
  121. function alert_close($msg)
  122. {
  123. global $g4;
  124. echo "<meta http-equiv=\"content-type\" content=\"text/html; charset={$g4['charset']}\">";
  125. echo "<script type='text/javascript'> alert('$msg'); window.close(); </script>";
  126. exit;
  127. }
  128. // way.co.kr 의 wayboard 참고
  129. function url_auto_link($str)
  130. {
  131. global $config;
  132. $str = preg_replace("/&lt;/", "\t_lt_\t", $str);
  133. $str = preg_replace("/&gt;/", "\t_gt_\t", $str);
  134. $str = preg_replace("/&amp;/", "&", $str);
  135. $str = preg_replace("/&quot;/", "\"", $str);
  136. $str = preg_replace("/&nbsp;/", "\t_nbsp_\t", $str);
  137. $str = preg_replace("/([^(http:\/\/)]|\(|^)(www\.[^[:space:]]+)/i", "\\1<A HREF=\"http://\\2\" TARGET='{$config['cf_link_target']}'>\\2</A>", $str);
  138. $str = preg_replace("/([^(HREF=\"?'?)|(SRC=\"?'?)]|\(|^)((http|https|ftp|telnet|news|mms):\/\/[a-zA-Z0-9\.-]+\.[가-힣\xA1-\xFEa-zA-Z0-9\.:&#=_\?\/~\+%@;\-\|\,\(\)]+)/i", "\\1<A HREF=\"\\2\" TARGET='{$config['cf_link_target']}'>\\2</A>", $str);
  139. $str = preg_replace("/([0-9a-z]([-_\.]?[0-9a-z])*@[0-9a-z]([-_\.]?[0-9a-z])*\.[a-z]{2,4})/i", "<a href='mailto:\\1'>\\1</a>", $str);
  140. $str = preg_replace("/\t_nbsp_\t/", "&nbsp;" , $str);
  141. $str = preg_replace("/\t_lt_\t/", "&lt;", $str);
  142. $str = preg_replace("/\t_gt_\t/", "&gt;", $str);
  143. return $str;
  144. }
  145. // url에 http:// 를 붙인다
  146. function set_http($url)
  147. {
  148. if (!trim($url)) return;
  149. if (!preg_match("/^(http|https|ftp|telnet|news|mms)\:\/\//i", $url))
  150. $url = "http://" . $url;
  151. return $url;
  152. }
  153. // 파일의 용량을 구한다.
  154. function get_filesize($size)
  155. {
  156. //$size = @filesize(addslashes($file));
  157. if ($size >= 1048576) {
  158. $size = number_format($size/1048576, 1) . "M";
  159. } else if ($size >= 1024) {
  160. $size = number_format($size/1024, 1) . "K";
  161. } else {
  162. $size = number_format($size, 0) . "byte";
  163. }
  164. return $size;
  165. }
  166. // 게시글에 첨부된 파일을 얻는다. (배열로 반환)
  167. function get_file($bo_table, $wr_id, $board)
  168. {
  169. global $g4, $qstr;
  170. $file["count"] = 0;
  171. $sql = " select * from {$g4['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' order by bf_no ";
  172. $result = sql_query($sql);
  173. while ($row = sql_fetch_array($result))
  174. {
  175. $no = $row['bf_no'];
  176. $file[$no]['href'] = "./download.php?bo_table=$bo_table&amp;wr_id=$wr_id&amp;no=$no" . $qstr;
  177. $file[$no]['download'] = $row['bf_download'];
  178. $file[$no]['path'] = "{$g4['path']}/data/file/$bo_table";
  179. $file[$no]['size'] = get_filesize($row['bf_filesize']);
  180. $file[$no]['datetime'] = $row['bf_datetime'];
  181. $file[$no]['source'] = addslashes($row['bf_source']);
  182. $file[$no]['bf_content'] = $row['bf_content'];
  183. $file[$no]['content'] = get_text($row['bf_content']);
  184. $file[$no]['view'] = view_file_link($row['bf_file'], $row['bf_width'], $row['bf_height'], $file[$no]['content'], $board);
  185. $file[$no]['file'] = $row['bf_file'];
  186. $file[$no]['image_width'] = $row['bf_width'] ? $row['bf_width'] : 640;
  187. $file[$no]['image_height']= $row['bf_height'] ? $row['bf_height'] : 480;
  188. $file[$no]['image_type'] = $row['bf_type'];
  189. $file["count"]++;
  190. }
  191. return $file;
  192. }
  193. // 폴더의 용량 ($dir는 / 없이 넘기세요)
  194. function get_dirsize($dir)
  195. {
  196. $size = 0;
  197. $d = dir($dir);
  198. while ($entry = $d->read()) {
  199. if ($entry != "." && $entry != "..") {
  200. $size += filesize("$dir/$entry");
  201. }
  202. }
  203. $d->close();
  204. return $size;
  205. }
  206. /*************************************************************************
  207. **
  208. ** 그누보드 관련 함수 모음
  209. **
  210. *************************************************************************/
  211. // 게시물 정보($write_row)를 출력하기 위하여 $list로 가공된 정보를 복사 및 가공
  212. function get_list($write_row, $board, $skin_path, $subject_len=40)
  213. {
  214. global $g4, $config;
  215. global $qstr, $page;
  216. // 배열전체를 복사
  217. $list = $write_row;
  218. unset($write_row);
  219. $list['is_notice'] = preg_match("/[^0-9]{0,1}" .$list['wr_id'] . "[\r]{0,1}/",$board['bo_notice']);
  220. if ($subject_len)
  221. $list['subject'] = conv_subject($list['wr_subject'], $subject_len, "…");
  222. else
  223. $list['subject'] = conv_subject($list['wr_subject'], $board['bo_subject_len'], "…");
  224. // 목록에서 내용 미리보기 사용한 게시판만 내용을 변환함 (속도 향상) : kkal3(커피)님께서 알려주셨습니다.
  225. if ($board['bo_use_list_content'])
  226. {
  227. $html = 0;
  228. if (strstr($list['wr_option'], "html1"))
  229. $html = 1;
  230. else if (strstr($list['wr_option'], "html2"))
  231. $html = 2;
  232. $list['content'] = conv_content($list['wr_content'], $html);
  233. }
  234. $list['comment_cnt'] = "";
  235. if ($list['wr_comment'])
  236. $list['comment_cnt'] = "({$list['wr_comment']})";
  237. // 당일인 경우 시간으로 표시함
  238. $list['datetime'] = substr($list['wr_datetime'],0,10);
  239. $list['datetime2'] = $list['wr_datetime'];
  240. if ($list['datetime'] == $g4['time_ymd'])
  241. $list['datetime2'] = substr($list['datetime2'],11,5);
  242. else
  243. $list['datetime2'] = substr($list['datetime2'],5,5);
  244. // 4.1
  245. $list['last'] = substr($list['wr_last'],0,10);
  246. $list['last2'] = $list['wr_last'];
  247. if ($list['last'] == $g4['time_ymd'])
  248. $list['last2'] = substr($list['last2'],11,5);
  249. else
  250. $list['last2'] = substr($list['last2'],5,5);
  251. $list['wr_homepage'] = get_text(addslashes($list['wr_homepage']));
  252. if ($board['bo_use_sideview'])
  253. $list['name'] = get_sideview($list['mb_id'], $list['wr_name'], $list['wr_email'], $list['wr_homepage']);
  254. else
  255. $list['name'] = "<span class='".($list['mb_id']?'member':'guest')."'>{$list['wr_name']}</span>";
  256. $reply = $list['wr_reply'];
  257. $list['reply'] = "";
  258. if (strlen($reply) > 0)
  259. {
  260. for ($k=0; $k<strlen($reply); $k++)
  261. $list['reply'] .= "<span class='reply'></span>";
  262. }
  263. $list['icon_reply'] = "";
  264. if ($list['reply'])
  265. $list['icon_reply'] = "<img src='$skin_path/img/icon_reply.gif' alt='' class='icon_reply' />";
  266. $list['icon_link'] = "";
  267. if ($list['wr_link1'] || $list['wr_link2'])
  268. $list['icon_link'] = "<img src='$skin_path/img/icon_link.gif' alt='' />";
  269. // 분류명 링크
  270. $list['ca_name_href'] = "{$g4['bbs_path']}/board.php?bo_table={$board['bo_table']}&amp;sca=".urlencode($list['ca_name']);
  271. $list['href'] = "{$g4['bbs_path']}/board.php?bo_table={$board['bo_table']}&amp;wr_id={$list['wr_id']}" . $qstr;
  272. $list['comment_href'] = $list['href'];
  273. $list['icon_new'] = "";
  274. if ($list['wr_datetime'] >= date("Y-m-d H:i:s", $g4['server_time'] - ($board['bo_new'] * 3600)))
  275. $list['icon_new'] = "<img src='$skin_path/img/icon_new.gif' alt='' />";
  276. $list['icon_hot'] = "";
  277. if ($list['wr_hit'] >= $board['bo_hot'])
  278. $list['icon_hot'] = "<img src='$skin_path/img/icon_hot.gif' alt='' />";
  279. $list['icon_secret'] = "";
  280. if (strstr($list['wr_option'], "secret"))
  281. $list['icon_secret'] = "<img src='$skin_path/img/icon_secret.gif' alt='' />";
  282. // 링크
  283. for ($i=1; $i<=$g4['link_count']; $i++)
  284. {
  285. $list['link'][$i] = set_http(get_text($list["wr_link{$i}"]));
  286. $list['link_href'][$i] = "{$g4['bbs_path']}/link.php?bo_table={$board['bo_table']}&amp;wr_id={$list['wr_id']}&amp;no=$i" . $qstr;
  287. $list['link_hit'][$i] = (int)$list["wr_link{$i}_hit"];
  288. }
  289. // 가변 파일
  290. if ($list['wr_file'])
  291. $list['file'] = get_file($board['bo_table'], $list['wr_id'], $board);
  292. if ($list['file']['count'])
  293. $list['icon_file'] = "<img src='$skin_path/img/icon_file.gif' alt='' />";
  294. return $list;
  295. }
  296. // get_list 의 alias
  297. function get_view($write_row, $board, $skin_path, $subject_len=125)
  298. {
  299. return get_list($write_row, $board, $skin_path, $subject_len);
  300. }
  301. // set_search_font(), get_search_font() 함수를 search_font() 함수로 대체
  302. function search_font($stx, $str)
  303. {
  304. global $config;
  305. // 문자앞에 \ 를 붙입니다.
  306. $src = array("/", "|");
  307. $dst = array("\/", "\|");
  308. if (!trim($stx)) return $str;
  309. // 검색어 전체를 공란으로 나눈다
  310. $s = explode(" ", $stx);
  311. // "/(검색1|검색2)/i" 와 같은 패턴을 만듬
  312. $pattern = "";
  313. $bar = "";
  314. for ($m=0; $m<count($s); $m++) {
  315. if (trim($s[$m]) == "") continue;
  316. // 태그는 포함하지 않아야 하는데 잘 안되는군. ㅡㅡa
  317. //$pattern .= $bar . '([^<])(' . quotemeta($s[$m]) . ')';
  318. //$pattern .= $bar . quotemeta($s[$m]);
  319. //$pattern .= $bar . str_replace("/", "\/", quotemeta($s[$m]));
  320. $tmp_str = quotemeta($s[$m]);
  321. $tmp_str = str_replace($src, $dst, $tmp_str);
  322. $pattern .= $bar . $tmp_str . "(?![^<]*>)";
  323. $bar = "|";
  324. }
  325. // 지정된 검색 폰트의 색상, 배경색상으로 대체
  326. $replace = "<span style='background-color:{$config['cf_search_bgcolor']}; color:{$config['cf_search_color']};'>\\1</span>";
  327. return preg_replace("/($pattern)/i", $replace, $str);
  328. }
  329. // 제목을 변환
  330. function conv_subject($subject, $len, $suffix="")
  331. {
  332. return cut_str(get_text($subject), $len, $suffix);
  333. }
  334. // OBJECT 태그의 XSS 막기
  335. function bad120422($matches)
  336. {
  337. $code = $matches[1];
  338. if (preg_match("#script#i", $code)) {
  339. return "OBJECT 태그에 스크립트는 사용 불가합니다.";
  340. } else if (preg_match("#base64#i", $code)) {
  341. return "OBJECT 태그에 BASE64는 사용 불가합니다.";
  342. }
  343. }
  344. // 내용을 변환
  345. function conv_content($content, $html)
  346. {
  347. global $config, $board;
  348. if ($html)
  349. {
  350. $source = array();
  351. $target = array();
  352. $source[] = "//";
  353. $target[] = "";
  354. if ($html == 2) { // 자동 줄바꿈
  355. $source[] = "/\n/";
  356. $target[] = "<br/>";
  357. }
  358. // 테이블 태그의 갯수를 세어 테이블이 깨지지 않도록 한다.
  359. $table_begin_count = substr_count(strtolower($content), "<table");
  360. $table_end_count = substr_count(strtolower($content), "</table");
  361. for ($i=$table_end_count; $i<$table_begin_count; $i++)
  362. {
  363. $content .= "</table>";
  364. }
  365. $content = preg_replace($source, $target, $content);
  366. $content = bad_tag_convert($content);
  367. // XSS (Cross Site Script) 막기
  368. // 완벽한 XSS 방지는 없다.
  369. // object 태그에서 javascript 코드 막기
  370. $content = preg_replace_callback("#<object([^>]+)>#i", "bad120422", $content);
  371. // 081022 : CSRF 방지
  372. //$content = preg_replace("/(on)(abort|blur|change|click|dblclick|dragdrop|error|focus|keydown|keypress|keyup|load|mousedown|mousemove|mouseout|mouseover|mouseup|mouseenter|mouseleave|move|reset|resize|select|submit|unload)/i", "$1<!-- XSS Filter -->$2", $content);
  373. //$content = preg_replace("/(on)([^\=]+)/i", "&#111;&#110;$2", $content);
  374. // 이런 경우를 방지함 <IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">
  375. $content = preg_replace("#\/\*.*\*\/#iU", "", $content);
  376. $content = preg_replace("/(on)([a-z]+)([^a-z]*)(\=)/i", "&#111;&#110;$2$3$4", $content);
  377. $content = preg_replace("/(dy)(nsrc)/i", "&#100;&#121;$2", $content);
  378. $content = preg_replace("/(lo)(wsrc)/i", "&#108;&#111;$2", $content);
  379. $content = preg_replace("/(sc)(ript)/i", "&#115;&#99;$2", $content);
  380. //$content = preg_replace("/(ex)(pression)/i", "&#101&#120;$2", $content);
  381. $content = preg_replace("/\<(\w|\s|\?)*(xml)/i", "", $content);
  382. // 이미지 태그의 src 속성에 삭제등의 링크가 있는 경우 게시물을 확인하는 것만으로도 데이터의 위변조가 가능하므로 이것을 막음
  383. $content = preg_replace("/<(img[^>]+delete\.php[^>]+bo_table[^>]+)/i", "*** CSRF 감지 : &lt;$1", $content);
  384. $content = preg_replace("/<(img[^>]+delete_comment\.php[^>]+bo_table[^>]+)/i", "*** CSRF 감지 : &lt;$1", $content);
  385. $content = preg_replace("/<(img[^>]+logout\.php[^>]+)/i", "*** CSRF 감지 : &lt;$1", $content);
  386. $content = preg_replace("/<(img[^>]+download\.php[^>]+bo_table[^>]+)/i", "*** CSRF 감지 : &lt;$1", $content);
  387. // 이런 경우를 방지함 <IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">
  388. //$content = preg_replace("#\/\*.*\*\/#iU", "", $content); // 이 코드를 위로 올립니다.
  389. $pattern = "";
  390. $pattern .= "(e|&#(x65|101);?)";
  391. $pattern .= "(x|&#(x78|120);?)";
  392. $pattern .= "(p|&#(x70|112);?)";
  393. $pattern .= "(r|&#(x72|114);?)";
  394. $pattern .= "(e|&#(x65|101);?)";
  395. $pattern .= "(s|&#(x73|115);?)";
  396. $pattern .= "(s|&#(x73|115);?)";
  397. $pattern .= "(i|&#(x6a|105);?)";
  398. $pattern .= "(o|&#(x6f|111);?)";
  399. $pattern .= "(n|&#(x6e|110);?)";
  400. $content = preg_replace("/".$pattern."/i", "__EXPRESSION__", $content);
  401. /*
  402. $content = preg_replace("/\#/", "&#35;", $content);
  403. $content = preg_replace("/\</", "&lt;", $content);
  404. $content = preg_replace("/\>/", "&gt;", $content);
  405. $content = preg_replace("/\(/", "&#40;", $content);
  406. $content = preg_replace("/\)/", "&#41;", $content);
  407. */
  408. }
  409. else // text 이면
  410. {
  411. // & 처리 : &amp; &nbsp; 등의 코드를 정상 출력함
  412. $content = html_symbol($content);
  413. // 공백 처리
  414. $content = str_replace(" ", "&nbsp; ", $content);
  415. $content = str_replace("\n ", "\n&nbsp;", $content);
  416. $content = get_text($content, 1);
  417. $content = url_auto_link($content);
  418. }
  419. return $content;
  420. }
  421. // 검색 구문을 얻는다.
  422. function get_sql_search($search_ca_name, $search_field, $search_text, $search_operator='and')
  423. {
  424. global $g4;
  425. $str = "";
  426. if ($search_ca_name)
  427. $str = " ca_name = '$search_ca_name' ";
  428. // 게시판에서 \ 를 검색할 수 있도록 수정
  429. $search_text = trim(stripslashes($search_text));
  430. if (!$search_text)
  431. return $str;
  432. if ($str)
  433. $str .= " and ";
  434. // 쿼리의 속도를 높이기 위하여 ( ) 는 최소화 한다.
  435. $op1 = "";
  436. // 검색어를 구분자로 나눈다. 여기서는 공백
  437. $s = array();
  438. $s = explode(" ", strip_tags($search_text));
  439. // 검색필드를 구분자로 나눈다. 여기서는 +
  440. //$field = array();
  441. //$field = explode("||", trim($search_field));
  442. $tmp = array();
  443. $tmp = explode(",", trim($search_field));
  444. $field = explode("||", $tmp[0]);
  445. $not_comment = $tmp[1];
  446. if(trim($tmp[0]) == "")
  447. {
  448. $str .= "(1)";
  449. }
  450. else
  451. {
  452. $str .= "(";
  453. for ($i=0; $i<count($s); $i++) {
  454. // 검색어
  455. $search_str = trim($s[$i]);
  456. if ($search_str == "") continue;
  457. /*
  458. 인기검색어 기능 삭제 : 101202
  459. // 인기검색어
  460. $sql = " insert into {$g4['popular_table']} set pp_word = '$search_str', pp_date = '{$g4['time_ymd']}', pp_ip = '{$_SERVER['REMOTE_ADDR']}' ";
  461. sql_query($sql, FALSE);
  462. */
  463. $str .= $op1;
  464. $str .= "(";
  465. $op2 = "";
  466. for ($k=0; $k<count($field); $k++) { // 필드의 수만큼 다중 필드 검색 가능 (필드1+필드2...)
  467. // SQL Injection 방지
  468. // 필드값에 a-z A-Z 0-9 _ , | 이외의 값이 있다면 검색필드를 wr_subject 로 설정한다.
  469. $field[$k] = preg_match("/^[\w\,\|]+$/", $field[$k]) ? $field[$k] : "wr_subject";
  470. $str .= $op2;
  471. switch ($field[$k]) {
  472. case "mb_id" :
  473. case "wr_name" :
  474. $str .= " $field[$k] = '$s[$i]' ";
  475. break;
  476. case "wr_hit" :
  477. case "wr_good" :
  478. case "wr_nogood" :
  479. $str .= " $field[$k] >= '$s[$i]' ";
  480. break;
  481. // 번호는 해당 검색어에 -1 을 곱함
  482. case "wr_num" :
  483. $str .= "$field[$k] = ".((-1)*$s[$i]);
  484. break;
  485. // LIKE 보다 INSTR 속도가 빠름
  486. default :
  487. if (preg_match("/[a-zA-Z]/", $search_str))
  488. $str .= "INSTR(LOWER($field[$k]), LOWER('$search_str'))";
  489. else
  490. $str .= "INSTR({$field[$k]}, '$search_str')";
  491. break;
  492. }
  493. $op2 = " or ";
  494. }
  495. $str .= ")";
  496. //$op1 = ($search_operator) ? ' and ' : ' or ';
  497. $op1 = " $search_operator ";
  498. }
  499. $str .= " ) ";
  500. }
  501. if ($not_comment)
  502. $str .= " and wr_is_comment = '0' ";
  503. return $str;
  504. }
  505. // 게시판 테이블에서 하나의 행을 읽음
  506. function get_write($write_table, $wr_id)
  507. {
  508. return sql_fetch(" select * from $write_table where wr_id = '$wr_id' ");
  509. }
  510. // 게시판의 다음글 번호를 얻는다.
  511. function get_next_num($table)
  512. {
  513. // 가장 작은 번호를 얻어
  514. $sql = " select min(wr_num) as min_wr_num from $table ";
  515. $row = sql_fetch($sql);
  516. // 가장 작은 번호에 1을 빼서 넘겨줌
  517. return (int)($row['min_wr_num'] - 1);
  518. }
  519. // 그룹 설정 테이블에서 하나의 행을 읽음
  520. function get_group($gr_id)
  521. {
  522. global $g4;
  523. return sql_fetch(" select * from {$g4['group_table']} where gr_id = '$gr_id' ");
  524. }
  525. // 회원 정보를 얻는다.
  526. function get_member($mb_id, $fields='*')
  527. {
  528. global $g4;
  529. return sql_fetch(" select $fields from {$g4['member_table']} where mb_id = TRIM('$mb_id') ");
  530. }
  531. // 날짜, 조회수의 경우 높은 순서대로 보여져야 하므로 $flag 를 추가
  532. // $flag : asc 낮은 순서 , desc 높은 순서
  533. // 제목별로 컬럼 정렬하는 QUERY STRING
  534. function subject_sort_link($col, $query_string='', $flag='asc')
  535. {
  536. global $sst, $sod, $sfl, $stx, $page;
  537. $q1 = "sst=$col";
  538. if ($flag == 'asc')
  539. {
  540. $q2 = 'sod=asc';
  541. if ($sst == $col)
  542. {
  543. if ($sod == 'asc')
  544. {
  545. $q2 = 'sod=desc';
  546. }
  547. }
  548. }
  549. else
  550. {
  551. $q2 = 'sod=desc';
  552. if ($sst == $col)
  553. {
  554. if ($sod == 'desc')
  555. {
  556. $q2 = 'sod=asc';
  557. }
  558. }
  559. }
  560. return "<a href='{$_SERVER['PHP_SELF']}?$query_string&amp;$q1&amp;$q2&amp;sfl=$sfl&amp;stx=$stx&amp;page=$page'>";
  561. }
  562. // 관리자 정보를 얻음
  563. function get_admin($admin='super')
  564. {
  565. global $config, $group, $board;
  566. global $g4;
  567. $is = false;
  568. if ($admin == 'board') {
  569. $mb = sql_fetch("select * from {$g4['member_table']} where mb_id in ('{$board['bo_admin']}') limit 1 ");
  570. $is = true;
  571. }
  572. if (($is && !$mb['mb_id']) || $admin == 'group') {
  573. $mb = sql_fetch("select * from {$g4['member_table']} where mb_id in ('{$group['gr_admin']}') limit 1 ");
  574. $is = true;
  575. }
  576. if (($is && !$mb['mb_id']) || $admin == 'super') {
  577. $mb = sql_fetch("select * from {$g4['member_table']} where mb_id in ('{$config['cf_admin']}') limit 1 ");
  578. }
  579. return $mb;
  580. }
  581. // 관리자인가?
  582. function is_admin($mb_id)
  583. {
  584. global $config, $group, $board;
  585. if (!$mb_id) return;
  586. if ($config['cf_admin'] == $mb_id) return 'super';
  587. if ($group['gr_admin'] == $mb_id) return 'group';
  588. if ($board['bo_admin'] == $mb_id) return 'board';
  589. return '';
  590. }
  591. // 분류 옵션을 얻음
  592. // 4.00 에서는 카테고리 테이블을 없애고 보드테이블에 있는 내용으로 대체
  593. function get_category_option($bo_table='')
  594. {
  595. global $g4, $board;
  596. $arr = explode("|", $board['bo_category_list']); // 구분자가 , 로 되어 있음
  597. $str = "";
  598. for ($i=0; $i<count($arr); $i++)
  599. if (trim($arr[$i]))
  600. $str .= "<option value='{$arr[$i]}'>{$arr[$i]}</option>\n";
  601. return $str;
  602. }
  603. // 게시판 그룹을 SELECT 형식으로 얻음
  604. function get_group_select($name, $selected='', $event='')
  605. {
  606. global $g4, $is_admin, $member;
  607. $sql = " select gr_id, gr_subject from {$g4['group_table']} a ";
  608. if ($is_admin == "group") {
  609. $sql .= " left join {$g4['member_table']} b on (b.mb_id = a.gr_admin)
  610. where b.mb_id = '{$member['mb_id']}' ";
  611. }
  612. $sql .= " order by a.gr_id ";
  613. $result = sql_query($sql);
  614. $str = "<select name='$name' $event>";
  615. for ($i=0; $row=sql_fetch_array($result); $i++)
  616. {
  617. $str .= "<option value='{$row['gr_id']}'";
  618. if ($row['gr_id'] == $selected) $str .= " selected='selected'";
  619. $str .= ">{$row['gr_subject']}</option>";
  620. }
  621. $str .= "</select>";
  622. return $str;
  623. }
  624. // '예', '아니오'를 SELECT 형식으로 얻음
  625. function get_yn_select($name, $selected='1', $event='')
  626. {
  627. $str = "<select name='$name' $event>";
  628. if ($selected) {
  629. $str .= "<option value='1' selected>예</option>";
  630. $str .= "<option value='0'>아니오</option>";
  631. } else {
  632. $str .= "<option value='1'>예</option>";
  633. $str .= "<option value='0' selected>아니오</option>";
  634. }
  635. $str .= "</select>";
  636. return $str;
  637. }
  638. // 포인트 부여
  639. function insert_point($mb_id, $point, $content='', $rel_table='', $rel_id='', $rel_action='')
  640. {
  641. global $config;
  642. global $g4;
  643. global $is_admin;
  644. // 포인트 사용을 하지 않는다면 return
  645. if (!$config['cf_use_point']) { return 0; }
  646. // 포인트가 없다면 업데이트 할 필요 없음
  647. if ($point == 0) { return 0; }
  648. // 회원아이디가 없다면 업데이트 할 필요 없음
  649. if ($mb_id == "") { return 0; }
  650. $mb = sql_fetch(" select mb_id from {$g4['member_table']} where mb_id = '$mb_id' ");
  651. if (!$mb['mb_id']) { return 0; }
  652. // 이미 등록된 내역이라면 건너뜀
  653. if ($rel_table || $rel_id || $rel_action)
  654. {
  655. $sql = " select count(*) as cnt from {$g4['point_table']} where mb_id = '$mb_id' and po_rel_table = '$rel_table' and po_rel_id = '$rel_id' and po_rel_action = '$rel_action' ";
  656. $row = sql_fetch($sql);
  657. if ($row['cnt'])
  658. return -1;
  659. }
  660. // 포인트 건별 생성
  661. $sql = " insert into {$g4['point_table']}
  662. set mb_id = '$mb_id',
  663. po_datetime = '{$g4['time_ymdhis']}',
  664. po_content = '".addslashes($content)."',
  665. po_point = '$point',
  666. po_rel_table = '$rel_table',
  667. po_rel_id = '$rel_id',
  668. po_rel_action = '$rel_action' ";
  669. sql_query($sql);
  670. // 포인트 내역의 합을 구하고
  671. $sql = " select sum(po_point) as sum_po_point from {$g4['point_table']} where mb_id = '$mb_id' ";
  672. $row = sql_fetch($sql);
  673. $sum_point = $row['sum_po_point'];
  674. // 포인트 UPDATE
  675. $sql = " update {$g4['member_table']} set mb_point = '$sum_point' where mb_id = '$mb_id' ";
  676. sql_query($sql);
  677. return 1;
  678. }
  679. // 포인트 삭제
  680. function delete_point($mb_id, $rel_table, $rel_id, $rel_action)
  681. {
  682. global $g4;
  683. $result = false;
  684. if ($rel_table || $rel_id || $rel_action)
  685. {
  686. $result = sql_query(" delete from {$g4['point_table']}
  687. where mb_id = '$mb_id'
  688. and po_rel_table = '$rel_table'
  689. and po_rel_id = '$rel_id'
  690. and po_rel_action = '$rel_action' ", false);
  691. // 포인트 내역의 합을 구하고
  692. $sql = " select sum(po_point) as sum_po_point from {$g4['point_table']} where mb_id = '$mb_id' ";
  693. $row = sql_fetch($sql);
  694. $sum_point = $row['sum_po_point'];
  695. // 포인트 UPDATE
  696. $sql = " update {$g4['member_table']} set mb_point = '$sum_point' where mb_id = '$mb_id' ";
  697. $result = sql_query($sql);
  698. }
  699. return $result;
  700. }
  701. // 회원 레이어
  702. function get_sideview($mb_id, $name="", $email="", $homepage="")
  703. {
  704. global $config;
  705. global $g4;
  706. $email = base64_encode($email);
  707. $homepage = set_http($homepage);
  708. $name = preg_replace("/\&#039;/", "", $name);
  709. $name = preg_replace("/\'/", "", $name);
  710. $name = preg_replace("/\"/", "&#034;", $name);
  711. $title_name = $name;
  712. $tmp_name = get_text(cut_str($name, $config['cf_cut_name'])); // 설정된 자리수 만큼만 이름 출력
  713. if ($mb_id) {
  714. $tmp_name = "<span class='member'>$tmp_name</span>";
  715. if ($config['cf_use_member_icon']) {
  716. $mb_dir = substr($mb_id,0,2);
  717. $icon_file = "{$g4['path']}/data/member/$mb_dir/$mb_id.gif";
  718. //if (file_exists($icon_file) && is_file($icon_file)) {
  719. if (file_exists($icon_file)) {
  720. //$size = getimagesize($icon_file);
  721. //$width = $size[0];
  722. //$height = $size[1];
  723. $width = $config['cf_member_icon_width'];
  724. $height = $config['cf_member_icon_height'];
  725. $tmp_name = "<img src='$icon_file' style='vertical-align:middle; width:$width; height:$height;' alt='$name' />";
  726. if ($config['cf_use_member_icon'] == 2) // 회원아이콘+이름
  727. $tmp_name = $tmp_name . " <span class='member'>$name</span>";
  728. }
  729. }
  730. $title_mb_id = "[$mb_id]";
  731. } else {
  732. $tmp_name = "<span class='guest'>$tmp_name</span>";
  733. $title_mb_id = "[비회원]";
  734. }
  735. $name = get_text($name);
  736. $email = get_text($email);
  737. $homepage = get_text($homepage);
  738. //return "<a href=\"javascript:showSideView(this, '$mb_id', '$name', '$email', '$homepage');\" title=\"{$title_mb_id}{$title_name}\">$tmp_name</a>";
  739. return "<a href='#' class='sidebox' rel='mb_id={$mb_id}&amp;name={$name}&amp;email={$email}&amp;homepage={$homepage}' onclick='return false;'>$tmp_name</a>";
  740. }
  741. // 파일을 보이게 하는 링크 (이미지, 플래쉬, 동영상)
  742. function view_file_link($file, $width, $height, $content="", $board)
  743. {
  744. global $config;
  745. global $g4;
  746. static $ids;
  747. if (!$file) return;
  748. $ids++;
  749. // 파일의 폭이 게시판설정의 이미지폭 보다 크다면 게시판설정 폭으로 맞추고 비율에 따라 높이를 계산
  750. if ($width > $board['bo_image_width'] && $board['bo_image_width'])
  751. {
  752. $rate = $board['bo_image_width'] / $width;
  753. $width = $board['bo_image_width'];
  754. $height = (int)($height * $rate);
  755. }
  756. // 폭이 있는 경우 폭과 높이의 속성을 주고, 없으면 자동 계산되도록 코드를 만들지 않는다.
  757. if ($width)
  758. $attr = " width='$width' height='$height' ";
  759. else
  760. $attr = "";
  761. if (preg_match("/\.(" .$config['cf_image_extension'] . ")$/i", $file))
  762. {
  763. // 이미지에 속성을 주지 않는 이유는 이미지 클릭시 원본 이미지를 보여주기 위한것임
  764. // 게시판설정 이미지보다 크다면 스킨의 자바스크립트에서 이미지를 줄여준다
  765. $img_file = "{$g4['path']}/data/file/{$board['bo_table']}/".urlencode($file);
  766. $size = getimagesize($img_file);
  767. // 이미지폭이 게시판에 설정된 이미지폭을 초과한다면 lightbox를 사용
  768. if ($size[0] > $board['bo_image_width'])
  769. return "<a rel='lightbox' href='$img_file'><img src='$img_file' width='{$board['bo_image_width']}' alt='lightbox' /></a>";
  770. else
  771. return "<img src='$img_file' alt='$content' />";
  772. }
  773. /* 110106 : FLASH XSS 공격으로 인하여 코드 자체를 막음
  774. else if (preg_match("/\.($config['cf_flash_extension'])$/i", $file))
  775. //return "<embed src='{$g4['path']}/data/file/{$board['bo_table']}/$file' $attr></embed>";
  776. return "<script>doc_write(flash_movie('{$g4['path']}/data/file/{$board['bo_table']}/$file', '_g4_{$ids}', '$width', '$height', 'transparent'));</script>";
  777. //=============================================================================================
  778. // 동영상 파일에 악성코드를 심는 경우를 방지하기 위해 경로를 노출하지 않음
  779. //---------------------------------------------------------------------------------------------
  780. else if (preg_match("/\.($config['cf_movie_extension'])$/i", $file))
  781. //return "<embed src='{$g4['path']}/data/file/{$board['bo_table']}/$file' $attr></embed>";
  782. return "<script>doc_write(obj_movie('{$g4['path']}/data/file/{$board['bo_table']}/$file', '_g4_{$ids}', '$width', '$height'));</script>";
  783. //=============================================================================================
  784. */
  785. }
  786. // view_file_link() 함수에서 넘겨진 이미지를 보이게 합니다.
  787. // {img:0} ... {img:n} 과 같은 형식
  788. function view_image($view, $number, $attribute)
  789. {
  790. if ($view['file'][$number]['view'])
  791. return preg_replace("/>$/", " $attribute>", $view['file'][$number]['view']);
  792. else
  793. //return "{".$number."번 이미지 없음}";
  794. return "";
  795. }
  796. /*
  797. // {link:0} ... {link:n} 과 같은 형식
  798. function view_link($view, $number, $attribute)
  799. {
  800. global $config;
  801. if ($view['link'][$number]['link'])
  802. {
  803. if (!preg_match("/target/i", $attribute))
  804. $attribute .= " target='$config['cf_link_target']'";
  805. return "<a href='{$view['link'][$number]['href']}' $attribute>{$view['link'][$number]['link']}</a>";
  806. }
  807. else
  808. return "{".$number."번 링크 없음}";
  809. }
  810. */
  811. // 한글 한글자(2byte, 유니코드 3byte)는 길이 2, 공란.영숫자.특수문자는 길이 1
  812. // 유니코드는 http://g4uni.winnwe.net/bbs/board.php?bo_table=g4uni_faq&wr_id=7 의 Mr.Learn님의 글을 참고하였습니다.
  813. function cut_str($str, $len, $suffix="…")
  814. {
  815. global $g4;
  816. if (strtoupper($g4['charset']) == 'UTF-8') {
  817. $c = substr(str_pad(decbin(ord($str{$len})),8,'0',STR_PAD_LEFT),0,2);
  818. if ($c == '10')
  819. for (;$c != '11' && $c{0} == 1;$c = substr(str_pad(decbin(ord($str{--$len})),8,'0',STR_PAD_LEFT),0,2));
  820. return substr($str,0,$len) . (strlen($str)-strlen($suffix) >= $len ? $suffix : '');
  821. } else {
  822. $s = substr($str, 0, $len);
  823. $cnt = 0;
  824. for ($i=0; $i<strlen($s); $i++)
  825. if (ord($s[$i]) > 127)
  826. $cnt++;
  827. $s = substr($s, 0, $len - ($cnt % 2));
  828. if (strlen($s) >= strlen($str))
  829. $suffix = "";
  830. return $s . $suffix;
  831. }
  832. }
  833. // TEXT 형식으로 변환
  834. function get_text($str, $html=0)
  835. {
  836. /* 3.22 막음 (HTML 체크 줄바꿈시 출력 오류때문)
  837. $source[] = "/ /";
  838. $target[] = " &nbsp;";
  839. */
  840. // 3.31
  841. // TEXT 출력일 경우 &amp; &nbsp; 등의 코드를 정상으로 출력해 주기 위함
  842. if ($html == 0) {
  843. $str = html_symbol($str);
  844. }
  845. $source[] = "/</";
  846. $target[] = "&lt;";
  847. $source[] = "/>/";
  848. $target[] = "&gt;";
  849. //$source[] = "/\"/";
  850. //$target[] = "&#034;";
  851. $source[] = "/\'/";
  852. $target[] = "&#039;";
  853. //$source[] = "/}/"; $target[] = "&#125;";
  854. if ($html) {
  855. $source[] = "/\n/";
  856. $target[] = "<br/>";
  857. }
  858. return preg_replace($source, $target, $str);
  859. }
  860. /*
  861. // HTML 특수문자 변환 htmlspecialchars
  862. function hsc($str)
  863. {
  864. $trans = array("\"" => "&#034;", "'" => "&#039;", "<"=>"&#060;", ">"=>"&#062;");
  865. $str = strtr($str, $trans);
  866. return $str;
  867. }
  868. */
  869. // 3.31
  870. // HTML SYMBOL 변환
  871. // &nbsp; &amp; &middot; 등을 정상으로 출력
  872. function html_symbol($str)
  873. {
  874. return preg_replace("/\&([a-z0-9]{1,20}|\#[0-9]{0,3});/i", "&#038;\\1;", $str);
  875. }
  876. /*************************************************************************
  877. **
  878. ** SQL 관련 함수 모음
  879. **
  880. *************************************************************************/
  881. // DB 연결
  882. function sql_connect($host, $user, $pass)
  883. {
  884. global $g4;
  885. /*
  886. if (strtolower($g4['charset']) == 'utf-8') @mysql_query(" set names utf8 ");
  887. else if (strtolower($g4['charset']) == 'euc-kr') @mysql_query(" set names euckr ");
  888. */
  889. return @mysql_connect($host, $user, $pass);
  890. }
  891. // DB 선택
  892. function sql_select_db($db, $connect)
  893. {
  894. global $g4;
  895. if (strtolower($g4['charset']) == 'utf-8') @mysql_query(" set names utf8 ");
  896. else if (strtolower($g4['charset']) == 'euc-kr') @mysql_query(" set names euckr ");
  897. return @mysql_select_db($db, $connect);
  898. }
  899. // mysql_query 와 mysql_error 를 한꺼번에 처리
  900. function sql_query($sql, $error=TRUE)
  901. {
  902. if ($error)
  903. $result = @mysql_query($sql) or die("<p>$sql<p>" . mysql_errno() . " : " . mysql_error() . "<p>error file : {$_SERVER['PHP_SELF']}");
  904. else
  905. $result = @mysql_query($sql);
  906. return $result;
  907. }
  908. // 쿼리를 실행한 후 결과값에서 한행을 얻는다.
  909. function sql_fetch($sql, $error=TRUE)
  910. {
  911. $result = sql_query($sql, $error);
  912. //$row = @sql_fetch_array($result) or die("<p>$sql<p>" . mysql_errno() . " : " . mysql_error() . "<p>error file : {$_SERVER['PHP_SELF']}");
  913. $row = sql_fetch_array($result);
  914. return $row;
  915. }
  916. // 결과값에서 한행 연관배열(이름으로)로 얻는다.
  917. function sql_fetch_array($result)
  918. {
  919. $row = @mysql_fetch_assoc($result);
  920. return $row;
  921. }
  922. // $result에 대한 메모리(memory)에 있는 내용을 모두 제거한다.
  923. // sql_free_result()는 결과로부터 얻은 질의 값이 커서 많은 메모리를 사용할 염려가 있을 때 사용된다.
  924. // 단, 결과 값은 스크립트(script) 실행부가 종료되면서 메모리에서 자동적으로 지워진다.
  925. function sql_free_result($result)
  926. {
  927. return mysql_free_result($result);
  928. }
  929. function sql_password($value)
  930. {
  931. // mysql 4.0x 이하 버전에서는 password() 함수의 결과가 16bytes
  932. // mysql 4.1x 이상 버전에서는 password() 함수의 결과가 41bytes
  933. $row = sql_fetch(" select password('$value') as pass ");
  934. return $row['pass'];
  935. }
  936. // PHPMyAdmin 참고
  937. function get_table_define($table, $crlf="\n")
  938. {
  939. global $g4;
  940. // For MySQL < 3.23.20
  941. $schema_create .= 'CREATE TABLE ' . $table . ' (' . $crlf;
  942. $sql = 'SHOW FIELDS FROM ' . $table;
  943. $result = sql_query($sql);
  944. while ($row = sql_fetch_array($result))
  945. {
  946. $schema_create .= ' ' . $row['Field'] . ' ' . $row['Type'];
  947. if (isset($row['Default']) && $row['Default'] != '')
  948. {
  949. $schema_create .= ' DEFAULT \'' . $row['Default'] . '\'';
  950. }
  951. if ($row['Null'] != 'YES')
  952. {
  953. $schema_create .= ' NOT NULL';
  954. }
  955. if ($row['Extra'] != '')
  956. {
  957. $schema_create .= ' ' . $row['Extra'];
  958. }
  959. $schema_create .= ',' . $crlf;
  960. } // end while
  961. sql_free_result($result);
  962. $schema_create = preg_replace('/,' . $crlf . '$/', '', $schema_create);
  963. $sql = 'SHOW KEYS FROM ' . $table;
  964. $result = sql_query($sql);
  965. while ($row = sql_fetch_array($result))
  966. {
  967. $kname = $row['Key_name'];
  968. $comment = (isset($row['Comment'])) ? $row['Comment'] : '';
  969. $sub_part = (isset($row['Sub_part'])) ? $row['Sub_part'] : '';
  970. if ($kname != 'PRIMARY' && $row['Non_unique'] == 0) {
  971. $kname = "UNIQUE|$kname";
  972. }
  973. if ($comment == 'FULLTEXT') {
  974. $kname = 'FULLTEXT|$kname';
  975. }
  976. if (!isset($index[$kname])) {
  977. $index[$kname] = array();
  978. }
  979. if ($sub_part > 1) {
  980. $index[$kname][] = $row['Column_name'] . '(' . $sub_part . ')';
  981. } else {
  982. $index[$kname][] = $row['Column_name'];
  983. }
  984. } // end while
  985. sql_free_result($result);
  986. while (list($x, $columns) = @each($index)) {
  987. $schema_create .= ',' . $crlf;
  988. if ($x == 'PRIMARY') {
  989. $schema_create .= ' PRIMARY KEY (';
  990. } else if (substr($x, 0, 6) == 'UNIQUE') {
  991. $schema_create .= ' UNIQUE ' . substr($x, 7) . ' (';
  992. } else if (substr($x, 0, 8) == 'FULLTEXT') {
  993. $schema_create .= ' FULLTEXT ' . substr($x, 9) . ' (';
  994. } else {
  995. $schema_create .= ' KEY ' . $x . ' (';
  996. }
  997. $schema_create .= implode($columns, ', ') . ')';
  998. } // end while
  999. if (strtolower($g4['charset']) == "utf-8")
  1000. $schema_create .= $crlf . ') DEFAULT CHARSET=utf8';
  1001. else
  1002. $schema_create .= $crlf . ')';
  1003. return $schema_create;
  1004. } // end of the 'PMA_getTableDef()' function
  1005. // 리퍼러 체크
  1006. function referer_check($url="")
  1007. {
  1008. /*
  1009. // 제대로 체크를 하지 못하여 주석 처리함
  1010. global $g4;
  1011. if (!$url)
  1012. $url = $g4['url'];
  1013. if (!preg_match("/^http['s']?:\/\/".$_SERVER['HTTP_HOST']."/", $_SERVER['HTTP_REFERER']))
  1014. alert("제대로 된 접근이 아닌것 같습니다.", $url);
  1015. */
  1016. }
  1017. // 한글 요일
  1018. function get_yoil($date, $full=0)
  1019. {
  1020. $arr_yoil = array ("일", "월", "화", "수", "목", "금", "토");
  1021. $yoil = date("w", strtotime($date));
  1022. $str = $arr_yoil[$yoil];
  1023. if ($full) {
  1024. $str .= "요일";
  1025. }
  1026. return $str;
  1027. }
  1028. // 날짜를 select 박스 형식으로 얻는다
  1029. function date_select($date, $name="")
  1030. {
  1031. global $g4;
  1032. $s = "";
  1033. if (substr($date, 0, 4) == "0000") {
  1034. $date = $g4['time_ymdhis'];
  1035. }
  1036. preg_match("/([0-9]{4})-([0-9]{2})-([0-9]{2})/", $date, $m);
  1037. // 년
  1038. $s .= "<select name='{$name}_y'>";
  1039. for ($i=$m[0]-3; $i<=$m[0]+3; $i++) {
  1040. $s .= "<option value='$i'";
  1041. if ($i == $m[0]) {
  1042. $s .= " selected";
  1043. }
  1044. $s .= ">$i";
  1045. }
  1046. $s .= "</select>년 \n";
  1047. // 월
  1048. $s .= "<select name='{$name}_m'>";
  1049. for ($i=1; $i<=12; $i++) {
  1050. $s .= "<option value='$i'";
  1051. if ($i == $m[2]) {
  1052. $s .= " selected";
  1053. }
  1054. $s .= ">$i";
  1055. }
  1056. $s .= "</select>월 \n";
  1057. // 일
  1058. $s .= "<select name='{$name}_d'>";
  1059. for ($i=1; $i<=31; $i++) {
  1060. $s .= "<option value='$i'";
  1061. if ($i == $m[3]) {
  1062. $s .= " selected";
  1063. }
  1064. $s .= ">$i";
  1065. }
  1066. $s .= "</select>일 \n";
  1067. return $s;
  1068. }
  1069. // 시간을 select 박스 형식으로 얻는다
  1070. // 1.04.00
  1071. // 경매에 시간 설정이 가능하게 되면서 추가함
  1072. function time_select($time, $name="")
  1073. {
  1074. preg_match("/([0-9]{2}):([0-9]{2}):([0-9]{2})/", $time, $m);
  1075. // 시
  1076. $s .= "<select name='{$name}_h'>";
  1077. for ($i=0; $i<=23; $i++) {
  1078. $s .= "<option value='$i'";
  1079. if ($i == $m[0]) {
  1080. $s .= " selected";
  1081. }
  1082. $s .= ">$i";
  1083. }
  1084. $s .= "</select>시 \n";
  1085. // 분
  1086. $s .= "<select name='{$name}_i'>";
  1087. for ($i=0; $i<=59; $i++) {
  1088. $s .= "<option value='$i'";
  1089. if ($i == $m[2]) {
  1090. $s .= " selected";
  1091. }
  1092. $s .= ">$i";
  1093. }
  1094. $s .= "</select>분 \n";
  1095. // 초
  1096. $s .= "<select name='{$name}_s'>";
  1097. for ($i=0; $i<=59; $i++) {
  1098. $s .= "<option value='$i'";
  1099. if ($i == $m[3]) {
  1100. $s .= " selected";
  1101. }
  1102. $s .= ">$i";
  1103. }
  1104. $s .= "</select>초 \n";
  1105. return $s;
  1106. }
  1107. // DEMO 라는 파일이 있으면 데모 화면으로 인식함
  1108. function check_demo()
  1109. {
  1110. global $g4;
  1111. if (file_exists("{$g4['path']}/DEMO"))
  1112. alert("데모 화면에서는 하실(보실) 수 없는 작업입니다.");
  1113. }
  1114. // 문자열이 한글, 영문, 숫자, 특수문자로 구성되어 있는지 검사
  1115. function check_string($str, $options)
  1116. {
  1117. global $g4;
  1118. $s = '';
  1119. for($i=0;$i<strlen($str);$i++) {
  1120. $c = $str[$i];
  1121. $oc = ord($c);
  1122. // 한글
  1123. if ($oc >= 0xA0 && $oc <= 0xFF) {
  1124. if (strtoupper($g4['charset']) == 'UTF-8') {
  1125. if ($options & _G4_HANGUL_) {
  1126. $s .= $c . $str[$i+1] . $str[$i+2];
  1127. }
  1128. $i+=2;
  1129. } else {
  1130. // 한글은 2바이트 이므로 문자하나를 건너뜀
  1131. $i++;
  1132. if ($options & _G4_HANGUL_) {
  1133. $s .= $c . $str[$i];
  1134. }
  1135. }
  1136. }
  1137. // 숫자
  1138. else if ($oc >= 0x30 && $oc <= 0x39) {
  1139. if ($options & _G4_NUMERIC_) {
  1140. $s .= $c;
  1141. }
  1142. }
  1143. // 영대문자
  1144. else if ($oc >= 0x41 && $oc <= 0x5A) {
  1145. if (($options & _G4_ALPHABETIC_) || ($options & _G4_ALPHAUPPER_)) {
  1146. $s .= $c;
  1147. }
  1148. }
  1149. // 영소문자
  1150. else if ($oc >= 0x61 && $oc <= 0x7A) {
  1151. if (($options & _G4_ALPHABETIC_) || ($options & _G4_ALPHALOWER_)) {
  1152. $s .= $c;
  1153. }
  1154. }
  1155. // 공백
  1156. else if ($oc >= 0x20) {
  1157. if ($options & _G4_SPACE_) {
  1158. $s .= $c;
  1159. }
  1160. }
  1161. else {
  1162. if ($options & _G4_SPECIAL_) {
  1163. $s .= $c;
  1164. }
  1165. }
  1166. }
  1167. // 넘어온 값과 비교하여 같으면 참, 틀리면 거짓
  1168. return ($str == $s);
  1169. }
  1170. // 한글(2bytes)에서 마지막 글자가 1byte로 끝나는 경우
  1171. // 출력시 깨지는 현상이 발생하므로 마지막 완전하지 않은 글자(1byte)를 하나 없앰
  1172. function cut_hangul_last($hangul)
  1173. {
  1174. global $g4;
  1175. // 한글이 반쪽나면 ?로 표시되는 현상을 막음
  1176. $cnt = 0;
  1177. for($i=0;$i<strlen($hangul);$i++) {
  1178. // 한글만 센다
  1179. if (ord($hangul[$i]) >= 0xA0) {
  1180. $cnt++;
  1181. }
  1182. }
  1183. // 홀수라면 한글이 반쪽난 상태이므로
  1184. if (strtoupper($g4['charset']) != 'UTF-8') {
  1185. if ($cnt%2) {
  1186. $hangul = substr($hangul, 0, $cnt-1);
  1187. }
  1188. }
  1189. return $hangul;
  1190. }
  1191. // 테이블에서 INDEX(키) 사용여부 검사
  1192. function explain($sql)
  1193. {
  1194. if (preg_match("/^(select)/i", trim($sql))) {
  1195. $q = "explain $sql";
  1196. echo $q;
  1197. $row = sql_fetch($q);
  1198. if (!$row['key']) $row['key'] = "NULL";
  1199. echo " <span style='color:#00f'>(type={$row['type']} , key={$row['key']})</span>";
  1200. }
  1201. }
  1202. // 악성태그 변환
  1203. function bad_tag_convert($code)
  1204. {
  1205. global $view;
  1206. global $member, $is_admin;
  1207. if ($is_admin && $member['mb_id'] != $view['mb_id']) {
  1208. //$code = preg_replace_callback("#(\<(embed|object)[^\>]*)\>(\<\/(embed|object)\>)?#i",
  1209. // embed 또는 object 태그를 막지 않는 경우 필터링이 되도록 수정
  1210. $code = preg_replace_callback("#(\<(embed|object)[^\>]*)\>?(\<\/(embed|object)\>)?#i",
  1211. create_function('$matches', 'return "<div class=\"embedx\">보안문제로 인하여 관리자 아이디로는 embed 또는 object 태그를 볼 수 없습니다. 확인하시려면 관리권한이 없는 다른 아이디로 접속하세요.</div>";'),
  1212. $code);
  1213. }
  1214. //return preg_replace("/\<([\/]?)(script|iframe)([^\>]*)\>/i", "&lt;$1$2$3&gt;", $code);
  1215. // script 나 iframe 태그를 막지 않는 경우 필터링이 되도록 수정
  1216. return preg_replace("/\<([\/]?)(script|iframe)([^\>]*)\>?/i", "&lt;$1$2$3&gt;", $code);
  1217. }
  1218. // 불법접근을 막도록 토큰을 생성하면서 토큰값을 리턴
  1219. function get_token()
  1220. {
  1221. $token = md5(uniqid(rand(), true));
  1222. set_session("ss_token", $token);
  1223. return $token;
  1224. }
  1225. // POST로 넘어온 토큰과 세션에 저장된 토큰 비교
  1226. function check_token()
  1227. {
  1228. set_session('ss_token', '');
  1229. return true;
  1230. /*
  1231. // 세션에 저장된 토큰과 폼값으로 넘어온 토큰을 비교하여 틀리면 에러
  1232. if ($_POST['token'] && get_session('ss_token') == $_POST['token']) {
  1233. // 맞으면 세션을 지운다. 세션을 지우는 이유는 새로운 폼을 통해 다시 들어오도록 하기 위함
  1234. set_session('ss_token', '');
  1235. } else {
  1236. alert_close('토큰 에러');
  1237. }
  1238. */
  1239. }
  1240. function isnot($val=null, $pre=null) {
  1241. return $val ? $val : $pre;
  1242. }
  1243. function isget($val=null, $key=null, $def=null) {
  1244. if (is_null($val)) return isnot($def, null);
  1245. switch (gettype($val)) {
  1246. case 'string':
  1247. return isset($GLOBALS[$val]) ? $GLOBALS[$val] : $key;
  1248. case 'array':
  1249. return isset($val[$key]) ? $val[$key] : $def;
  1250. case 'object':
  1251. if (is_callable(array($val, $key)))
  1252. return $val->{$key}();
  1253. else if (isset($val->$key))
  1254. return $val->$key;
  1255. return $def;
  1256. }
  1257. return null;
  1258. }
  1259. // 문자열에 utf8 문자가 들어 있는지 검사하는 함수
  1260. // 코드 : http://in2.php.net/manual/en/function.mb-check-encoding.php#95289
  1261. function is_utf8($str)
  1262. {
  1263. $len = strlen($str);
  1264. for($i = 0; $i < $len; $i++) {
  1265. $c = ord($str[$i]);
  1266. if ($c > 128) {
  1267. if (($c > 247)) return false;
  1268. elseif ($c > 239) $bytes = 4;
  1269. elseif ($c > 223) $bytes = 3;
  1270. elseif ($c > 191) $bytes = 2;
  1271. else return false;
  1272. if (($i + $bytes) > $len) return false;
  1273. while ($bytes > 1) {
  1274. $i++;
  1275. $b = ord($str[$i]);
  1276. if ($b < 128 || $b > 191) return false;
  1277. $bytes--;
  1278. }
  1279. }
  1280. }
  1281. return true;
  1282. }
  1283. // 중복되는 파일명의 .확장자 앞에 (n) 을 추가하여 반환
  1284. function duplicate_filename($path, $filename)
  1285. {
  1286. $pos = strrpos($filename, '.');
  1287. if ($pos === false) return $path.'/'.$filename;
  1288. $file = substr($filename, 0, $pos);
  1289. $ext = substr($filename, $pos, strlen($filename));
  1290. $count = 1;
  1291. $count_str = "";
  1292. do {
  1293. $real_filename = abs(ip2long($_SERVER['REMOTE_ADDR'])).'_'.str_replace('%', '', urlencode($file)).$count_str.urlencode($ext);
  1294. $count_str = "(".$count++.")";
  1295. } while (file_exists($path.'/'.$real_filename));
  1296. return $real_filename;
  1297. }
  1298. ?>