You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

464 lines
20 KiB

  1. <?php
  2. /*********************************************************************************************************
  3. * Class Boardlib
  4. * ======================================================================================================
  5. *
  6. * 게시판용 라이브러리
  7. *********************************************************************************************************/
  8. class Boardlib {
  9. protected $CI;
  10. function __construct()
  11. {
  12. $this->CI =& get_instance();
  13. }
  14. function initialize($brd_key = "")
  15. {
  16. if(empty($brd_key)) return;
  17. }
  18. /******************************************************************************************************
  19. * 새글이 올라온 게시글 목록을 보여줍니다.
  20. *****************************************************************************************************/
  21. function getNewPostBoards ()
  22. {
  23. $cnt_query =
  24. $this->CI->db
  25. ->select('brd_key, COUNT(brd_key) AS new_cnt')
  26. ->from('board_post')
  27. ->where('reg_datetime >=', date('Y-m-d H:i:s', strtotime('-1 days')))
  28. ->where('post_status','Y')
  29. ->group_by('brd_key')
  30. ->get_compiled_select();
  31. $board_list =
  32. $this->CI->db
  33. ->select('B.*, IF(ISNULL(BC.new_cnt), 0, new_cnt) AS new_cnt')
  34. ->from('board AS B')
  35. ->join("($cnt_query) AS BC", 'BC.brd_key=B.brd_key','left')
  36. ->get()
  37. ->result_array();
  38. return $board_list;
  39. }
  40. /******************************************************************************************************
  41. * 게시판의 정보를 가져옵니다.
  42. *****************************************************************************************************/
  43. function get($brd_key, $get_raw_data = FALSE) {
  44. return $get_raw_data ? $this->_get_board_raw($brd_key) : $this->_get_board_mixed($brd_key);
  45. }
  46. /******************************************************************************************************
  47. * 가공되지 않은 게시판 정보를 가져옵니다.
  48. *****************************************************************************************************/
  49. private function _get_board_raw($brd_key = "")
  50. {
  51. if(empty($brd_key)) return array();
  52. // 캐시된 데이타가 없으면 DB에서 새로 가져옴
  53. if( ! $board = $this->CI->cache->get('board_raw_'.$brd_key) )
  54. {
  55. $result =
  56. $this->CI->db
  57. ->from('board')
  58. ->where('brd_key', $brd_key)
  59. ->limit(1)
  60. ->get();
  61. $board = $result->row_array();
  62. // 개발환경에선 테스트를 위해 CACHE 저장을 하지 않는다.
  63. if( ENVIRONMENT !== 'development') {
  64. $this->CI->cache->save('board_raw_'.$brd_key, $board, 60*5);
  65. }
  66. }
  67. return $board;
  68. }
  69. /******************************************************************************************************
  70. * 가공된 게시판 정보를 가져옵니다.
  71. *****************************************************************************************************/
  72. private function _get_board_mixed($brd_key ="")
  73. {
  74. if( empty($brd_key) ) return array();
  75. // 캐시된 데이타가 없으면 DB에서 새로 가져옴
  76. if( ! $board = $this->CI->cache->get('board_'.$brd_key) ) {
  77. $board = $this->_get_board_raw($brd_key);
  78. $board['category'] = explode(";", rtrim($board['brd_category'],';'));
  79. if(count($board['category']) > 0) {
  80. foreach($board['category'] as &$row)
  81. {
  82. $row = trim($row);
  83. }
  84. }
  85. // 개발환경에선 테스트를 위해 CACHE 저장을 하지 않는다.
  86. if( ENVIRONMENT !== 'development') {
  87. $this->cache->save('board_'.$brd_key, $board, 60*5);
  88. }
  89. }
  90. return $board;
  91. }
  92. /******************************************************************************************************
  93. * 특정 게시판의 캐시 데이타를 삭제한다.
  94. *****************************************************************************************************/
  95. function delete_cache($brd_key)
  96. {
  97. $this->CI->cache->delete('board_raw_'.$brd_key);
  98. $this->CI->cache->delete('board_'.$brd_key);
  99. }
  100. /******************************************************************************************************
  101. * 특정 게시판의 캐시 데이타를 삭제한다.
  102. *****************************************************************************************************/
  103. function common_data($brd_key)
  104. {
  105. $this->CI->data['board'] = $this->get($brd_key, FALSE);
  106. if( empty($this->CI->data['board']) OR ! isset($this->CI->data['board']))
  107. {
  108. alert('존재하지 않는 게시판 또는 삭제된 게시판입니다.');
  109. exit;
  110. }
  111. $this->CI->data['use_secret'] = ($this->CI->data['board']['brd_use_secret'] == 'Y' OR $this->CI->data['board']['brd_use_secret'] == 'A');
  112. $this->CI->data['use_notice'] = PAGE_ADMIN OR $this->CI->member->is_super();
  113. $this->CI->data['use_category'] = (($this->CI->data['board']['brd_use_category'] == 'Y') && (count($this->CI->data['board']['category']) > 0));
  114. $this->CI->data['board']['brd_skin_l'] = ($this->CI->site->viewmode == DEVICE_MOBILE) ? $this->CI->data['board']['brd_skin_l_m'] : $this->CI->data['board']['brd_skin_l'];
  115. $this->CI->data['board']['brd_skin_w'] = ($this->CI->site->viewmode == DEVICE_MOBILE) ? $this->CI->data['board']['brd_skin_w_m'] : $this->CI->data['board']['brd_skin_w'];
  116. $this->CI->data['board']['brd_skin_c'] = ($this->CI->site->viewmode == DEVICE_MOBILE) ? $this->CI->data['board']['brd_skin_c_m'] : $this->CI->data['board']['brd_skin_c'];
  117. $this->CI->data['board']['brd_skin_v'] = ($this->CI->site->viewmode == DEVICE_MOBILE) ? $this->CI->data['board']['brd_skin_v_m'] : $this->CI->data['board']['brd_skin_v'];
  118. $this->CI->data['board']['brd_page_rows'] = ($this->CI->site->viewmode == DEVICE_MOBILE) ? $this->CI->data['board']['brd_page_rows_m'] : $this->CI->data['board']['brd_page_rows'];
  119. $this->CI->data['board']['brd_fixed_num'] = ($this->CI->site->viewmode == DEVICE_MOBILE) ? $this->CI->data['board']['brd_fixed_num_m'] : $this->CI->data['board']['brd_fixed_num'];
  120. unset($this->CI->data['board']['brd_skin_m'], $this->CI->data['board']['brd_page_rows_m'], $this->CI->data['board']['brd_fixed_num_m']);
  121. // 카테고리 목록
  122. $this->CI->data['category_list'] = ( $this->CI->data['use_category'] && count($this->CI->data['board']['category']) > 0 ) ? $this->CI->data['board']['category'] : NULL;
  123. // GET 데이타 정리
  124. $this->CI->param['page'] = $this->CI->data['page'] = (int)$this->CI->input->get('page', TRUE, 1) >= 1 ? $this->CI->input->get('page', TRUE, 1) : 1;
  125. $this->CI->param['scol'] = $this->CI->data['scol'] = $this->CI->input->get('scol', TRUE, '');
  126. $this->CI->param['stxt'] = $this->CI->data['stxt'] = $this->CI->input->get('stxt', TRUE, '');
  127. $this->CI->param['category'] = $this->CI->data['category'] = $this->CI->input->get('category', TRUE, '');
  128. // 링크 주소 정리
  129. $queryParam = array();
  130. foreach($this->CI->param as $key=>$val) if(! empty($val)) $queryParam[$key] = $val;
  131. $param = ( $queryParam && is_array($queryParam) ) ? '?'.http_build_query($queryParam): '';
  132. $this->CI->data['board']['link']['base_url'] = PAGE_ADMIN ? base_url("admin/board/posts/{$brd_key}") : base_url("board/{$brd_key}");
  133. $this->CI->data['board']['link']['list'] = PAGE_ADMIN ? base_url("admin/board/posts/{$brd_key}{$param}") : base_url("board/{$brd_key}$param");
  134. $this->CI->data['board']['link']['write'] = PAGE_ADMIN ? base_url("admin/board/write/{$brd_key}/{$param}") : base_url( "board/{$brd_key}/write{$param}");
  135. $this->CI->data['board']['link']['rss'] = base_url("rss/{$brd_key}");
  136. if(! empty($post_idx))
  137. {
  138. $this->CI->data['board']['link']['modify'] = PAGE_ADMIN ? base_url( "admin/board/write/{$brd_key}/{$post_idx}{$param}" ) : base_url( "board/{$brd_key}/write/{$post_idx}{$param}");
  139. $this->CI->data['board']['link']['delete'] = base_url( "board/{$brd_key}/delete/{$post_idx}".$param );
  140. $this->CI->data['board']['link']['reply'] = base_url( "board/{$brd_key}/reply/{$post_idx}". $param );
  141. }
  142. $this->CI->data['board']['auth']['admin'] = $this->CI->member->is_super();
  143. $this->CI->data['board']['auth']['read'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_read']) );
  144. $this->CI->data['board']['auth']['list'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_list']) );
  145. $this->CI->data['board']['auth']['write'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_write']) );
  146. $this->CI->data['board']['auth']['download'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_download']) );
  147. $this->CI->data['board']['auth']['comment'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_comment']) );
  148. $this->CI->data['board']['auth']['reply'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_reply']) );
  149. }
  150. /**
  151. * 게시글 목록을 가져온다.
  152. * @param $board
  153. * @param array $param
  154. * @return mixed
  155. */
  156. function post_list($board, $param)
  157. {
  158. $this->CI->db
  159. ->select('SQL_CALC_FOUND_ROWS P.*, IF(ISNULL(M.mem_nickname), P.post_nickname, M.mem_nickname) AS post_nickname', FALSE)
  160. ->from('board_post AS P')
  161. ->join("member AS M", "M.mem_idx=P.upd_user","left")
  162. ->where('brd_key', $board['brd_key'])
  163. ->where_in('post_status', array('Y'))
  164. ->where('post_notice', 'Y')
  165. ->order_by("post_num DESC, post_reply ASC, post_idx ASC");
  166. $result= $this->CI->db->get();
  167. $notice_list['list'] = $result->result_array();
  168. $this->CI->db
  169. ->select('SQL_CALC_FOUND_ROWS P.*, IF(ISNULL(M.mem_nickname), P.post_nickname, M.mem_nickname) AS post_nickname', FALSE)
  170. ->from('board_post AS P')
  171. ->join("member AS M", "M.mem_idx=P.upd_user","left")
  172. ->where('brd_key', $board['brd_key'])
  173. ->where_in('post_status', array('Y','B'))
  174. ->where('post_notice', 'N')
  175. ->order_by("post_num DESC, post_reply ASC, post_idx ASC");
  176. $start = 0;
  177. if( $board['brd_page_limit'] == 'Y' ) {
  178. $page_rows = $board['brd_page_rows'];
  179. $page = element('page', $param, 1);
  180. $start = ($page - 1) * $page_rows;
  181. $this->CI->db->limit($page_rows, $start);
  182. }
  183. if( element('category', $param) ) {
  184. $this->CI->db->where('post_category', $param['category']);
  185. }
  186. if( element('scol', $param) && element('stxt', $param) )
  187. {
  188. if( $param['scol'] == 'title' ) {
  189. $this->CI->db->like('post_title', $param['stxt']);
  190. }
  191. else if ( $param['scol'] == 'nickname' )
  192. {
  193. $this->CI->db->like('post_nickname', $param['stxt']);
  194. }
  195. }
  196. $list['list'] = $this->CI->db->get()->result_array();
  197. $list['total_count'] = (int)$this->CI->db->query("SELECT FOUND_ROWS() AS cnt")->row(0)->cnt;
  198. foreach($list['list'] as $i=>&$row)
  199. {
  200. $row['nums'] = $list['total_count'] - $i - $start;
  201. }
  202. $list['list'] = array_merge($notice_list['list'], $list['list']);
  203. $query_param = $this->get_param();
  204. foreach($list['list'] as &$row)
  205. {
  206. $row = $this->post_process($board, $row, $query_param);
  207. }
  208. return $list;
  209. }
  210. /**
  211. * 게시글 하나를 가져온다.
  212. * @param $brd_key
  213. * @param $post_idx
  214. * @param bool $get_raw_data
  215. * @return mixed
  216. */
  217. function get_post($brd_key, $post_idx, $get_raw_data=FALSE)
  218. {
  219. $this->CI->db
  220. ->select('P.*, IF(ISNULL(M.mem_nickname), P.post_nickname, M.mem_nickname) AS post_nickname')
  221. ->from('board_post AS P')
  222. ->join("member AS M", "M.mem_idx=P.upd_user","left")
  223. ->where('post_idx', $post_idx)
  224. ->where_in('post_status', array('Y','N'))
  225. ->where('brd_key', $brd_key);
  226. $result =$this->CI->db->get();
  227. if(! $post = $result->row_array() )
  228. {
  229. return NULL;
  230. }
  231. if( ! $get_raw_data ) {
  232. $board = $this->get($brd_key, FALSE);
  233. $post = $this->post_process($board, $post, $this->CI->param, TRUE);
  234. $np = $this->get_np($brd_key, $post_idx, $post['post_num'], $post['post_reply']);
  235. $post['prev'] = ( isset($np['prev']) && isset($np['prev']['post_idx']) )? $np['prev'] : NULL;
  236. $post['next'] = ( isset($np['next']) && isset($np['next']['post_idx']) )? $np['next'] : NULL;
  237. }
  238. return $post;
  239. }
  240. /**
  241. * 패러미터 정보를 정리해서 가져옴
  242. * @return string
  243. */
  244. function get_param()
  245. {
  246. // 링크를 위한 자료정리
  247. $queryParam = array();
  248. if( $this->CI->input->get('category', TRUE) ) $queryParam['category'] = $this->CI->input->get('category', TRUE);
  249. if( $this->CI->input->get('page', TRUE) ) $queryParam['page'] = $this->CI->input->get('page', TRUE);
  250. if( $this->CI->input->get('scol', TRUE) ) $queryParam['scol'] = $this->CI->input->get('scol', TRUE);
  251. if( $this->CI->input->get('stxt', TRUE) ) $queryParam['stxt'] = $this->CI->input->get('stxt', TRUE);
  252. $param = "";
  253. if( $queryParam && is_array($queryParam) )
  254. {
  255. $param = http_build_query($queryParam);
  256. $param = "?". $param;
  257. }
  258. return $param;
  259. }
  260. /**
  261. * 게시글의 내용을 정리한다.
  262. * @param $board
  263. * @param $post
  264. * @param $param
  265. * @param bool $extra
  266. * @param bool $files
  267. * @return mixed
  268. */
  269. function post_process($board, $post, $param, $files=FALSE)
  270. {
  271. if(is_array($param))
  272. {
  273. $param = '?' . http_build_query($param);
  274. }
  275. $post['post_notice'] = ($post['post_notice']=='Y');
  276. $post['link'] = PAGE_ADMIN ? base_url("admin/board/read/{$board['brd_key']}/{$post['post_idx']}{$param}") : base_url("board/{$board['brd_key']}/{$post['post_idx']}{$param}");
  277. $post['link_modify'] = PAGE_ADMIN ? base_url("admin/board/write/{$board['brd_key']}/{$post['post_idx']}") : base_url("board/{$board['brd_key']}/write/{$post['post_idx']}");
  278. $post['link_delete'] = base_url("board/{$board['brd_key']}/delete/{$post['post_idx']}");
  279. $post['is_new'] = ((time() - strtotime($post['reg_datetime']) ) <= (24 * 60 * 60));
  280. $post['is_hot'] = ($post['post_hit'] >= 300) ;
  281. $post['is_secret'] = ($post['post_secret'] == 'Y');
  282. $post['post_datetime'] = display_datetime($post['reg_datetime'], $board['brd_display_time']);
  283. if( $files) {
  284. $post['file'] = $this->get_attach_list($board['brd_key'], $post['post_idx']);
  285. }
  286. return $post;
  287. }
  288. /**
  289. * 해당 게시글의 이전글과 다음글을 가져온다.
  290. * @param $brd_key
  291. * @param $post_idx
  292. * @param $post_num
  293. * @param $post_depth
  294. * @return mixed
  295. */
  296. function get_np($brd_key, $post_idx,$post_num,$post_reply)
  297. {
  298. $param = $this->get_param();
  299. $this->CI->db->group_start();
  300. $this->CI->db->or_group_start();
  301. $this->CI->db->where("post_num =", (int)$post_num);
  302. $this->CI->db->where('post_reply >', $post_reply);
  303. $this->CI->db->where('post_idx >', $post_idx);
  304. $this->CI->db->group_end();
  305. $this->CI->db->or_group_start();
  306. $this->CI->db->where('post_num <', $post_num);
  307. $this->CI->db->group_end();
  308. $this->CI->db->group_end();
  309. // 이전글 가져오기
  310. $return['prev'] = $this->CI->db->where_in("post_status", array("Y","B"))
  311. ->where('post_notice', "N")
  312. ->where("brd_key", $brd_key)
  313. ->where('post_idx !=', $post_idx)
  314. ->limit(1)
  315. ->order_by("post_num DESC, post_reply ASC, post_idx ASC")
  316. ->get("board_post")
  317. ->row_array();
  318. if(isset($return['prev']['post_idx']))
  319. {
  320. $return['prev']['link'] = PAGE_ADMIN ? base_url("admin/board/read/{$brd_key}/{$return['prev']['post_idx']}{$param}") : base_url("board/{$brd_key}/{$return['prev']['post_idx']}{$param}");
  321. }
  322. $this->CI->db->group_start();
  323. $this->CI->db->or_group_start();
  324. $this->CI->db->where("post_num =", (int)$post_num);
  325. $this->CI->db->where('post_reply <', $post_reply);
  326. $this->CI->db->where('post_idx <', $post_idx);
  327. $this->CI->db->group_end();
  328. $this->CI->db->or_group_start();
  329. $this->CI->db->where('post_num >', $post_num);
  330. $this->CI->db->group_end();
  331. $this->CI->db->group_end();
  332. // 다음글 가져오기
  333. $return['next'] =
  334. $this->CI->db->where_in("post_status", array("Y","B"))
  335. ->where('post_notice', "N")
  336. ->where("brd_key", $brd_key)
  337. ->where('post_idx !=', $post_idx)
  338. ->limit(1)
  339. ->order_by("post_num ASC, post_reply DESC, post_idx DESC")
  340. ->get("board_post")->row_array();
  341. if(isset($return['next']['post_idx']))
  342. {
  343. $return['next']['link'] = PAGE_ADMIN ? base_url("admin/board/read/{$brd_key}/{$return['next']['post_idx']}{$param}") : base_url("board/{$brd_key}/{$return['next']['post_idx']}{$param}");
  344. }
  345. return $return;
  346. }
  347. /**
  348. * 게시글에 포함된 첨부파일 목록을 가져온다.
  349. * @param $brd_key
  350. * @param $post_idx
  351. * @return array
  352. */
  353. function get_attach_list($brd_key, $post_idx)
  354. {
  355. if(empty($brd_key) OR empty($post_idx)) return array();
  356. $file_list = $this->CI->db->where('att_target_type', 'BOARD')->where('att_target', $post_idx)->get('attach')->result_array();
  357. foreach($file_list as &$f)
  358. {
  359. $f['link'] = base_url("board/{$brd_key}/download/{$post_idx}/{$f['att_idx']}");
  360. }
  361. return $file_list;
  362. }
  363. /**
  364. * 댓글 목록 가져오기
  365. * @param $brd_key
  366. * @param $post_idx
  367. */
  368. function comment_list($brd_key, $post_idx, $board_admin=FALSE, $mem_userid="")
  369. {
  370. $board = $this->get($brd_key, TRUE);
  371. $this->CI->db
  372. ->select('SQL_CALC_FOUND_ROWS C.*, IF(ISNULL(C.cmt_nickname), M.mem_nickname, C.cmt_nickname) AS cmt_nickname', FALSE)
  373. ->from('board_comment AS C')
  374. ->join('member AS M','M.mem_idx=C.reg_user','left')
  375. ->where('brd_key', $brd_key)
  376. ->where('post_idx', $post_idx)
  377. ->where_in('cmt_status', array('Y','B'))
  378. ->order_by("cmt_num DESC,cmt_reply ASC, cmt_idx ASC");
  379. $list['list'] = $this->CI->db->get()->result_array();
  380. $list['total_count'] = (int)$this->CI->db->query('SELECT FOUND_ROWS() AS cnt')->row(0)->cnt;
  381. foreach($list['list'] as &$row)
  382. {
  383. $row['cmt_datetime'] = display_datetime( $row['reg_datetime'], $board['brd_display_time']);
  384. $row['link']['delete'] = base_url("board/{$brd_key}/comment/{$post_idx}/{$row['cmt_idx']}/delete");
  385. $row['link']['blind'] = base_url("board/{$brd_key}/comment/{$post_idx}/{$row['cmt_idx']}/blind");
  386. $row['auth'] = $board_admin || ( $row['reg_user'] >0 && $mem_userid == $row['reg_user'] ) || $row['reg_user']==0;
  387. $row['ip'] = display_ipaddress(long2ip($row['cmt_ip']), '1001');
  388. }
  389. return $list;
  390. }
  391. }