diff --git a/package-lock.json b/package-lock.json index 2b85be5..64b57ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1575,8 +1575,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -1597,14 +1596,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1619,20 +1616,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1749,8 +1743,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1762,7 +1755,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1777,7 +1769,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1785,14 +1776,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1811,7 +1800,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -1892,8 +1880,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -1905,7 +1892,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -1991,8 +1977,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -2028,7 +2013,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2048,7 +2032,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2092,14 +2075,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/wheeparam/application/controllers/Board.php b/wheeparam/application/controllers/Board.php index 5d34c5e..343649e 100644 --- a/wheeparam/application/controllers/Board.php +++ b/wheeparam/application/controllers/Board.php @@ -26,112 +26,7 @@ class Board extends WB_Controller { public function view($brd_key, $post_idx) { $this->board_common($brd_key, 'read'); - $this->data['view'] = $this->boardlib->get_post($brd_key, $post_idx, FALSE); - - if(! in_array( $this->data['view']['post_status'], array("Y","B"))) - { - alert(langs('게시판/msg/invalid_post')); - exit; - } - - // 비밀글일 경우 처리 - if( $this->data['view']['post_secret'] == 'Y' ) - { - $is_auth = FALSE; - - if( !empty($this->data['view']['reg_user']) && $this->data['view']['reg_user'] == $this->member->info('idx') ) - { - $is_auth = TRUE; - } - - if( $this->data['board']['auth']['admin'] ) { - $is_auth = TRUE; - } - - // 해당 글이 답글일 경우 - if( strlen($this->data['view']['post_reply']) > 0 && $this->member->is_login()) - { - // 원글중에 작성자가 있는경우 글을 볼 권한이 있다! - $tmp = $this->db->where('post_num', $this->data['view']['post_num'])->where('brd_key', $brd_key)->get('board_post')->result_array(); - foreach($tmp as $t) - { - if( $t['reg_user'] && $t['reg_user'] == $this->member->info('idx') ) - { - $is_auth = TRUE; - break; - } - } - } - - if(! $is_auth) - { - if( ! $this->session->userdata('post_password_'.$post_idx) ) - { - redirect(base_url("board/{$brd_key}/password/{$post_idx}?w=s&reurl=".current_full_url())); - } - } - } - - // 게시판 조회수 상승 - if( ! $this->session->userdata('post_hit_'.$post_idx) OR (int)$this->session->userdata('post_hit_'.$post_idx) + 60*60*24 < time() ) - { - $this->db->where('post_idx', $post_idx)->set('post_hit', 'post_hit+1', FALSE)->update('board_post'); - $this->data['view']['post_hit'] += 1; - $this->session->set_userdata('post_hit_'.$post_idx, time()); - } - - // 포인트 관련 프로세스 - $this->point_process('brd_point_read', 'POST_READ', '게시글 읽기', $post_idx, ($this->data['view']['reg_user'] == $this->member->info('idx')) ); - - // 링크 추가 - $this->data['board']['link']['reply'] = base_url("board/{$brd_key}/write/?post_parent={$post_idx}"); - $this->data['board']['link']['modify'] = base_url("board/{$brd_key}/write/{$post_idx}"); - $this->data['board']['link']['delete'] = base_url("board/{$brd_key}/delete/{$post_idx}"); - - // 메타태그 설정 - $this->site->meta_title = $this->data['view']['post_title'] . ' - ' . $this->data['board']['brd_title']; // 이 페이지의 타이틀 - $this->site->meta_description = cut_str(get_summary($this->data['view']['post_content'],FALSE),80); // 이 페이지의 요약 설명 - $this->site->meta_keywords = $this->data['view']['post_keywords']; // 이 페이지에서 추가할 키워드 메타 태그 - $this->site->meta_image = $this->data['view']['post_thumbnail']; // 이 페이지에서 표시할 대표이미지 - - // 댓글 입력폼 - - $write_skin_path = DIR_SKIN . "/board/comment/" . $this->data['board']['brd_skin_c'] . "/c_write"; - $comment_hidden = array("reurl"=>current_full_url(),"cmt_idx"=>"","cmt_parent"=>""); - $comment_action_url = base_url( "board/{$brd_key}/comment/{$post_idx}", SSL_VERFIY ? 'https':'http' ); - $tmp['comment_view'] = array(); - $tmp['comment_form_open'] = form_open($comment_action_url,array("id"=>"form-board-comment","data-form"=>"board-comment"), $comment_hidden); - $tmp['comment_form_close'] = form_close(); - $this->data['comment_write'] = $this->data['board']['brd_use_comment'] == 'Y' && $this->data['board']['auth']['comment'] ? $this->load->view($write_skin_path, $tmp, TRUE) : NULL; - - // 댓글 목록 - $list_skin_path = DIR_SKIN . "/board/comment/" . $this->data['board']['brd_skin_c'] . "/c_list"; - if( $this->data['board']['brd_use_comment'] == 'Y' ) - { - $mem_userid = ($this->member->is_login()) ? $this->member->is_login() : ''; - $tmp2['comment_list'] = $this->boardlib->comment_list($brd_key, $post_idx, $this->data['board']['auth']['admin'], $mem_userid); - // 각 댓글마다 대댓글 폼을 만든다. - foreach($tmp2['comment_list']['list'] as &$row) - { - unset($tmp); - $row['comment_form'] = ""; - if(strlen($row['cmt_reply']) < 5) - { - $comment_hidden = array("reurl"=>current_full_url(),"cmt_idx"=>"","cmt_parent"=>$row['cmt_idx']); - $comment_action_url = base_url( "board/{$brd_key}/comment/{$post_idx}", SSL_VERFIY ? 'https':'http' ); - $tmp['comment_view'] = array(); - $tmp['comment_form_open'] = form_open($comment_action_url,array("data-form"=>"board-comment"), $comment_hidden); - $tmp['comment_form_close'] = form_close(); - $row['comment_form'] = $this->data['board']['brd_use_comment'] == 'Y' && $this->data['board']['auth']['comment'] ? $this->load->view($write_skin_path, $tmp, TRUE) : NULL; - } - } - } - $tmp2['board'] = $this->data['board']; - $this->data['comment_list'] = $this->data['board']['brd_use_comment'] == 'Y' ? $this->load->view($list_skin_path, $tmp2, TRUE) : NULL; - - $this->view = "view"; - $this->skin_type = "board/view"; - $this->skin = $this->data['board']['brd_skin_v']; + $this->boardlib->read_process($brd_key, $post_idx); } /** @@ -163,198 +58,10 @@ class Board extends WB_Controller { */ public function comment($brd_key, $post_idx) { - $this->load->library('form_validation'); - - $this->form_validation->set_rules('cmt_content', langs('게시판/comment/form_content'), 'trim|required'); - - if( empty($brd_key) OR empty($post_idx) ) - { - alert(langs('게시판/msg/invalid_access')); - exit; - } - $this->board_common($brd_key,'comment'); - - $data['brd_key'] = $brd_key; - $data['post_idx'] = $post_idx; - $data['cmt_idx'] = $this->input->post('cmt_idx', TRUE); - $data['cmt_parent'] = $this->input->post('cmt_parent', TRUE, 0); - $data['cmt_content'] = $this->input->post('cmt_content', FALSE); - $data['mem_userid'] = ( $this->member->is_login() ) ? $this->member->info('userid') : ''; - $data['mem_password'] = ( $this->member->is_login() ) ? $this->member->info('password') : get_password_hash( $this->input->post('mem_password', FALSE) ); - $data['mem_nickname'] = ( $this->member->is_login() ) ? $this->member->info('nickname') : $this->input->post('mem_nickname'); - $data['cmt_modtime'] = date('Y-m-d H:i:s'); - $data['cmt_ip'] = ip2long( $this->input->ip_address() ); - $data['cmt_status'] = 'Y'; - $data['cmt_mobile'] = $this->site->viewmode == DEVICE_MOBILE ? 'Y' : 'N'; - - $reurl = $this->input->post('reurl', TRUE, base_url("board/{$brd_key}/{$post_idx}") ); - - // 값 유효성 체크 - if( empty($data['cmt_content']) ) - { - alert(langs('게시판/comment/content_required')); - exit; - } - - if( empty($data['mem_nickname']) ) - { - alert(langs('게시판/comment/nickname_required')); - exit; - } - - if( empty($data['mem_password']) ) - { - alert(langs('게시판/comment/password_required')); - exit; - } - - // 신규 등록일경우 - if( empty($data['cmt_idx']) ) - { - $data['cmt_regtime'] = date('Y-m-d H:i:s'); - - if(! empty($data['cmt_parent'])) - { - $parent = $this->db->where('cmt_idx', $data['cmt_parent'])->where_in('cmt_status', array('Y','B'))->where('post_idx', $data['post_idx'])->get('board_comment')->row_array(); - - if(! $parent OR !isset($parent['cmt_idx']) OR ! $parent['cmt_idx']) { - alert('답변할 댓글이 없습니다.\\n답변하는 동안 댓글이 삭제되었을 수 있습니다.'); - exit; - } - - if($parent['post_idx'] != $data['post_idx']) { - alert('댓글을 등록할 수 없습니다.\\n잘못된 방법으로 등록을 요청하였습니다.'); - exit; - } - - if(strlen($parent['cmt_reply']) >= 5) { - alert('더이상 답변을 달수 없습니다.\\n\\n답변은 5단계 까지만 가능합니다.'); - exit; - } - - $reply_len = strlen($parent['cmt_reply']) + 1; - - $begin_reply_char = 'A'; - $end_reply_char = 'Z'; - $reply_number = +1; - - $this->db->select("MAX(SUBSTRING(cmt_reply, {$reply_len}, 1)) AS reply")->from('board_comment')->where('cmt_num', $parent['cmt_num'])->where('post_idx', $data['post_idx'])->where("SUBSTRING(cmt_reply, {$reply_len}, 1) <>", ''); - if($parent['cmt_reply']) $this->db->like('cmt_reply', $parent['cmt_reply'],'after'); - $row = $this->db->get()->row_array(); - - $reply_char =""; - - if(!$row['reply']) $reply_char = $begin_reply_char; - else if ($row['reply'] == $end_reply_char) { - alert('더이상 답변을 달수 없습니다.\\n\\n답변은 26개까지만 가능합니다.'); - exit; - } - else $reply_char = chr(ord($row['reply']) + $reply_number); - - $data['cmt_reply'] = $parent['cmt_reply'] . $reply_char; - $data['cmt_num'] = $parent['cmt_num']; - } - else - { - $tmp = (int)$this->db->select_max('cmt_num','max')->from('board_comment')->where('post_idx',$data['post_idx'])->get()->row(0)->max; - - $data['cmt_reply'] = ""; - $data['cmt_num'] = $tmp+1; - } - - if( $this->db->insert('board_comment', $data) ) - { - // 대댓글을 위한 정보입력 - $cmt_idx = $this->db->insert_id(); - - // 포인트 입력처리 - $this->point_process('brd_point_comment', "CMT_WRITE", "댓글 등록", $cmt_idx, FALSE); - - $this->board_model->update_post_comment_count($brd_key, $post_idx); - alert('댓글 작성이 완료되었습니다.', $reurl); - } - } - // 수정권한이라면 - else - { - // 기존 댓글 정보를 가져온다 - $comment = $this->db->where("cmt_idx", $data['cmt_idx'])->where('brd_key', $brd_key)->where('post_idx', $post_idx)->get('board_comment')->row_array(); - if( ! $comment || ! isset($comment['cmt_idx']) || $comment['cmt_idx'] != $data['cmt_idx'] ) - { - alert(langs('게시판/msg/invalid_comment')); - exit; - } - - if(! $this->data['board']['auth']['admin'] ) - { - // 기존 댓글과 수정권한이 있는지 확인한다. - if( $comment['mem_userid'] ) - { - if( $this->member->is_login() ) - { - if( $this->member->info('userid') != $comment['mem_userid'] ) - { - alert(langs('게시판/msg/comment_modify_unauthorize')); - exit; - } - } - else - { - alert_login(); - exit; - } - } - else - { - if( $data['mem_password'] != $comment['mem_password'] ) - { - alert(langs('게시판/msg/invalid_password')); - exit; - } - } - } - - // 수정일 경우는 바뀌어선 안되는 정보들은 unset - unset($data['brd_key'], $data['post_idx']); - - $this->db->where('brd_key', $brd_key); - $this->db->where('post_idx', $post_idx); - $this->db->where('cmt_idx', $data['cmt_idx']); - if( $this->db->update('board_comment', $data) ) - { - $this->board_model->update_post_comment_count($brd_key, $post_idx); - alert_close(langs('게시판/msg/comment_modify_success'), TRUE); - exit; - } - } - - - alert(langs('게시판/msg/comment_failed')); - exit; + $this->boardlib->comment_process($brd_key, $post_idx); } - /** - * 코멘트 수정/삭제 권한 확인 - * @param $comment - * @return bool - */ - public function _check_comment_modify($comment) - { - if( $this->data['board']['auth']['admin'] ) return TRUE; - - // 댓글 수정/삭제 권한 확인 - if( $comment['mem_userid'] && ! $this->member->is_login() ) - { - return langs('게시판/msg/comment_modify_unauthorize'); - } - else if ( $comment['mem_userid'] && $this->member->is_login() && $this->member->info('userid') != $comment['mem_userid']) - { - return langs('게시판/msg/comment_modify_unauthorize'); - } - - return TRUE; - } /** * 코멘트 수정 폼 @@ -370,25 +77,7 @@ class Board extends WB_Controller { $this->board_common($comment['brd_key']); - if( ($result = $this->_check_comment_modify($comment)) !== TRUE ) - { - alert_close($result); - exit; - } - - $this->site->meta_title = "댓글 수정"; - - $hidden=array("mem_nickname"=>$comment['mem_nickname'],"cmt_idx"=>$comment['cmt_idx'],"cmt_parent"=>$comment['cmt_parent']); - $action_url = base_url('board/'.$comment['brd_key'].'/comment/'.$comment['post_idx'].'/'.$cmt_idx, SSL_VERFIY ? 'https':'http'); - $this->data['comment_form_open'] = form_open($action_url, array("id"=>"form-board-comment","data-form"=>"board-comment"), $hidden); - $this->data['comment_form_close'] = form_close(); - $this->data['comment_view'] = $comment; - $this->data['is_reply'] = FALSE; - - $this->theme_file = "popup"; - $this->skin_type = "board/comment"; - $this->skin = $this->data['board']['brd_skin_c']; - $this->view = "c_write"; + $this->boardlib->comment_modify_form($cmt_idx,$comment); } /** @@ -400,65 +89,7 @@ class Board extends WB_Controller { public function comment_delete($brd_key, $post_idx, $cmt_idx) { $this->board_common($brd_key); - - if( ! $comment = $this->db->where('cmt_idx', $cmt_idx)->where('cmt_status', 'Y')->get('board_comment')->row_array() ) - { - alert(langs('게시판/msg/invalid_comment')); - exit; - } - - if( ! $this->data['board']['auth']['admin'] ) - { - if( ($result = $this->_check_comment_modify($comment)) !== TRUE ) - { - alert($result); - exit; - } - - if( empty($comment['mem_userid']) ) - { - alert(langs('게시판/msg/cannot_delete_guest_comment')); - exit; - } - } - - // 원본 가져오기 - $original = $this->db->where('cmt_idx', $cmt_idx)->get('board_comment')->row_array(); - if(!$original OR !isset($original['cmt_idx'])) - alert('삭제할 원본 댓글이 없습니다.\\ 이미 삭제되엇거나 존재하지 않는 댓글입니다.'); - - - // 이 댓글의 하위 댓글이 있는지 확인 - $len = strlen($original['cmt_reply']); - if ($len < 0) $len = 0; - $comment_reply = substr($original['cmt_reply'], 0, $len); - - $cnt = - $this->db - ->select('COUNT(*) AS cnt') - ->from('board_comment') - ->like('cmt_reply', $comment_reply,'after') - ->where('cmt_idx <>', $cmt_idx) - ->where('cmt_num', $original['cmt_num']) - ->where('post_idx', $original['post_idx']) - ->where('cmt_status', 'Y') - ->where('cmt_parent', $cmt_idx) - ->get()->row(0)->cnt; - - - if($cnt > 0) - alert('삭제하려는 댓글에 답변이 달려있어 삭제할 수 없습니다.'); - - if( $this->db->where('brd_key', $brd_key)->where('post_idx', $post_idx)->where('cmt_idx', $cmt_idx)->set('cmt_status', 'N')->update('board_comment') ) - { - $this->board_model->update_post_comment_count($brd_key, $post_idx); - - // 댓글등록으로 증가한 포인트가 있다면 다시 감소 - $this->point_cancel("CMT_WRITE",$cmt_idx, "댓글삭제"); - - alert(langs('게시판/msg/comment_delete_success')); - exit; - } + $this->boardlib->comment_delete_process($brd_key, $post_idx, $cmt_idx); } @@ -491,7 +122,7 @@ class Board extends WB_Controller { { $reurl = $this->input->post("reurl", TRUE, base_url("board/{$brd_key}/{$post_idx}") ); $password = $this->input->post("password", TRUE); - $post = $this->board_model->get_post($brd_key, $post_idx); + $post = $this->boardlib->get($brd_key, $post_idx); if( get_password_hash($password) == $post['mem_password'] ) { $this->session->set_userdata('post_password_'.$post_idx, TRUE); @@ -506,44 +137,6 @@ class Board extends WB_Controller { } } - /** - * 수정이나 삭제 권한이 있나 확인한다. - * @param $brd_key - * @param $post_idx - */ - public function _modify_auth($brd_key, $post_idx="") - { - if(empty($post_idx)) return; - - $post = $this->board_model->get_post($brd_key, $post_idx, FALSE); - - // 관리자가 아니라면 - if( ! $this->data['board']['auth']['admin'] ) - { - // 회원이 작성한 글이라면 - if( ! empty($post['mem_userid']) ) - { - if( ! $this->member->is_login() ) - { - alert_login( langs('게시판/msg/modify_require_login') ); - exit; - } - else if ( $post['mem_userid'] != $this->member->info('userid') ) - { - alert(langs('게시판/msg/modify_unauthorize')); - exit; - } - } - else - { - if( ! $this->session->userdata('post_password_'.$post_idx) ) - { - redirect(base_url("board/{$brd_key}/password/{$post_idx}?reurl=".current_full_url())); - } - } - } - } - /** * 글쓰기 페이지 * @param $brd_key @@ -551,324 +144,8 @@ class Board extends WB_Controller { */ public function write($brd_key, $post_idx="") { - $this->load->library('form_validation'); $this->board_common($brd_key, 'write'); - - // 수정이라면 권한을 확인한다. - $this->_modify_auth($brd_key, $post_idx); - - $this->form_validation->set_rules('post_title', langs('게시판/form/post_title') ,'required|trim'); - $this->form_validation->set_rules('post_content', langs('게시판/form/post_content'),'required|trim'); - if( ! $this->member->is_login() ) - { - $this->form_validation->set_rules('mem_nickname', langs('게시판/form/mem_nickname') ,'required|trim'); - $this->form_validation->set_rules('mem_password', langs('게시판/form/password') ,'required|trim|min_length[4]|max_length[16]'); - } - - - if( $this->form_validation->run() != FALSE) - { - $this->load->library('upload'); - - if( ! $this->member->is_login() ) - { - // 비회원이고 리캡쳐 설정이 되있을 경우 경우 구글 리캡챠확인 - if( $this->site->config('google_recaptcha_site_key') && $this->site->config('google_recaptcha_secret_key') ) - { - $this->load->library('google_recaptcha'); - $response = $this->input->post('g-recaptcha-response', TRUE); - - if( empty($response) OR ! $this->google_recaptcha->check_response( $response ) ) - { - alert('자동등록 방지 인증에 실패하였습니다.'); - exit; - } - } - // 비회원일이고 수정일 경우 입력한 패스워드와 기존 패스워드 확인 - if( $post_idx ) - { - $post = $this->board_model->get_post($brd_key, $post_idx, FALSE); - - if( get_password_hash( $this->input->post('mem_password', TRUE) ) != $post['mem_password'] ) - { - alert('잘못된 비밀번호 입니다.'); - exit; - } - } - } - - // 받아온 값을 정리한다. - $data['post_title'] = $this->input->post('post_title', TRUE); - $data['bca_idx'] = (int) $this->input->post('bca_idx', TRUE); - $data['post_parent'] = $this->input->post('post_parent', TRUE, 0); - $data['post_secret'] = $this->input->post('post_secret', TRUE, 'N') == 'Y' ? "Y":'N'; - $data['post_content'] = $this->input->post('post_content', FALSE); - $data['brd_key'] = $brd_key; - $data['upd_datetime'] = date('Y-m-d H:i:s'); - $data['post_html'] = $this->data['use_wysiwyg'] ? 'Y' : 'N'; - $data['post_notice'] = $this->input->post('post_notice', TRUE) == 'Y' ? 'Y' : 'N'; - $data['post_ip'] = ip2long( $this->input->ip_address() ); - $data['post_mobile'] = $this->site->viewmode == DEVICE_MOBILE ? 'Y' : 'N'; - $data['post_keywords'] = $this->input->post('post_keywords', TRUE); - for($i=1; $i<=9; $i++) - { - $data['post_ext'.$i] = $this->input->post('post_ext'.$i, TRUE,''); - } - - $parent = array(); - if(! empty( $data['post_parent'] ) ) - { - $parent = $this->board_model->get_post($brd_key, $data['post_parent'], FALSE); - } - - // 관리자가 아니라면 사용할수 없는 옵션 끄기 - if(! $this->data['board']['auth']['admin'] ) - { - $data['post_notice'] = 'N'; - } - - if($this->input->post('post_annonymous', TRUE) == 'Y' OR $this->data['board']['brd_use_anonymous'] == 'A') - { - $data['mem_nickname'] = "익명"; - } - - // 로그인 상태에 따라 값을 수정 - if( $this->member->is_login() ) - { - $data['upd_user'] = $this->member->info('idx'); - $data['post_nickname'] = $this->member->info('nickname'); - $data['post_password'] = $this->member->info('password'); - } - else - { - $data['upd_user'] = 0; - $data['post_nickname'] = $this->input->post('mem_nickname', TRUE); - $data['post_password'] = get_password_hash( $this->input->post('mem_password', TRUE) ); - } - - // 게시판 설정을 이용해서 값 정리 - if( $this->data['board']['brd_use_secret'] == 'N' ) $data['post_secret'] = 'N'; - else if ( $this->data['board']['brd_use_secret'] == 'A' ) $data['post_secret'] = 'Y'; - // 답글인경우 원글이 비밀글이면 답글도 비밀글 - else if ( ! empty($data['post_parent']) && $parent['post_secret'] == 'Y' ) $data['post_secret'] = 'Y'; - - // 파일 업로드가 있다면 - if( $this->data['use_attach'] ) - { - - if( isset($_FILES) && isset($_FILES['userfile']) && count($_FILES['userfile']) > 0 ) - { - $dir_path = DIR_UPLOAD . "/board/{$brd_key}/".date('Y')."/".date('m'); - make_dir($dir_path,FALSE); - - $upload_config['upload_path'] = "./".$dir_path; - $upload_config['file_ext_tolower'] = TRUE; - $upload_config['allowed_types'] = FILE_UPLOAD_ALLOW; - $upload_config['encrypt_name'] = TRUE; - - $this->load->library("upload", $upload_config); - $this->data['upload_array'] = array(); - - // FOR문으로 업로드하기 위해 돌리기 - $files = NULL; - foreach ($_FILES['userfile'] as $key => $value) { - foreach ($value as $noKey => $noValue) { - $files[$noKey][$key] = $noValue; - } - } - unset($_FILES); - - // FOR 문 돌면서 정리 - foreach ($files as $file) { - $_FILES['userfile'] = $file; - $this->upload->initialize($upload_config); - if( ! isset($_FILES['userfile']['tmp_name']) OR ! $_FILES['userfile']['tmp_name']) continue; - if (! $this->upload->do_upload('userfile') ) - { - alert('파일 업로드에 실패하였습니다.\\n'.$this->upload->display_errors(' ',' ')); - exit; - } - else - { - $filedata = $this->upload->data(); - $this->data['upload_array'][] = array( - "att_target_type" => 'BOARD', - "att_origin" => $filedata['orig_name'], - "att_filepath" => $dir_path . "/" . $filedata['file_name'], - "att_downloads" => 0, - "att_filesize" => $filedata['file_size'] * 1024, - "att_width" => $filedata['image_width'] ? $filedata['image_width'] : 0, - "att_height" => $filedata['image_height'] ? $filedata['image_height'] : 0, - "att_ext" => $filedata['file_ext'], - "att_is_image" => ($filedata['is_image'] == 1) ? 'Y' : 'N', - "reg_user" => $this->member->is_login(), - "reg_datetime" => date('Y-m-d H:i:s') - ); - } - } - } - } - - // 첨부파일 삭제가 있다면 삭제한다. - $del_file = $this->input->post("del_file", TRUE); - if( $del_file && count($del_file) > 0 ) - { - foreach($del_file as $att_idx) { - $this->board_model->attach_remove($att_idx); - } - } - - // 외부이미지를복사 꺼놓음.. - //$data['post_content'] = $this->board_model->copy_external_image($data['post_content'], $this->agent->agent_string()); - - // 게시판설정에 관리자승인이 되어있다면 글입력시 자동 미승인상태로 - if( $this->data['board']['brd_use_assign'] == 'Y' && ! PAGE_ADMIN ) - { - $data['post_assign'] = 'N'; - } - - // 수정이냐 신규냐에 따라 값 설정 - if( empty($post_idx) ) - { - $data['post_status'] = 'Y'; - $data['post_count_comment'] = 0; - $data['post_hit'] = 0; - $data['reg_user'] = $data['upd_user']; - $data['reg_datetime'] = $data['upd_datetime']; - - // 답글인경우 - if(! empty($data['post_parent'])) - { - if( strlen($parent['post_reply']) >= 10 ) - { - alert('더 이상 답변하실 수 없습니다.\\n답변은 10단계 까지만 가능합니다.'); - exit; - } - - $reply_len = strlen($parent['post_reply']) + 1; - - $begin_reply_char = 'A'; - $end_reply_char = 'Z'; - $reply_number = +1; - - $reply_char = ""; - - $this->db->select("MAX(SUBSTRING(post_reply, {$reply_len}, 1)) AS reply")->from('board_post')->where('post_num', $parent['post_num'])->where('brd_key', $brd_key)->where("SUBSTRING(post_reply, {$reply_len}, 1) <>", ''); - if($parent['post_reply']) $this->db->like('post_reply', $parent['post_reply'],'after'); - $row = $this->db->get()->row_array(); - - if(! $row['reply']) { - $reply_char = $begin_reply_char; - } - else if ($row['reply'] == $end_reply_char) { - alert("더 이상 답변하실 수 없습니다.\\n답변은 26개 까지만 가능합니다."); - exit; - } - else { - $reply_char = chr(ord($row['reply']) + $reply_number); - } - - $data['post_reply'] = $parent['post_reply'] . $reply_char; - - // 답변의 원글이 비밀글이라면, 비밀번호는 원글과 동일하게 넣는다. - if( $parent['post_secret'] == 'Y' ) { - $data['mem_password'] = $parent['mem_password']; - } - - $data['post_num'] = $parent['post_num']; - } - else { - $tmp = (int)$this->db->select_max('post_num','max')->from('board_post')->where('brd_key',$brd_key)->get()->row(0)->max; - $data['post_reply'] = ""; - $data['post_num'] = $tmp+1; - } - - if(! $this->db->insert('board_post', $data) ) - { - alert(langs('게시판/msg/write_failed')); - exit; - } - - $post_idx = $this->db->insert_id(); - } - else { - $this->db->where('brd_key', $brd_key); - $this->db->where('post_idx', $post_idx); - - if(! $this->db->update('board_post', $data)) - { - alert(langs('게시판/msg/write_failed')); - exit; - } - - } - - // 업로드된 데이타가 있을경우에 DB에 기록 - if(isset($this->data['upload_array']) && count($this->data['upload_array']) >0 ) - { - foreach($this->data['upload_array'] as &$arr) { - $arr['att_target'] = $post_idx; - } - $this->db->insert_batch("attach", $this->data['upload_array']); - } - - // 자신의 글은 바로 볼수 있도록 - if( ! $this->member->is_login() ) - { - $this->session->set_userdata('post_password_'.$post_idx, TRUE); - } - - if($this->member->is_login()) - { - $this->point_process('brd_point_write', "POST_WRITE", "게시글 등록", $post_idx, FALSE); - } - - $insert_data['post_idx'] = $post_idx; - $insert_data['post_status'] = 'Y'; - - alert(langs('게시판/msg/write_success'), base_url("board/{$brd_key}/{$post_idx}")); - exit; - - - } - else { - // 수정일경우를 대비해서 글 고유 pk 넘김 - $this->data['post_idx'] = (int)$post_idx; - $this->data['post_parent'] = $this->input->get('post_parent', TRUE); - $this->data['view'] = empty($post_idx) ? array() : $this->board_model->get_post($brd_key, $post_idx, FALSE); - $this->data['parent'] = empty($this->data['post_parent']) ? array() : $this->board_model->get_post($brd_key, $this->data['post_parent'], FALSE); - - if( $this->data['post_idx'] && (! $this->data['view'] OR ! isset($this->data['view']['post_idx']) OR !$this->data['view']['post_idx'] ) ) - { - alert(langs('게시판/msg/invalid_access')); - exit; - } - - $hidden = array(); - // 답글작성일경우 부모 번호 넘겨주기 - if($this->data['post_parent']) { - $hidden['post_parent'] = $this->data['post_parent']; - - $this->data['view']['post_title'] = "RE : ". $this->data['parent']['post_title']; - } - - $write_url = base_url("board/{$brd_key}/write" . ($post_idx ? '/'.$post_idx : ''), SSL_VERFIY ? "https":'http'); - - $this->data['form_open'] = form_open_multipart($write_url, array("data-form"=>"post", "id"=>"form-post","autocomplete"=>"off"), $hidden); - $this->data['form_close'] = form_close(); - - // 메타태그 설정 - $this->site->meta_title = $this->data['board']['brd_title'] . ' - '. ((empty($post_idx)) ? '새 글 작성' : '글 수정'); // 이 페이지의 타이틀 - $this->site->meta_description = $this->data['board']['brd_description']; // 이 페이지의 요약 설명 - $this->site->meta_keywords = $this->data['board']['brd_keywords']; // 이 페이지에서 추가할 키워드 메타 태그 - $this->site->meta_image = ""; // 이 페이지에서 표시할 대표이미지 - - // 레이아웃 & 뷰파일 설정 - $this->view = "write"; - - $this->skin_type = "board/write"; - $this->skin = $this->data['board']['brd_skin_w']; - } + $this->boardlib->write_process($brd_key, $post_idx); } /** @@ -904,72 +181,6 @@ class Board extends WB_Controller { force_download($name, $data); } - /** - * 게시판에 관련된 포인트를 처리합니다. - * @param $type - * @param $mpo_type - * @param $msg - * @param $target_idx - */ - public function point_process($type, $mpo_type, $msg, $target_idx, $check_writer=FALSE) - { - // 첨부파일 다운시 필요한 포인트가 있다면 확인 - if( $this->data['board'][$type] != 0 ) - { - // 회원일 경우만 실행한다. - if( $this->member->is_login() ) - { - // 본인의 것은 실행하지 않는다. - if( ! $check_writer ) - { - // 이미 처리된 포인트 내역이 있는지 확인한다. (포인트는 한번만 차감/등록한다.) - $res = (int) $this->db->select('COUNT(*) as cnt')->where('target_type', $mpo_type)->where('target_idx', $target_idx)->where('mem_idx', $this->member->is_login())->get('member_point')->row(0)->cnt; - if( $res <= 0) - { - // 포인트 차감일 경우, 해당 포인트가 있는지 확인한다 - if( (int)$this->data['board'][$type] < 0) - { - if( (int)$this->member->info('point') < abs((int)$this->data['board'][$type]) ) - { - alert(langs('회원/point/not_enough') . "({$this->data['board'][$type]})"); - exit; - } - } - - // 포인트 실제 처리 - $this->member->add_point($this->member->is_login(),$this->data['board'][$type."_flag"], $this->data['board'][$type], FALSE, $mpo_type, $msg, $target_idx); - } - } - } - // 비회원일 경우 아예 실행이 불가능하다. - else - { - alert(langs('공통/msg/login_required')); - exit; - } - } - } - - /** - * 게시판에 관련된 포인트를 삭제등의 행동시 취소합니다. - * @param $target_type - * @param $target_idx - * @param $msg - */ - public function point_cancel($target_type, $target_idx, $msg) - { - // 댓글등록으로 증가한 포인트가 있다면 다시 감소 - // 포인트 입력처리 - if( $this->member->is_login() ) - { - $ret = $this->db->where('target_type', $target_type)->where('mem_idx', $this->member->is_login() )->where('target_idx', $target_idx)->where('mpo_value !=','0')->get('member_point')->row_array(); - if( $ret && isset($ret['mpo_value']) && $ret['mpo_value'] != 0 ) - { - $this->member->add_point($this->member->is_login(),$ret['mpo_flag']*-1, $ret['mpo_value'], FALSE, $target_type, $msg, $target_idx); - } - } - } - /** * 게시글 삭제 * @param $brd_key @@ -978,9 +189,9 @@ class Board extends WB_Controller { public function delete($brd_key, $post_idx) { $this->board_common($brd_key); - $this->_modify_auth($brd_key, $post_idx); + $this->boardlib->_check_modify_auth($brd_key, $post_idx); - $post = $this->board_model->get_post($brd_key, $post_idx, FALSE); + $post = $this->boardlib->get($brd_key, $post_idx, FALSE); $len = strlen($post['post_reply']); if( $len < 0 ) $len = 0; @@ -1005,7 +216,7 @@ class Board extends WB_Controller { if( $this->db->where('post_idx', $post_idx)->set('post_status', 'N')->update('board_post') ) { - $this->point_cancel("POST_WRITE", $post_idx, "게시글 삭제"); + $this->boardlib->point_cancel("POST_WRITE", $post_idx, "게시글 삭제"); alert( langs('게시판/msg/delete_success'), base_url("board/{$brd_key}") ); exit; @@ -1017,19 +228,6 @@ class Board extends WB_Controller { } } - /** - * 권한 확인 - * @return array - */ - private function check_auth() - { - $return = array(); - - - - return $return; - } - /** * 게시판마다 공통으로 불러오기 * @param $brd_key @@ -1078,7 +276,7 @@ class Board extends WB_Controller { // 레이아웃 정의 $this->theme = $this->site->get_layout(); $this->skin_type = "board"; - $this->active = "/board/".$this->data['board']['brd_key']; + $this->active = "board/".$this->data['board']['brd_key']; } } \ No newline at end of file diff --git a/wheeparam/application/controllers/admin/Board.php b/wheeparam/application/controllers/admin/Board.php index 26dd379..d8f2bbd 100644 --- a/wheeparam/application/controllers/admin/Board.php +++ b/wheeparam/application/controllers/admin/Board.php @@ -231,241 +231,57 @@ class Board extends WB_Controller } + /** + * 게시글 읽기 + */ function read($brd_key, $post_idx="") { $this->boardlib->common_data($brd_key); - - $this->data['view'] = $this->boardlib->get_post($brd_key, $post_idx, FALSE); - - $this->active = "board/" . $brd_key; + $this->boardlib->read_process($brd_key, $post_idx); $this->theme = "admin"; - $this->view = "board/read"; } + /** + * 게시글 작성/수정 + */ function write($brd_key, $post_idx="") { - $this->load->library('form_validation'); $this->boardlib->common_data($brd_key); + $this->boardlib->write_process($brd_key, $post_idx); + } - $this->form_validation->set_rules('post_title', langs('게시판/form/post_title') ,'required|trim'); - $this->form_validation->set_rules('post_content', langs('게시판/form/post_content'),'required|trim'); + /** + * 댓글 작성/수정 처리부분 + */ + function comment($brd_key, $post_idx) + { + $this->boardlib->common_data($brd_key); + $this->boardlib->comment_process($brd_key, $post_idx); + } - if( $this->form_validation->run() != FALSE) + /** + * 댓글 작성/수정 폼 + */ + function comment_modify($cmt_idx="") + { + if( ! $comment = $this->db->where('cmt_idx', $cmt_idx)->where('cmt_status', 'Y')->get('board_comment')->row_array() ) { - $this->load->library('upload'); - - // 받아온 값을 정리한다. - $data['post_title'] = $this->input->post('post_title', TRUE); - $data['post_category'] = $this->input->post('post_category', TRUE, ''); - $data['post_parent'] = $this->input->post('post_parent', TRUE, 0); - $data['post_secret'] = $this->input->post('post_secret', TRUE, 'N') == 'Y' ? "Y":'N'; - $data['post_content'] = $this->input->post('post_content', FALSE); - $data['brd_key'] = $brd_key; - $data['upd_datetime'] = date('Y-m-d H:i:s'); - $data['upd_user'] = $this->member->is_login(); - $data['post_notice'] = $this->input->post('post_notice', TRUE) == 'Y' ? 'Y' : 'N'; - $data['post_ip'] = ip2long( $this->input->ip_address() ); - $data['post_mobile'] = $this->site->viewmode == DEVICE_MOBILE ? 'Y' : 'N'; - $data['post_keywords'] = $this->input->post('post_keywords', TRUE); - for($i=1; $i<=9; $i++) - { - $data['post_ext'.$i] = $this->input->post('post_ext'.$i, TRUE,''); - } - - $parent = array(); - if(! empty( $data['post_parent'] ) ) - { - $parent = $this->board_model->get_post($brd_key, $data['post_parent'], FALSE); - } - - // 게시판 설정을 이용해서 값 정리 - if( $this->data['board']['brd_use_secret'] == 'N' ) $data['post_secret'] = 'N'; - else if ( $this->data['board']['brd_use_secret'] == 'A' ) $data['post_secret'] = 'Y'; - // 답글인경우 원글이 비밀글이면 답글도 비밀글 - else if ( ! empty($data['post_parent']) && $parent['post_secret'] == 'Y' ) $data['post_secret'] = 'Y'; - - // 파일 업로드가 있다면 - if( isset($_FILES) && isset($_FILES['userfile']) && count($_FILES['userfile']) > 0 ) - { - $dir_path = DIR_UPLOAD . "/board/{$brd_key}/".date('Y')."/".date('m'); - make_dir($dir_path,FALSE); - - $upload_config['upload_path'] = "./".$dir_path; - $upload_config['file_ext_tolower'] = TRUE; - $upload_config['allowed_types'] = FILE_UPLOAD_ALLOW; - $upload_config['encrypt_name'] = TRUE; - - $this->load->library("upload", $upload_config); - $this->data['upload_array'] = array(); - - // FOR문으로 업로드하기 위해 돌리기 - $files = NULL; - foreach ($_FILES['userfile'] as $key => $value) { - foreach ($value as $noKey => $noValue) { - $files[$noKey][$key] = $noValue; - } - } - unset($_FILES); - - // FOR 문 돌면서 정리 - foreach ($files as $file) { - $_FILES['userfile'] = $file; - $this->upload->initialize($upload_config); - if( ! isset($_FILES['userfile']['tmp_name']) OR ! $_FILES['userfile']['tmp_name']) continue; - if (! $this->upload->do_upload('userfile') ) - { - alert('파일 업로드에 실패하였습니다.\\n'.$this->upload->display_errors(' ',' ')); - exit; - } - else - { - $filedata = $this->upload->data(); - $this->data['upload_array'][] = array( - "att_target_type" => 'BOARD', - "att_origin" => $filedata['orig_name'], - "att_filepath" => $dir_path . "/" . $filedata['file_name'], - "att_downloads" => 0, - "att_filesize" => $filedata['file_size'] * 1024, - "att_width" => $filedata['image_width'] ? $filedata['image_width'] : 0, - "att_height" => $filedata['image_height'] ? $filedata['image_height'] : 0, - "att_ext" => $filedata['file_ext'], - "att_is_image" => ($filedata['is_image'] == 1) ? 'Y' : 'N', - "reg_user" => $this->member->is_login(), - "reg_datetime" => date('Y-m-d H:i:s') - ); - } - } - } - - // 첨부파일 삭제가 있다면 삭제한다. - $del_file = $this->input->post("del_file", TRUE); - if( $del_file && count($del_file) > 0 ) - { - foreach($del_file as $att_idx) { - $this->board_model->attach_remove($att_idx); - } - } - - // 수정이냐 신규냐에 따라 값 설정 - if( empty($post_idx) ) - { - $data['mem_userid'] = $this->member->info('userid'); - $data['mem_nickname'] = $this->member->info('nickname'); - $data['mem_password'] = $this->member->info('password'); - - $data['post_regtime'] = date('Y-m-d H:i:s'); - $data['post_status'] = 'Y'; - $data['post_count_comment'] = 0; - $data['post_hit'] = 0; - - // 답글인경우 - if(! empty($data['post_parent'])) - { - if( strlen($parent['post_reply']) >= 10 ) - { - alert('더 이상 답변하실 수 없습니다.\\n답변은 10단계 까지만 가능합니다.'); - exit; - } - - $reply_len = strlen($parent['post_reply']) + 1; - - $begin_reply_char = 'A'; - $end_reply_char = 'Z'; - $reply_number = +1; - - $reply_char = ""; - - $this->db->select("MAX(SUBSTRING(post_reply, {$reply_len}, 1)) AS reply")->from('board_post')->where('post_num', $parent['post_num'])->where('brd_key', $brd_key)->where("SUBSTRING(post_reply, {$reply_len}, 1) <>", ''); - if($parent['post_reply']) $this->db->like('post_reply', $parent['post_reply'],'after'); - $row = $this->db->get()->row_array(); - - if(! $row['reply']) { - $reply_char = $begin_reply_char; - } - else if ($row['reply'] == $end_reply_char) { - alert("더 이상 답변하실 수 없습니다.\\n답변은 26개 까지만 가능합니다."); - exit; - } - else { - $reply_char = chr(ord($row['reply']) + $reply_number); - } - - $data['post_reply'] = $parent['post_reply'] . $reply_char; - - // 답변의 원글이 비밀글이라면, 비밀번호는 원글과 동일하게 넣는다. - if( $parent['post_secret'] == 'Y' ) { - $data['mem_password'] = $parent['mem_password']; - } - - $data['post_num'] = $parent['post_num']; - } - else { - $tmp = (int)$this->db->select_max('post_num','max')->from('board_post')->where('brd_key',$brd_key)->get()->row(0)->max; - $data['post_reply'] = ""; - $data['post_num'] = $tmp+1; - } - - if(! $this->db->insert('board_post', $data) ) - { - alert(langs('게시판/msg/write_failed')); - exit; - } - - $post_idx = $this->db->insert_id(); - } - else { - $this->db->where('brd_key', $brd_key); - $this->db->where('post_idx', $post_idx); - - if(! $this->db->update('board_post', $data)) - { - alert(langs('게시판/msg/write_failed')); - exit; - } - - } - - // 업로드된 데이타가 있을경우에 DB에 기록 - if(isset($this->data['upload_array']) && count($this->data['upload_array']) >0 ) - { - foreach($this->data['upload_array'] as &$arr) { - $arr['att_target'] = $post_idx; - } - $this->db->insert_batch("attach", $this->data['upload_array']); - } - - alert(langs('게시판/msg/write_success'), base_url("admin/board/read/{$brd_key}/{$post_idx}")); + alert_close(langs('게시판/msg/invalid_comment')); exit; } - else { - // 수정일경우를 대비해서 글 고유 pk 넘김 - $this->data['post_idx'] = (int)$post_idx; - $this->data['post_parent'] = $this->input->get('post_parent', TRUE); - $this->data['view'] = empty($post_idx) ? array() : $this->boardlib->get_post($brd_key, $post_idx, FALSE); - $this->data['parent'] = empty($this->data['post_parent']) ? array() : $this->boardlib->get_post($brd_key, $this->data['post_parent'], FALSE); - - if( $this->data['post_idx'] && (! $this->data['view'] OR ! isset($this->data['view']['post_idx']) OR !$this->data['view']['post_idx'] ) ) - { - alert('잘못된 접근입니다.'); - exit; - } - - $hidden = array(); - // 답글작성일경우 부모 번호 넘겨주기 - if($this->data['post_parent']) { - $hidden['post_parent'] = $this->data['post_parent']; - $this->data['view']['post_title'] = "RE : ". $this->data['parent']['post_title']; - } - - $write_url = base_url("admin/board/write/{$brd_key}" . ($post_idx ? '/'.$post_idx : ''), SSL_VERFIY ? "https":'http'); - $this->data['form_open'] = form_open_multipart($write_url, array("autocomplete"=>"off"), $hidden); - $this->data['form_close'] = form_close(); - - // 레이아웃 & 뷰파일 설정 - $this->active = "board/".$brd_key; - $this->theme = "admin"; - $this->view = "board/write"; - } + $this->boardlib->common_data($comment['brd_key']); + $this->boardlib->comment_modify_form($cmt_idx,$comment); + } + /** + * 댓글 삭제 + * @param $brd_key + * @param $post_idx + * @param $cmt_idx + */ + public function comment_delete($brd_key, $post_idx, $cmt_idx) + { + $this->boardlib->common_data($brd_key); + $this->boardlib->comment_delete_process($brd_key, $post_idx, $cmt_idx); } } diff --git a/wheeparam/application/core/WB_Controller.php b/wheeparam/application/core/WB_Controller.php index eb54273..d22ec39 100644 --- a/wheeparam/application/core/WB_Controller.php +++ b/wheeparam/application/core/WB_Controller.php @@ -10,7 +10,7 @@ defined('BASEPATH') OR exit(); class WB_Controller extends CI_Controller { - protected $view = FALSE; + public $view = FALSE; public $data = array(); protected $asides = array(); public $theme = FALSE; diff --git a/wheeparam/application/helpers/common_helper.php b/wheeparam/application/helpers/common_helper.php index a6f136d..c970ee5 100644 --- a/wheeparam/application/helpers/common_helper.php +++ b/wheeparam/application/helpers/common_helper.php @@ -302,6 +302,7 @@ function format_size($bytes, $decimals = 2) { * HTML SYMBOL 변환 *   & · 등을 정상으로 출력 *****************************************************************************************/ + function html_symbol($str) { return preg_replace("/\&([a-z0-9]{1,20}|\#[0-9]{0,3});/i", "&\\1;", $str); @@ -691,86 +692,6 @@ function get_google_map($geo_data = '', $maxwidth = '') return $google_map; } - -/** - * 게시물중에서 - * @param $post - * @param string $thumb_width - * @param string $thumb_height - * @return string|void - */ -function get_post_thumbnail($post, $thumb_width = '', $thumb_height = '') -{ - $CI = & get_instance(); - - if(empty($post) OR !is_array($post)) return ''; - - // 첨부파일중 이미지중 첫번째를 가져온다. - if( isset($post['file']) && count($post['file'])>0) - { - foreach($post['file'] as $file) - { - if($file['att_is_image'] == 'Y') - { - return thumbnail($file['att_filepath'], $thumb_width, $thumb_height); - } - } - } - - $matches = get_editor_image($post['post_content']); - if (! empty($matches)) { - $img = element(0, element(1, $matches)); - if (! empty($img)) { - - preg_match("/src=[\'\"]?([^>\'\"]+[^>\'\"]+)/i", $img, $m); - $src = isset($m[1]) ? $m[1] : ''; - - $p = parse_url($src); - - if (isset($p['host']) && $p['host'] === $CI->input->server('HTTP_HOST') - && strpos($p['path'], '/' . DIR_UPLOAD) !== false) { - $src = str_replace(base_url('/') , '', $src); - $src = thumbnail( $src , $thumb_width, $thumb_height); - } - - return $src; - - } - } - - // 본문 내용중에 iframe 동영상 포함여부를 확인한다. - preg_match_all("/]*src=[\'\"]?([^>\'\"]+[^>\'\"]+)[\'\"]?[^>]*>/i", $post['post_content'], $matches); - for($i=0; $i]*src=[\'\"]?([^>\'\"]+[^>\'\"]+)[\'\"]?[^>]*>/i", $post['post_content'], $matches); - for($i=0; $i[^\s\'\"]+)\s*=\s*(\'|\")?(?P[^\s\'\"]+)(\'|\")?@i', $str, $match); diff --git a/wheeparam/application/libraries/Boardlib.php b/wheeparam/application/libraries/Boardlib.php index 1929f31..659aac0 100644 --- a/wheeparam/application/libraries/Boardlib.php +++ b/wheeparam/application/libraries/Boardlib.php @@ -12,11 +12,8 @@ class Boardlib { function __construct() { $this->CI =& get_instance(); - } - function initialize($brd_key = "") - { - if(empty($brd_key)) return; + $this->CI->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file', 'key_prefix' => PROJECT)); } /****************************************************************************************************** @@ -174,12 +171,12 @@ class Boardlib { } $this->CI->data['board']['auth']['admin'] = $this->CI->member->is_super(); - $this->CI->data['board']['auth']['read'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_read']) ); - $this->CI->data['board']['auth']['list'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_list']) ); - $this->CI->data['board']['auth']['write'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_write']) ); - $this->CI->data['board']['auth']['download'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_download']) ); - $this->CI->data['board']['auth']['comment'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_comment']) ); - $this->CI->data['board']['auth']['reply'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->member->level() >= $this->CI->data['board']['brd_lv_reply']) ); + $this->CI->data['board']['auth']['read'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->CI->member->level() >= $this->CI->data['board']['brd_lv_read']) ); + $this->CI->data['board']['auth']['list'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->CI->member->level() >= $this->CI->data['board']['brd_lv_list']) ); + $this->CI->data['board']['auth']['write'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->CI->member->level() >= $this->CI->data['board']['brd_lv_write']) ); + $this->CI->data['board']['auth']['download'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->CI->member->level() >= $this->CI->data['board']['brd_lv_download']) ); + $this->CI->data['board']['auth']['comment'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->CI->member->level() >= $this->CI->data['board']['brd_lv_comment']) ); + $this->CI->data['board']['auth']['reply'] = ( $this->CI->data['board']['auth']['admin'] OR ($this->CI->member->level() >= $this->CI->data['board']['brd_lv_reply']) ); } /** @@ -434,7 +431,7 @@ class Boardlib { * @param $brd_key * @param $post_idx */ - function comment_list($brd_key, $post_idx, $board_admin=FALSE, $mem_userid="") + function comment_list($brd_key, $post_idx, $board_admin=FALSE, $mem_useridx="") { $board = $this->get($brd_key, TRUE); @@ -455,11 +452,945 @@ class Boardlib { $row['cmt_datetime'] = display_datetime( $row['reg_datetime'], $board['brd_display_time']); $row['link']['delete'] = base_url("board/{$brd_key}/comment/{$post_idx}/{$row['cmt_idx']}/delete"); $row['link']['blind'] = base_url("board/{$brd_key}/comment/{$post_idx}/{$row['cmt_idx']}/blind"); - $row['auth'] = $board_admin || ( $row['reg_user'] >0 && $mem_userid == $row['reg_user'] ) || $row['reg_user']==0; + $row['auth'] = $board_admin || ( $row['reg_user'] >0 && $mem_useridx == $row['reg_user'] ) || $row['reg_user']==0; $row['ip'] = display_ipaddress(long2ip($row['cmt_ip']), '1001'); } return $list; } + /** + * 게시글 작성 처리 + */ + function write_process($brd_key, $post_idx="") + { + // 수정이나 삭제할경우 권한을 확인한다. + if(! empty($post_idx)) $this->_check_modify_auth($brd_key, $post_idx); + + $this->CI->load->library('form_validation'); + + $this->CI->form_validation->set_rules('post_title', langs('게시판/form/post_title') ,'required|trim'); + $this->CI->form_validation->set_rules('post_content', langs('게시판/form/post_content'),'required|trim'); + if( ! $this->CI->member->is_login() ) + { + $this->CI->form_validation->set_rules('post_nickname', langs('게시판/form/mem_nickname') ,'required|trim'); + $this->CI->form_validation->set_rules('post_password', langs('게시판/form/password') ,'required|trim|min_length[4]|max_length[16]'); + } + + if( $this->CI->form_validation->run() != FALSE ) + { + // 비회원이로 리캡쳐 설정이 되있을 경우 구글 리캡챠 확인 + + if( ! $this->CI->member->is_login() ) + { + // 비회원이고 리캡쳐 설정이 되있을 경우 경우 구글 리캡챠확인 + if( $this->CI->site->config('google_recaptcha_site_key') && $this->CI->site->config('google_recaptcha_secret_key') ) + { + $this->CI->load->library('google_recaptcha'); + $response = $this->CI->input->post('g-recaptcha-response', TRUE); + + if( empty($response) OR ! $this->CI->google_recaptcha->check_response( $response ) ) + { + alert('자동등록 방지 인증에 실패하였습니다.'); + exit; + } + } + // 비회원일이고 수정일 경우 입력한 패스워드와 기존 패스워드 확인 + if( $post_idx ) + { + $post = $this->get_post($brd_key, $post_idx, FALSE); + + if( get_password_hash( $this->CI->input->post('post_password', TRUE) ) != $post['post_password'] ) + { + alert('잘못된 비밀번호 입니다.'); + exit; + } + } + } + + // 받아온 값을 정리한다. + $data['post_title'] = $this->CI->input->post('post_title', TRUE); + $data['post_category'] = $this->CI->input->post('post_category', TRUE, ''); + $data['post_parent'] = $this->CI->input->post('post_parent', TRUE, 0); + $data['post_secret'] = $this->CI->input->post('post_secret', TRUE, 'N') == 'Y' ? "Y":'N'; + $data['post_content'] = $this->CI->input->post('post_content', FALSE); + $data['brd_key'] = $brd_key; + $data['upd_datetime'] = date('Y-m-d H:i:s'); + $data['upd_user'] = $this->CI->member->is_login(); + $data['post_notice'] = $this->CI->input->post('post_notice', TRUE) == 'Y' ? 'Y' : 'N'; + $data['post_ip'] = ip2long( $this->CI->input->ip_address() ); + $data['post_mobile'] = $this->CI->site->viewmode == DEVICE_MOBILE ? 'Y' : 'N'; + $data['post_keywords'] = $this->CI->input->post('post_keywords', TRUE); + for($i=1; $i<=9; $i++) $data['post_ext'.$i] = $this->CI->input->post('post_ext'.$i, TRUE,''); + + $parent = array(); + if(! empty( $data['post_parent'] ) ) + { + $parent = $this->get_post($brd_key, $data['post_parent'], FALSE); + } + + // 관리자가 아니라면 사용할수 없는 옵션 끄기 + if( ! PAGE_ADMIN && ! $this->CI->member->is_super() ) + { + $data['post_notice'] = 'N'; + } + + // 익명전용 게시판이라면 게시글도 익명처리 + if($this->CI->input->post('post_annonymous', TRUE) == 'Y' OR $this->CI->data['board']['brd_use_anonymous'] == 'A') + { + $data['post_nickname'] = "익명"; + } + + // 로그인 상태에 따라 값을 수정 + if( $this->CI->member->is_login() ) + { + $data['post_nickname'] = $this->CI->member->info('nickname'); + $data['post_password'] = $this->CI->member->info('password'); + } + else + { + $data['upd_user'] = 0; + $data['post_nickname'] = $this->CI->input->post('post_nickname', TRUE); + $data['post_password'] = get_password_hash( $this->CI->input->post('post_password', TRUE) ); + } + + // 게시판 설정을 이용해서 값 정리 + if( $this->CI->data['board']['brd_use_secret'] == 'N' ) $data['post_secret'] = 'N'; + else if ( $this->CI->data['board']['brd_use_secret'] == 'A' ) $data['post_secret'] = 'Y'; + // 답글인경우 원글이 비밀글이면 답글도 비밀글 + else if ( ! empty($data['post_parent']) && $parent['post_secret'] == 'Y' ) $data['post_secret'] = 'Y'; + + + // 파일 업로드가 있다면 + $upload_array = array(); + if( isset($_FILES) && isset($_FILES['userfile']) && count($_FILES['userfile']) > 0 ) + { + $dir_path = DIR_UPLOAD . "/board/{$brd_key}/".date('Y')."/".date('m'); + make_dir($dir_path,FALSE); + + $upload_config['upload_path'] = "./".$dir_path; + $upload_config['file_ext_tolower'] = TRUE; + $upload_config['allowed_types'] = FILE_UPLOAD_ALLOW; + $upload_config['encrypt_name'] = TRUE; + + $this->CI->load->library("upload", $upload_config); + + // FOR문으로 업로드하기 위해 돌리기 + $files = NULL; + foreach ($_FILES['userfile'] as $key => $value) { + foreach ($value as $noKey => $noValue) { + $files[$noKey][$key] = $noValue; + } + } + unset($_FILES); + + // FOR 문 돌면서 정리 + foreach ($files as $file) { + $_FILES['userfile'] = $file; + $this->CI->upload->initialize($upload_config); + if( ! isset($_FILES['userfile']['tmp_name']) OR ! $_FILES['userfile']['tmp_name']) continue; + if (! $this->CI->upload->do_upload('userfile') ) + { + alert('파일 업로드에 실패하였습니다.\\n'.$this->CI->upload->display_errors(' ',' ')); + exit; + } + else + { + $filedata = $this->upload->data(); + $upload_array[] = array( + "att_target_type" => 'BOARD', + "att_origin" => $filedata['orig_name'], + "att_filepath" => $dir_path . "/" . $filedata['file_name'], + "att_downloads" => 0, + "att_filesize" => $filedata['file_size'] * 1024, + "att_width" => $filedata['image_width'] ? $filedata['image_width'] : 0, + "att_height" => $filedata['image_height'] ? $filedata['image_height'] : 0, + "att_ext" => $filedata['file_ext'], + "att_is_image" => ($filedata['is_image'] == 1) ? 'Y' : 'N', + "reg_user" => $this->CI->member->is_login(), + "reg_datetime" => date('Y-m-d H:i:s') + ); + } + } + } + + // 첨부파일 삭제가 있다면 삭제한다. + $del_file = $this->CI->input->post("del_file", TRUE); + if( $del_file && count($del_file) > 0 ) { + foreach($del_file as $att_idx) { + $this->attach_remove($att_idx); + } + } + + // 게시글의 대표 이미지를 가져온다. + if ( count($upload_array) > 0 ) { + // 첨부파일중에 이미지가 있으면 그중에 가장 먼저나오는걸 설정 + foreach($upload_array as $row) { + if($row['att_is_image'] == 'Y') { + $data['post_thumbnail'] = $row['att_filepath']; + break; + } + } + + // 첨부파일중에 없다면 HTML 코드에서 이미지를 찾아낸다. + if( empty($data['post_thumbnail']) ) { + $matches = get_editor_image($data['post_content']); + if(! empty($matches)) { + $img = element(0, element(1, $matches)); + + if(! empty($img)) { + preg_match("/src=[\'\"]?([^>\'\"]+[^>\'\"]+)/i", $img, $m); + $src = isset($m[1]) ? $m[1] : ''; + + if(! empty($src)) { + $data['post_thumbnail'] = $src; + } + } + } + } + $matches = null; + + // 거기서도 없으면 본문내용에 포함된 iframe 동영상에서.. + if( empty($data['post_thumbnail']) ) { + preg_match_all("/]*src=[\'\"]?([^>\'\"]+[^>\'\"]+)[\'\"]?[^>]*>/i", $data['post_content'], $matches); + for ($i = 0; $i < count($matches[1]); $i++) { + if (!isset($matches[1][$i])) continue; + + $video = get_video_info($matches[1][$i]); + + // 비디오 타입이 아니거나, 알려지지 않은 비디오 일경우 건너뛴다. + if (!$video['type'] OR !$video['thumb']) continue; + + if ($video['thumb']) { + $data['post_thumbnail'] = $video['thumb']; + } + } + } + + // 그래도 없으면 embed 태그 포함여부 확인해서.. + $matches = null; + if( empty($data['post_thumbnail']) ) { + preg_match_all("/]*src=[\'\"]?([^>\'\"]+[^>\'\"]+)[\'\"]?[^>]*>/i", $data['post_content'], $matches); + for($i=0; $i= 10 ) + { + alert('더 이상 답변하실 수 없습니다.\\n답변은 10단계 까지만 가능합니다.'); + exit; + } + + $reply_len = strlen($parent['post_reply']) + 1; + + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + + $reply_char = ""; + $this->CI->db->select("MAX(SUBSTRING(post_reply, {$reply_len}, 1)) AS reply")->from('board_post')->where('post_num', $parent['post_num'])->where('brd_key', $brd_key)->where("SUBSTRING(post_reply, {$reply_len}, 1) <>", ''); + if($parent['post_reply']) $this->CI->db->like('post_reply', $parent['post_reply'],'after'); + $row = $this->CI->db->get()->row_array(); + + if(! $row['reply']) { + $reply_char = $begin_reply_char; + } + else if ($row['reply'] == $end_reply_char) { + alert("더 이상 답변하실 수 없습니다.\\n답변은 26개 까지만 가능합니다."); + exit; + } + else { + $reply_char = chr(ord($row['reply']) + $reply_number); + } + + $data['post_reply'] = $parent['post_reply'] . $reply_char; + + // 답변의 원글이 비밀글이라면, 비밀번호는 원글과 동일하게 넣는다. + if( $parent['post_secret'] == 'Y' ) { + $data['post_password'] = $parent['post_password']; + } + + $data['post_num'] = $parent['post_num']; + } + else { + $tmp = (int)$this->CI->db->select_max('post_num','max')->from('board_post')->where('brd_key',$brd_key)->get()->row(0)->max; + $data['post_reply'] = ""; + $data['post_num'] = $tmp+1; + } + + if(! $this->CI->db->insert('board_post', $data) ) { + alert(langs('게시판/msg/write_failed')); + exit; + } + $post_idx = $this->CI->db->insert_id(); + } + else { + $this->CI->db->where('brd_key', $brd_key)->where('post_idx', $post_idx); + if(! $this->CI->db->update('board_post', $data)) + { + alert(langs('게시판/msg/write_failed')); + exit; + } + } + + // 업로드된 데이타가 있을경우에 DB에 기록 + if(isset($upload_array) && count($upload_array) >0 ) + { + foreach($upload_array as &$arr) { + $arr['att_target'] = $post_idx; + } + $this->CI->db->insert_batch("attach", $upload_array); + } + + // 자신의 글은 비밀글이더라도 바로 보거나, 아니면 수정/삭제를 할수 있도록 세션처리 + if($this->CI->member->is_login() ) { + if( ! PAGE_ADMIN && ! $this->CI->member->is_super() ) + { + $this->point_process('brd_point_write', "POST_WRITE", "게시글 등록", $post_idx, FALSE); + } + + } else { + $this->CI->session->set_userdata('post_password_'.$post_idx, TRUE); + } + + // 이동할 페이지 정의 + $reurl = PAGE_ADMIN ? base_url("admin/board/read/{$brd_key}/{$post_idx}") : base_url("board/{$brd_key}/{$post_idx}"); + alert(langs('게시판/msg/write_success'), $reurl); + exit; + } + else + { + $this->CI->data['post_idx'] = (int)$post_idx; + $this->CI->data['post_parent'] = $this->CI->input->get('post_parent', TRUE); + $this->CI->data['view'] = empty($post_idx) ? array() : $this->get_post($brd_key, $post_idx, FALSE); + $this->CI->data['parent'] = empty($this->CI->data['post_parent']) ? array() : $this->get_post($brd_key, $this->CI->data['post_parent'], FALSE); + + if( $this->CI->data['post_idx'] && (! $this->CI->data['view'] OR ! isset($this->CI->data['view']['post_idx']) OR !$this->CI->data['view']['post_idx'] ) ) + { + alert(langs('게시판/msg/invalid_access')); + exit; + } + + $hidden = array(); + + // 답글작성일경우 부모 번호 넘겨주기 + // 카테고리도 같은 카테고리로 + if($this->CI->data['post_parent']) { + $hidden['post_parent'] = $this->CI->data['post_parent']; + + $this->CI->data['view']['post_title'] = "RE : ". $this->CI->data['parent']['post_title']; + $this->CI->data['view']['post_category'] = $this->CI->data['parent']['post_category']; + } + + $write_url = PAGE_ADMIN ? base_url("admin/board/write/{$brd_key}/{$post_idx}") : base_url("board/{$brd_key}/write/{$post_idx}"); + $this->CI->data['form_open'] = form_open_multipart($write_url, array("autocomplete"=>"off","data-form"=>"post","id"=>"form-post"), $hidden); + $this->CI->data['form_close'] = form_close(); + + $this->CI->view = PAGE_ADMIN ? "board/write" : "write"; + $this->CI->theme = PAGE_ADMIN ? "admin" : $this->CI->site->get_layout(); + $this->CI->active = "board/{$brd_key}"; + + if(! PAGE_ADMIN) { + $this->CI->site->meta_title = $this->CI->data['board']['brd_title'] . ' - '. ((empty($post_idx)) ? '새 글 작성' : '글 수정'); // 이 페이지의 타이틀 + $this->CI->site->meta_description = $this->CI->data['board']['brd_description']; // 이 페이지의 요약 설명 + $this->CI->site->meta_keywords = $this->CI->data['board']['brd_keywords']; // 이 페이지에서 추가할 키워드 메타 태그 + $this->CI->site->meta_image = ""; // 이 페이지에서 표시할 대표이미지 + + $this->CI->skin_type = "board/write"; + $this->CI->skin = $this->CI->data['board']['brd_skin_w']; + } + } + + } + + /** + * 게시글 읽기 처리 + */ + function read_process($brd_key, $post_idx) + { + $this->CI->data['view'] = $this->get_post($brd_key, $post_idx, FALSE); + + if(! in_array( $this->CI->data['view']['post_status'], array("Y","B"))) + { + alert(langs('게시판/msg/invalid_post')); + exit; + } + + // 비밀글일 경우 처리 + if( $this->CI->data['view']['post_secret'] == 'Y' ) + { + $is_auth = FALSE; + + if( PAGE_ADMIN OR $this->CI->member->is_super() ) + { + $is_auth = TRUE; + } + + if( !empty($this->CI->data['view']['reg_user']) && $this->CI->data['view']['reg_user'] == $this->CI->member->info('idx') ) + { + $is_auth = TRUE; + } + + // 해당 글이 답글일 경우 + if( strlen($this->CI->data['view']['post_reply']) > 0 && $this->CI->member->is_login()) + { + // 원글중에 작성자가 있는경우 글을 볼 권한이 있다! + $tmp = $this->CI->db->where('post_num', $this->CI->data['view']['post_num'])->where('brd_key', $brd_key)->get('board_post')->result_array(); + foreach($tmp as $t) + { + if( $t['reg_user'] && $t['reg_user'] == $this->CI->member->info('idx') ) + { + $is_auth = TRUE; + break; + } + } + } + + // 이 과정을 전부했는데도 권한이 없으면 비밀번호 확인 + if(! $is_auth) + { + if( ! $this->CI->session->userdata('post_password_'.$post_idx) ) + { + redirect(base_url("board/{$brd_key}/password/{$post_idx}?w=s&reurl=".current_full_url())); + } + } + } + + // 게시판 조회수 상승 + if( ! PAGE_ADMIN ) { + if( ! $this->CI->session->userdata('post_hit_'.$post_idx) OR (int)$this->CI->session->userdata('post_hit_'.$post_idx) + 60*60*24 < time() ) + { + $this->CI->db->where('post_idx', $post_idx)->set('post_hit', 'post_hit+1', FALSE)->update('board_post'); + $this->CI->data['view']['post_hit'] += 1; + $this->CI->session->set_userdata('post_hit_'.$post_idx, time()); + } + + // 포인트 관련 프로세스 + $this->point_process('brd_point_read', 'POST_READ', '게시글 읽기', $post_idx, ($this->CI->data['view']['reg_user'] == $this->CI->member->info('idx')) ); + + + // 메타태그 설정 + $this->CI->site->meta_title = $this->CI->data['view']['post_title'] . ' - ' . $this->CI->data['board']['brd_title']; // 이 페이지의 타이틀 + $this->CI->site->meta_description = cut_str(get_summary($this->CI->data['view']['post_content'],FALSE),80); // 이 페이지의 요약 설명 + $this->CI->site->meta_keywords = $this->CI->data['view']['post_keywords']; // 이 페이지에서 추가할 키워드 메타 태그 + $this->CI->site->meta_image = $this->CI->data['view']['post_thumbnail']; // 이 페이지에서 표시할 대표이미지 + } + + // 링크 만들기 + $this->CI->data['board']['link']['reply'] = PAGE_ADMIN ? base_url("admin/board/write/{$brd_key}/?post_parent={$post_idx}") : base_url("board/{$brd_key}/write/?post_parent={$post_idx}"); + $this->CI->data['board']['link']['modify'] = PAGE_ADMIN ? base_url("admin/board/write/{$brd_key}/{$post_idx}") : base_url("board/{$brd_key}/write/{$post_idx}"); + $this->CI->data['board']['link']['delete'] = PAGE_ADMIN ? '': base_url("board/{$brd_key}/delete/{$post_idx}"); + + // 댓글 입력폼 + $write_skin_path = DIR_SKIN . "/board/comment/" . $this->CI->data['board']['brd_skin_c'] . "/c_write"; + $comment_hidden = array("reurl"=>current_full_url(),"cmt_idx"=>"","cmt_parent"=>""); + $comment_action_url = PAGE_ADMIN ? base_url("admin/board/comment/{$brd_key}/{$post_idx}") : base_url( "board/{$brd_key}/comment/{$post_idx}"); + + $tmp['comment_view'] = array(); + $tmp['comment_form_open'] = form_open($comment_action_url,array("id"=>"form-board-comment","data-form"=>"board-comment"), $comment_hidden); + $tmp['comment_form_close'] = form_close(); + $this->CI->data['comment_write'] = $this->CI->data['board']['brd_use_comment'] == 'Y' && $this->CI->data['board']['auth']['comment'] ? $this->CI->load->view($write_skin_path, $tmp, TRUE) : NULL; + + // 댓글 목록 + $list_skin_path = DIR_SKIN . "/board/comment/" . $this->CI->data['board']['brd_skin_c'] . "/c_list"; + if( $this->CI->data['board']['brd_use_comment'] == 'Y' ) + { + $mem_useridx = $this->CI->member->is_login(); + $this->CI->data['comment_list'] = $this->comment_list($brd_key, $post_idx, $this->CI->data['board']['auth']['admin'], $mem_useridx); + + // 각 댓글마다 대댓글 폼을 만든다. + foreach($this->CI->data['comment_list']['list'] as &$row) + { + unset($tmp); + $row['comment_form'] = ""; + if(strlen($row['cmt_reply']) < 5) + { + $comment_hidden = array("reurl"=>current_full_url(),"cmt_idx"=>"","cmt_parent"=>$row['cmt_idx']); + $tmp['comment_view'] = array(); + $tmp['comment_form_open'] = form_open($comment_action_url, array("data-form"=>"board-comment"), $comment_hidden); + $tmp['comment_form_close'] = form_close(); + $row['comment_form'] = $this->CI->data['board']['brd_use_comment'] == 'Y' && $this->CI->data['board']['auth']['comment'] ? $this->CI->load->view($write_skin_path, $tmp, TRUE) : NULL; + } + } + } + $tmp2['board'] = $this->CI->data['board']; + $this->CI->data['comments'] = $this->CI->data['comment_list']; + $tmp2['comment_list'] = $this->CI->data['comment_list']; + + $this->CI->data['comment_list'] = $this->CI->data['board']['brd_use_comment'] == 'Y' ? $this->CI->load->view($list_skin_path, $tmp2, TRUE) : NULL; + + $this->CI->view = PAGE_ADMIN ? "board/read" : "view"; + $this->CI->active = "board/" . $brd_key; + $this->CI->theme = PAGE_ADMIN ? "admin" : $this->CI->site->get_layout(); + + if(! PAGE_ADMIN) { + $this->CI->skin_type = "board/view"; + $this->CI->skin = $this->CI->data['board']['brd_skin_v']; + } + } + + /** + * 댓글 입력 처리 + */ + function comment_process($brd_key, $post_idx) + { + $this->CI->load->library('form_validation'); + + $this->CI->form_validation->set_rules('cmt_content', langs('게시판/comment/form_content'), 'trim|required'); + + if( empty($brd_key) OR empty($post_idx) ) + { + alert(langs('게시판/msg/invalid_access')); + exit; + } + + $data['brd_key'] = $brd_key; + $data['post_idx'] = $post_idx; + $data['cmt_idx'] = $this->CI->input->post('cmt_idx', TRUE); + $data['cmt_parent'] = $this->CI->input->post('cmt_parent', TRUE, 0); + $data['cmt_content'] = $this->CI->input->post('cmt_content', FALSE); + $data['upd_user'] = $this->CI->member->is_login(); + $data['cmt_password'] = ( $this->CI->member->is_login() ) ? $this->CI->member->info('password') : get_password_hash( $this->CI->input->post('cmt_password', FALSE) ); + $data['cmt_nickname'] = ( $this->CI->member->is_login() ) ? $this->CI->member->info('nickname') : $this->CI->input->post('cmt_nickname'); + $data['upd_datetime'] = date('Y-m-d H:i:s'); + $data['cmt_ip'] = ip2long( $this->CI->input->ip_address() ); + $data['cmt_status'] = 'Y'; + $data['cmt_mobile'] = $this->CI->site->viewmode == DEVICE_MOBILE ? 'Y' : 'N'; + $base_reurl = PAGE_ADMIN ? base_url("admin/board/read/{$brd_key}/{$post_idx}") : base_url("board/{$brd_key}/{$post_idx}"); + $reurl = $this->CI->input->post('reurl', TRUE, $base_reurl ); + + // 값 유효성 체크 + if( empty($data['cmt_content']) ) + { + alert(langs('게시판/comment/content_required')); + exit; + } + + if( empty($data['cmt_nickname']) ) + { + alert(langs('게시판/comment/nickname_required')); + exit; + } + + if( empty($data['cmt_password']) ) + { + alert(langs('게시판/comment/password_required')); + exit; + } + + // 신규 등록일 경우 + if( empty($data['cmt_idx']) ) { + $data['reg_datetime'] = $data['upd_datetime']; + $data['reg_user'] = $data['upd_user']; + + if(! empty($data['cmt_parent'])) { + $parent = $this->CI->db->where('cmt_idx', $data['cmt_parent'])->where_in('cmt_status', array('Y','B'))->where('post_idx', $data['post_idx'])->get('board_comment')->row_array(); + + if(! $parent OR !isset($parent['cmt_idx']) OR ! $parent['cmt_idx']) { + alert('답변할 댓글이 없습니다.\\n답변하는 동안 댓글이 삭제되었을 수 있습니다.'); + exit; + } + + if($parent['post_idx'] != $data['post_idx']) { + alert('댓글을 등록할 수 없습니다.\\n잘못된 방법으로 등록을 요청하였습니다.'); + exit; + } + + if(strlen($parent['cmt_reply']) >= 5) { + alert('더이상 답변을 달수 없습니다.\\n\\n답변은 5단계 까지만 가능합니다.'); + exit; + } + + $reply_len = strlen($parent['cmt_reply']) + 1; + + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + + $this->CI->db->select("MAX(SUBSTRING(cmt_reply, {$reply_len}, 1)) AS reply")->from('board_comment')->where('cmt_num', $parent['cmt_num'])->where('post_idx', $data['post_idx'])->where("SUBSTRING(cmt_reply, {$reply_len}, 1) <>", ''); + if($parent['cmt_reply']) $this->CI->db->like('cmt_reply', $parent['cmt_reply'],'after'); + $row = $this->CI->db->get()->row_array(); + + + $reply_char =""; + + if(!$row['reply']) $reply_char = $begin_reply_char; + else if ($row['reply'] == $end_reply_char) { + alert('더이상 답변을 달수 없습니다.\\n\\n답변은 26개까지만 가능합니다.'); + exit; + } + else $reply_char = chr(ord($row['reply']) + $reply_number); + + $data['cmt_reply'] = $parent['cmt_reply'] . $reply_char; + $data['cmt_num'] = $parent['cmt_num']; + } else { + $tmp = (int)$this->CI->db->select_max('cmt_num','max')->from('board_comment')->where('post_idx',$data['post_idx'])->get()->row(0)->max; + + $data['cmt_reply'] = ""; + $data['cmt_num'] = $tmp+1; + } + + if( $this->CI->db->insert('board_comment', $data) ) + { + // 대댓글을 위한 정보입력 + $cmt_idx = $this->CI->db->insert_id(); + + // 포인트 입력처리 + $this->point_process('brd_point_comment', "CMT_WRITE", "댓글 등록", $cmt_idx, FALSE); + + $this->update_post_comment_count($brd_key, $post_idx); + alert('댓글 작성이 완료되었습니다.', $reurl); + } else { + alert(langs('게시판/msg/comment_failed')); + exit; + } + + } else { + // 기존 댓글 정보를 가져온다 + $comment = $this->CI->db->where("cmt_idx", $data['cmt_idx'])->where('brd_key', $brd_key)->where('post_idx', $post_idx)->get('board_comment')->row_array(); + if( ! $comment || ! isset($comment['cmt_idx']) || $comment['cmt_idx'] != $data['cmt_idx'] ) + { + alert(langs('게시판/msg/invalid_comment')); + exit; + } + + if( ! PAGE_ADMIN && ! $this->CI->member->is_super() ) + { + // 기존 댓글과 수정권한이 있는지 확인한다. + if( ! empty( $comment['reg_user']) ) + { + if( $this->CI->member->is_login() ) + { + if( $this->CI->member->is_login() != $comment['reg_user'] ) + { + alert(langs('게시판/msg/comment_modify_unauthorize')); + exit; + } + } + else + { + alert_login(); + exit; + } + } + else + { + if( $data['cmt_password'] != $comment['cmt_password'] ) + { + alert(langs('게시판/msg/invalid_password')); + exit; + } + } + } + + // 수정일 경우는 바뀌어선 안되는 정보들은 unset + unset($data['brd_key'], $data['post_idx']); + + $this->CI->db->where('brd_key', $brd_key)->where('post_idx', $post_idx)->where('cmt_idx', $data['cmt_idx']); + if( $this->CI->db->update('board_comment', $data) ) + { + $this->update_post_comment_count($brd_key, $post_idx); + alert_close(langs('게시판/msg/comment_modify_success'), TRUE); + exit; + } else { + alert(langs('게시판/msg/comment_failed')); + exit; + } + } + } + + /** + * 댓글 입력폼 + */ + function comment_modify_form($cmt_idx="", $comment) + { + if( ($result = $this->_check_comment_modify($comment)) !== TRUE ) + { + alert_close($result); + exit; + } + + $this->CI->site->meta_title = "댓글 수정"; + + $hidden=array("cmt_nickname"=>$comment['cmt_nickname'],"cmt_idx"=>$comment['cmt_idx'],"cmt_parent"=>$comment['cmt_parent']); + $action_url = PAGE_ADMIN ? base_url("admin/board/comment/{$comment['brd_key']}/{$comment['post_idx']}/{$cmt_idx}"): base_url('board/'.$comment['brd_key'].'/comment/'.$comment['post_idx'].'/'.$cmt_idx); + $this->CI->data['comment_form_open'] = form_open($action_url, array("id"=>"form-board-comment","data-form"=>"board-comment"), $hidden); + $this->CI->data['comment_form_close'] = form_close(); + $this->CI->data['comment_view'] = $comment; + $this->CI->data['is_reply'] = FALSE; + + $this->CI->theme = $this->CI->site->get_layout(); + $this->CI->theme_file = "popup"; + $this->CI->skin_type = "board/comment"; + $this->CI->skin = $this->CI->data['board']['brd_skin_c']; + $this->CI->view = "c_write"; + } + + /** + * 댓글 삭제 처리 + */ + public function comment_delete_process($brd_key, $post_idx, $cmt_idx) + { + + if( ! $comment = $this->CI->db->where('cmt_idx', $cmt_idx)->where('cmt_status', 'Y')->get('board_comment')->row_array() ) + { + alert(langs('게시판/msg/invalid_comment')); + exit; + } + + + // 권한 확인 + if( ! PAGE_ADMIN && ! $this->CI->member->is_super() ) + { + if( ($result = $this->_check_comment_modify($comment)) !== TRUE ) + { + alert($result); + exit; + } + + if( empty($comment['reg_user']) ) + { + alert(langs('게시판/msg/cannot_delete_guest_comment')); + exit; + } + } + + // 원본 가져오기 + $original = $this->CI->db->where('cmt_idx', $cmt_idx)->get('board_comment')->row_array(); + if(!$original OR !isset($original['cmt_idx'])) + alert('삭제할 원본 댓글이 없습니다.\\ 이미 삭제되엇거나 존재하지 않는 댓글입니다.'); + + + // 이 댓글의 하위 댓글이 있는지 확인 + $len = strlen($original['cmt_reply']); + if ($len < 0) $len = 0; + $comment_reply = substr($original['cmt_reply'], 0, $len); + + + $cnt = + $this->CI->db + ->select('COUNT(*) AS cnt') + ->from('board_comment') + ->like('cmt_reply', $comment_reply,'after') + ->where('cmt_idx <>', $cmt_idx) + ->where('cmt_num', $original['cmt_num']) + ->where('post_idx', $original['post_idx']) + ->where('cmt_status', 'Y') + ->where('cmt_parent', $cmt_idx) + ->get()->row(0)->cnt; + + + if($cnt > 0) + alert('삭제하려는 댓글에 답변이 달려있어 삭제할 수 없습니다.'); + + if( $this->CI->db->where('brd_key', $brd_key)->where('post_idx', $post_idx)->where('cmt_idx', $cmt_idx)->set('cmt_status', 'N')->update('board_comment') ) + { + $this->update_post_comment_count($brd_key, $post_idx); + + // 댓글등록으로 증가한 포인트가 있다면 다시 감소 + $this->point_cancel("CMT_WRITE",$cmt_idx, "댓글삭제"); + + alert(langs('게시판/msg/comment_delete_success')); + exit; + } + + } + + + /** + * 코멘트 수정/삭제 권한 확인 + * @param $comment + * @return bool + */ + public function _check_comment_modify($comment) + { + if( PAGE_ADMIN OR $this->CI->member->is_super() ) return TRUE; + + // 댓글 수정/삭제 권한 확인 + if( $comment['reg_user'] && ! $this->CI->member->is_login() ) + { + return langs('게시판/msg/comment_modify_unauthorize'); + } + else if ( $comment['reg_user'] && $this->CI->member->is_login() && $this->CI->member->is_login() != $comment['reg_user']) + { + return langs('게시판/msg/comment_modify_unauthorize'); + } + + return TRUE; + } + + /** + * 수정이나 삭제 권한을 확인한다. + */ + private function _check_modify_auth($brd_key, $post_idx="") + { + if(empty($post_idx)) return; + if(PAGE_ADMIN) return; // 관리자 페이지일 경우도 리턴 + + $post = $this->get_post($brd_key, $post_idx, FALSE); + + if( $this->CI->member->is_super()) return; // 관리자일경우 체크하지 않는다. + if(! empty($post['reg_user']) ) + { + if( ! $this->CI->member->is_login() ) + { + alert_login( langs('게시판/msg/modify_require_login') ); + exit; + } + else if ( $post['reg_user'] != $this->CI->member->info('idx') ) + { + alert(langs('게시판/msg/modify_unauthorize')); + exit; + } + } + else + { + if(! $this->CI->session->userdata('post_password_'.$post_idx)) + { + redirect(base_url("board/{$brd_key}/password/{$post_idx}?reurl=".current_full_url())); + } + } + } + + /********************************************************** + * 첨부파일 삭제 + * @param $bfi_idx + * @return mixed + *********************************************************/ + function attach_remove($att_idx) + { + if(empty($att_idx)) return false; + $this->CI->db->where("att_idx", $att_idx); + $result = $this->CI->db->get('attach'); + $attach = $result->row_array(); + if(! $attach) return false; + if( file_exists(FCPATH. $attach['att_filepath']) ) + { + @unlink(FCPATH.$attach['att_filepath']); + } + $this->CI->db->where("att_idx", $att_idx); + $this->CI->db->delete("attach"); + } + + /** + * 게시판에 관련된 포인트를 처리합니다. + * @param $type + * @param $mpo_type + * @param $msg + * @param $target_idx + */ + public function point_process($type, $mpo_type, $msg, $target_idx, $check_writer=FALSE) + { + // 첨부파일 다운시 필요한 포인트가 있다면 확인 + if( $this->CI->data['board'][$type] != 0 ) + { + // 회원일 경우만 실행한다. + if( $this->CI->member->is_login() ) + { + // 본인의 것은 실행하지 않는다. + if( ! $check_writer ) + { + // 이미 처리된 포인트 내역이 있는지 확인한다. (포인트는 한번만 차감/등록한다.) + $res = (int) $this->CI->db->select('COUNT(*) as cnt')->where('target_type', $mpo_type)->where('target_idx', $target_idx)->where('mem_idx', $this->CI->member->is_login())->get('member_point')->row(0)->cnt; + if( $res <= 0) + { + // 포인트 차감일 경우, 해당 포인트가 있는지 확인한다 + if( (int)$this->CI->data['board'][$type] != 0) + { + if( $this->CI->data['board'][$type."_flag"] > 0) { + // 포인트 상승일 경우 처리 + + } else { + // 포인트 감소일 경우 회원에게 남은 포인트가 있는지 확인한다. + + if( (int)$this->CI->member->info('point') < (int)$this->CI->data['board'][$type] ) + { + alert(langs('회원/point/not_enough') . "({$this->CI->data['board'][$type]})"); + exit; + } + } + + } + + // 포인트 실제 처리 + $this->CI->member->add_point($this->CI->member->is_login(),$this->CI->data['board'][$type."_flag"], $this->CI->data['board'][$type], FALSE, $mpo_type, $msg, $target_idx); + } + } + } + // 비회원일 경우 아예 실행이 불가능하다. + else + { + alert(langs('공통/msg/login_required')); + exit; + } + } + } + + /** + * 게시판에 관련된 포인트를 삭제등의 행동시 취소합니다. + * @param $target_type + * @param $target_idx + * @param $msg + */ + public function point_cancel($target_type, $target_idx, $msg) + { + // 댓글등록으로 증가한 포인트가 있다면 다시 감소 + // 포인트 입력처리 + if( $this->CI->member->is_login() ) + { + $ret = $this->CI->db->where('target_type', $target_type)->where('mem_idx', $this->CI->member->is_login() )->where('target_idx', $target_idx)->where('mpo_value !=','0')->get('member_point')->row_array(); + if( $ret && isset($ret['mpo_value']) && $ret['mpo_value'] != 0 ) + { + $this->CI->member->add_point($this->CI->member->is_login(),$ret['mpo_flag']*-1, $ret['mpo_value'], FALSE, $target_type, $msg, $target_idx); + } + } + } + + /** + * 해당 게시글의 코멘트가 몇개인지 확인한다. + * @param $brd_key + * @param $post_idx + */ + function get_comment_count($brd_key, $post_idx) + { + $count = (int)$this->CI->db->select('COUNT(*) AS cnt')->from('board_comment')->where_in('cmt_status', array('Y','B'))->where('brd_key',$brd_key)->where('post_idx',$post_idx)->get()->row(0)->cnt; + return $count; + } + + + /** + * 해당 게시물의 댓글수를 최신화 한다 + * @param $brd_key + * @param $post_idx + */ + function update_post_comment_count($brd_key, $post_idx) + { + $count = $this->get_comment_count($brd_key, $post_idx); + + $this->CI->db->where('brd_key', $brd_key)->where('post_idx', $post_idx)->set('post_count_comment', (int)$count); + return $this->CI->db->update('board_post'); + } + } \ No newline at end of file diff --git a/wheeparam/application/models/Board_model.php b/wheeparam/application/models/Board_model.php deleted file mode 100644 index e1510fc..0000000 --- a/wheeparam/application/models/Board_model.php +++ /dev/null @@ -1,166 +0,0 @@ -load->driver('cache', array('adapter' => 'apc', 'backup' => 'file', 'key_prefix' => PROJECT)); - } - - - /** - * 글 내용중 외부서버의 이미지를 내부서버로 복제한다. - * @param $content - */ - function copy_external_image($content, $user_agent) - { - // 외부서버의 이미지를 내부 서버로 복제한다. - preg_match_all('/]*)>/',$content, $matches_img); - - if(isset($matches_img[2]) && count($matches_img[2]) > 0) - { - foreach($matches_img[2] as $img) { - $img = preg_replace('/\?.*/', '', $img); - - $img_server = parse_url($img); - $cdn_server = parse_url(base_url()); - - // 만약 같은서버에 올려진 파일이라면 지나간다. - if (isset($img_server['host']) && $img_server['host'] === $cdn_server['host']) { - continue; - } - - // 파일의 확장자를 구한다. - $read_img = $img; - $fileinfo = pathinfo($read_img); - $ext = (isset($fileinfo['extension']) && $fileinfo['extension']) ? $fileinfo['extension'] : ""; - - // curl로 파일을 복사해온다. - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $read_img); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_REFERER, $read_img); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $img_content = curl_exec ($ch); - $curl_info = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); - - make_dir(DIR_UPLOAD . DIRECTORY_SEPARATOR . "editor", TRUE); - $file_path_add = "./"; - $new_file_src = DIR_UPLOAD . "/editor/" .date('Y/m') ."/" .md5(time().$img) . ($ext?".".$ext:""); - $new_url = base_url($new_file_src); - - $fh = fopen($file_path_add.$new_file_src, 'w'); - fwrite($fh, $img_content); - fclose($fh); - curl_close($ch); - - $imagesize = getimagesize($file_path_add.$new_file_src); - - if( $imagesize) { - // 기존 html의 경로 바꾸기 - $content = str_replace( $img, $new_url, $content ); - } - } - } - - return $content; - } - - /** - * 패러미터 정보를 가져온다. - * @return string - */ - - /** - * 게시글에 포함된 첨부파일 목록을 가져온다. - * @param $brd_key - * @param $post_idx - * @return array - */ - function get_attach_list($brd_key, $post_idx) - { - if(empty($brd_key) OR empty($post_idx)) return array(); - $file_list = $this->db->where('att_target_type', 'BOARD')->where('att_target', $post_idx)->get('attach')->result_array(); - foreach($file_list as &$f) - { - $f['link'] = base_url("board/{$brd_key}/download/{$post_idx}/{$f['att_idx']}"); - } - return $file_list; - } - - - - /********************************************************** - * 첨부파일 삭제 - * @param $bfi_idx - * @return mixed - *********************************************************/ - function attach_remove($att_idx) - { - if(empty($att_idx)) return false; - $this->db->where("att_idx", $att_idx); - $result = $this->db->get('attach'); - $attach = $result->row_array(); - if(! $attach) return false; - if( file_exists(FCPATH. $attach['att_filepath']) ) - { - @unlink(FCPATH.$attach['att_filepath']); - } - $this->db->where("att_idx", $att_idx); - $this->db->delete("attach"); - } - - /** - * 해당 게시판에 관리자 권한이 있는지 확인한다. - * @param $brd_key - * @param $member_idx - * @return bool - */ - function is_admin($brd_key, $member_idx) - { - if( empty($member_idx) OR $member_idx == 0 ) - { - return FALSE; - } - - $result = (int)$this->db->select('COUNT(*) AS cnt')->where('ath_type','BOARD')->where('ath_key', $brd_key)->where('mem_idx', $member_idx)->get('member_auth')->row(0)->cnt; - return ( $result > 0 ); - } - - - /** - * 해당 게시글의 코멘트가 몇개인지 확인한다. - * @param $brd_key - * @param $post_idx - */ - function get_comment_count($brd_key, $post_idx) - { - $count = (int)$this->db->select('COUNT(*) AS cnt')->from('board_comment')->where_in('cmt_status', array('Y','B'))->where('brd_key',$brd_key)->where('post_idx',$post_idx)->get()->row(0)->cnt; - return $count; - } - - /** - * 해당 게시물의 댓글수를 최신화 한다 - * @param $brd_key - * @param $post_idx - */ - function update_post_comment_count($brd_key, $post_idx) - { - $count = $this->get_comment_count($brd_key, $post_idx); - - $this->db->where('brd_key', $brd_key); - $this->db->where('post_idx', $post_idx); - $this->db->set('post_count_comment', (int)$count); - return $this->db->update('board_post'); - } -} \ No newline at end of file diff --git a/wheeparam/views/skins/board/comment/basic/c_list.php b/wheeparam/views/skins/board/comment/basic/c_list.php index 7168de3..0278d6a 100644 --- a/wheeparam/views/skins/board/comment/basic/c_list.php +++ b/wheeparam/views/skins/board/comment/basic/c_list.php @@ -32,11 +32,6 @@ ?>
- - - - - 삭제 diff --git a/wheeparam/views/skins/board/comment/basic/c_modify.php b/wheeparam/views/skins/board/comment/basic/c_modify.php index 38693f7..32b3d0d 100644 --- a/wheeparam/views/skins/board/comment/basic/c_modify.php +++ b/wheeparam/views/skins/board/comment/basic/c_modify.php @@ -10,12 +10,12 @@
- +
member->is_login()) :?>
- +
diff --git a/wheeparam/views/skins/board/comment/basic/c_write.php b/wheeparam/views/skins/board/comment/basic/c_write.php index 9637660..3eaa229 100644 --- a/wheeparam/views/skins/board/comment/basic/c_write.php +++ b/wheeparam/views/skins/board/comment/basic/c_write.php @@ -4,7 +4,7 @@
- +
member->is_login()):?> diff --git a/wheeparam/views/themes/admin/board/read.php b/wheeparam/views/themes/admin/board/read.php index 8d8f266..28b7d6c 100644 --- a/wheeparam/views/themes/admin/board/read.php +++ b/wheeparam/views/themes/admin/board/read.php @@ -96,13 +96,87 @@ + + +
+ "form-board-comment","data-form"=>"board-comment"))?> + +
+
댓글 입력
+
+
+
내용
+
+ +
+ +
+
+
+ + +
    + +
  • +

    +
    + 관리자에 의해서 블라인드 된 댓글입니다.

    '; + else : + echo '

    삭제된 댓글입니다.

    '; + endif; + ?> +
    +
    + + + 삭제 +
    + +
  • + + + +

    작성된 댓글이 없습니다.

    + +
+
+ +