/** * 빠른검색 * @class admin * @param $str: 검색 적용할 필드명, 콤마로 구분하고 필드명에 ! 삽입시 일치 쿼리 적용 */ function quickSearch($str, $param = '') { global $mini; $param = param($param); def($param['name'], 'default'); iss($mini['list'][$param['name']]); iss($_GET['s']); iss($_GET['and']); iss($_GET['target']); iss($_GET['quick']); iss($_REQUEST['id']); iss($where); $is_all = 0; $output = ''; $sep = $_GET['and'] ? "and" : "or "; $data =& $mini['list'][$param['name']]; iss($data['where']); if ($_GET['quick']) { $_GET['quick'] = convChar($_GET['quick']); $_GET['quick'] = str_replace("\\'", "'", $_GET['quick']); $_GET['quick'] = str_replace("\\\\'", "'", $_GET['quick']); $_GET['quick'] = str_replace("\\\"", "\"", $_GET['quick']); $tmp = array(); $tmp = explode(",", trim($str)); foreach ($tmp as $val) { $val = trim($val); if (preg_match("/\\!/", $val)) { $output .= " {$sep} " . str_replace("!", "", $val) . " = '{$_GET['quick']}'"; } else { $output .= " {$sep} {$val} LIKE '%{$_GET['quick']}%'"; } } if ($output) { $output = substr($output, 4); } $output = " and ({$output})"; $data['where'] = $data['where'] ? $data['where'] . $output : "WHERE " . substr($output, 4); $data['key'] = 0; } }
/** 검색 처리 * @class list * @param -name: 리스팅 변수배열 이름 -is_simple: key table 사용 여부 -where_and: 기본 and 검색조건 -where: 기본 검색조건 -other: 뒤에 들어갈 절 -quickName: quick 검색 변수명 -sName: 검색 변수명 -andName: and 검색 변수명 */ function setSearch($param = '') { global $mini; $param = param($param); /* 리스팅 변수배열 멤버변수 table keyTable list start div nowDiv key is_total fieldName where order order_desc 검색 조건에 따라 total 이 들어가야 한다 */ def($param['name'], 'default'); def($mini['list'][$param['name']], ''); def($_REQUEST['target'], ''); def($_REQUEST['id'], ''); def($param['quickName'], 'quick'); def($param['sName'], 's'); def($param['andName'], 'and'); def($_REQUEST[$param['sName']], ''); $where = $where_and = $both = ''; $is_all = 0; $sep = !empty($_REQUEST[$param['andName']]) ? "and" : "or "; $data =& $mini['list'][$param['name']]; def($data['key'], 0); def($data['is_total'], 0); $s = array(); if (!empty($param['other'])) { $data['other_query_after'] = $param['other']; } //// 기본 검색조건 적용 if (!empty($param['where_and'])) { $where_and .= " and {$param['where_and']}"; } if (!empty($param['where'])) { $where .= " {$sep} {$param['where']}"; } //// 모드 없는 검색 설정 if (!empty($_REQUEST[$param['quickName']]) && empty($param['is_simple'])) { $s = array('title' => $_REQUEST[$param['quickName']], 'ment' => $_REQUEST[$param['quickName']], 'name' => $_REQUEST[$param['quickName']], 'tag' => $_REQUEST[$param['quickName']]); } else { if (!empty($_REQUEST['category']) && empty($_REQUEST[$param['sName']])) { $s = array('category!' => $_REQUEST['category']); } } //// 일반 if (!empty($_REQUEST[$param['sName']])) { $s = array_merge($s, $_REQUEST[$param['sName']]); } //// 검색 루프 시작 if (!empty($s) && is_array($s)) { // 키 테이블만 사용할 수 있는 조건인지 확인(PHP5 에서는 array_diff_key로 한번에 해결, 4.0.4에서 array_diff가 깨질 수 있음!) $tmp_keys = "[" . implode("][", array_keys($s)) . "]"; $tmp_keys = str_replace(array('!', '^', '$', '@', '+', '-', '*', '~'), '', $tmp_keys); $is_key = array_diff(getStr($tmp_keys), array('category', 'tag', 'title', 'ment', 'target_member', 'name')) || !empty($param['is_simple']) ? 0 : 1; foreach ($s as $key => $val) { // 조건 뽑기 preg_match("/(\\+|\\-|\\@|\\^|\\!|\$|\\~)\$/i", $key, $mat); $is_special = preg_match("/^\\@/i", $key); $key = str_replace(array('@', '^', '!', '$', '+', '-', '*', '~'), '', trim($key)); $option = $mat[1]; // 검색어 언어셋 변경 $val = convChar($val); $val = str_replace("\\'", "'", $val); $val = str_replace("\\\\'", "'", $val); $val = str_replace("\\\"", "\"", $val); // 검색어 쪼개기 // if (empty($param['is_simple']) && (!empty($_REQUEST[$param['quickName']]) || (!empty($_REQUEST[$param['sName']]) && count($_REQUEST[$param['sName']]) == 1))) { // $val_arr = array(); // $val_arr = getIndex($val, 'search'); // $count_val_arr = count($val_arr); // } $val_arr = array(); if ($key != 'ip' && $key != 'date' && $key != 'target_member' && $key != 'name') { $val_arr = getIndex($val, 'search'); } else { $val_arr = array($val); } $count_val_arr = count($val_arr); // 특수검색(@모드) if ($is_special) { switch ($key) { // 모든 게시판에서 검색 case 'all': $is_all = 1; break; /* case 'date': break; case 'private': break; */ /* case 'date': break; case 'private': break; */ default: __error("정의되지 않은 특별검색 입니다"); } } // 검색테이블 사용 if ($is_key) { $data['key'] = 1; $tmp_q = empty($_REQUEST['is_cmt']) ? " and cmt_no=0" : ""; if ($key == 'target_member' && preg_match("/[^0-9]/", $val)) { continue; } $tmp_sep = $option == '~' ? " and" : " or "; $where_name = $option == '~' ? "where_and" : "where"; if ($option == '!') { foreach ($val_arr as $key2 => $val2) { ${$where_name} .= $key == 'target_member' ? "{$tmp_sep} (target_member={$val2}{$tmp_q})" : "{$tmp_sep} (mode='{$key}'{$tmp_q} and ment='{$val2}')"; } // 총 게시물 수를 저장한 검색조건이라면 전체 검색을 할 수 있게 is_total 변수를 지정한다 if ($key == 'category' && count($s) == 1) { $data['is_total'] = 1; $data['key'] = 1; $data['is_only_category'] = 1; // if (!isset($mini['board']['total'][$key][$val])) // __error("존재하지 않는 {$key} 입니다."); if (isset($mini['board']['total'][$key][$val])) { $data['total'] = $mini['board']['total'][$key][$val]; } else { $data['total'] = 0; } } } else { foreach ($val_arr as $key2 => $val2) { ${$where_name} .= $key == 'target_member' ? "{$tmp_sep} (target_member={$val2}{$tmp_q})" : "{$tmp_sep} (mode='{$key}'{$tmp_q} and ment LIKE '{$val2}%')"; } } } else { $tmp_sep = $option == '~' ? "and" : $sep; $where_name = $sep == 'and' ? "where_and" : "where"; // +- 가 동시에 적용될 경우 두개는 and로 묶기(date between) if ($option == '-' || $option == '+') { if (isset($s["{$key}-"]) && isset($s["{$key}+"])) { ${$where_name} .= "{$tmp_sep} ({$key} <= '{$s[$key . '-']}' and {$key} >= '{$s[$key . '+']}')"; $both .= "[{$key}]"; } } // :keyword: 검색 적용(high, low) if (preg_match("/:[a-z]+:\$/i", $val)) { $mat = array(); preg_match("/:([a-z]+):\$/i", $val, $mat); $val = preg_replace("/:[a-z]+:/i", "", $val); switch ($mat[1]) { case 'high': if ($val !== '') { ${$where_name} .= " {$tmp_sep} {$key} >= '{$val}'"; } break; case 'low': if ($val !== '') { ${$where_name} .= " {$tmp_sep} {$key} <= '{$val}'"; } break; } } else { if (is_array($val_arr)) { foreach ($val_arr as $key2 => $val2) { switch ($option) { case '!': ${$where_name} .= " {$tmp_sep} {$key}='{$val2}'"; break; case '^': if ($val2 !== '') { ${$where_name} .= " {$tmp_sep} {$key} LIKE '{$val2}%'"; } break; case '$': if ($val2 !== '') { ${$where_name} .= " {$tmp_sep} {$key} LIKE '%{$val2}'"; } break; case '*': if ($val2 !== '') { ${$where_name} .= " {$tmp_sep} {$key} LIKE '%[{$val2}]%'"; } break; case '+': if ($val2 !== '' && !inStr($key, $both)) { ${$where_name} .= " {$tmp_sep} {$key} >= '{$val2}'"; } break; case '-': if ($val2 !== '' && !inStr($key, $both)) { ${$where_name} .= " {$tmp_sep} {$key} <= '{$val2}'"; } break; default: if ($val2 !== '') { ${$where_name} .= " {$tmp_sep} {$key} LIKE '%{$val2}%'"; } } } } } } } } //// 검색 조건이 있을 떄 if ($where || $where_and) { // and와 합침 if ($where && $where_and) { $where = " and (" . substr($where, 4) . "){$where_and}"; } else { if (!$where && $where_and) { $where = $where_and; } } if (!empty($is_key)) { // 다중 게시판 검색 시(총 게시물 수가 없어야 가능) if (!empty($_REQUEST['target']) && !$data['is_total']) { $tmp = array(); $tmp = explode(",", trim($_REQUEST['target'])); $tmp_where = ''; foreach ($tmp as $key => $val) { $val = trim($val); if ($val && !preg_match("/[^0-9]/", $val)) { $tmp_where .= " or id={$val}"; } } if ($tmp_where) { $where = " and (" . substr($tmp_where, 3) . ") and (" . substr($where, 4) . ")"; } } else { if ($_REQUEST['id'] && (!$is_all || $data['is_total'])) { $where = " and id='{$mini['board']['no']}' and (" . substr($where, 4) . ")"; } } } $data['where'] = "WHERE " . substr($where, 4); if (!empty($is_key) && !empty($_REQUEST[$param['andName']]) && !empty($count_val_arr)) { $data['where'] .= " GROUP BY num HAVING count(num) >= {$count_val_arr}"; $data['is_group'] = 1; } } else { $data['is_total'] = 1; } }