belongsTo(BoardGroup::class)->withDefault(); } public function boardCategory() { return $this->hasMany(BoardCategory::class); } public function boardMeta() { return $this->hasMany(BoardMeta::class); } public function boardAdmin() { return $this->hasMany(BoardAdmin::class); } public function post() { return $this->hasMany(Post::class); } /** * 게시판 조회 */ public function data(SearchData $params): object { $query = $this->query(); $query->select( 'tb_board.*', DB::raw('(SELECT COUNT(*) FROM tb_post WHERE board_id = tb_board.id) AS postRows'), DB::raw('(SELECT COUNT(*) FROM tb_comment WHERE board_id = tb_board.id) AS commentRows') ); if ($params->keyword) { switch ($params->field) { case 'tb_board.code': case 'tb_board.name': case 'users.name': case 'users.email': $query->where($params->field, 'LIKE', "%{$params->keyword}%"); break; case 'tb_board.board_id': case 'users.id': case 'users.sid': $query->where($params->field, '=', $params->keyword); break; } } $query->orderBy('tb_board.sort'); $list = $query->paginate($params->perPage, ['*'], 'page', $params->page); $total = $this->count(); $rows = $list->count(); return (object)[ 'total' => $total, 'rows' => $rows, 'list' => $list ]; } /** * 게시판 그룹에 조회 */ public function findByGroup(int $boardGroupID) { return static::where('board_group_id', $boardGroupID)->get(); } /** * 게시판 주소로 게시판 정보 조회 */ public function findByCode(string $code): Board { return static::where('code', $code)->firstOrNew(); } /** * 게시판 설정 등록 */ public function register(Request $request, ResponseData $response): ResponseData { DB::beginTransaction(); try { $posts = $request->all(); $boardID = $this->insertGetId([ 'board_group_id' => $posts['board_group_id'], 'code' => $posts['code'], 'name' => $posts['name'], 'sort' => $posts['sort'], 'is_search' => $posts['is_search'], 'is_display' => $posts['is_display'], 'created_at' => now() ]); $boardMetaModel = new boardMeta(); $boardMetaModel->save($boardID, [ 'pc_header_content' => $posts['pc_header_content'], 'pc_footer_content' => $posts['pc_footer_content'], 'mobile_header_content' => $posts['mobile_header_content'], 'mobile_footer_content' => $posts['mobile_footer_content'], 'use_inform_modal' => $posts['use_inform_modal'], 'inform_content' => $posts['inform_content'] ]); $tmpDefaultAdminAttributes = [ // 목록 'board_layout_type' => [0, '게시판 종류'], 'list_sort_type' => [1, '기본 정렬 순'], 'list_per_page' => [15, 'PC - 목록 수'], 'list_mobile_per_page' => [15, '모바일 - 목록 수'], 'list_page_count' => [10, 'PC - 페이지 수'], 'list_page_mobile_count' => [10, '모바일 - 페이지 수'], 'always_show_write_button' => [1, '글쓰기 버튼 보이기'], 'show_list_from_view' => [1, '하단 목록 보이기'], 'new_icon_hour' => [0, 'NEW 아이콘 - 시간'], 'hot_icon_hit' => [0, 'HOT 아이콘 - 시간'], 'hot_icon_day' => [0, 'HOT 아이콘 - 일'], 'subject_length' => [0, 'PC - 제목'], 'subject_mobile_length' => [0, 'PC - 모바일'], 'except_notice' => [0, '공지사항 제외'], 'except_speaker' => [0, '전체공지 제외'], // 열람 'use_bookmark' => [1, '즐겨찾기 기능'], 'use_post_like' => [1, '추천 기능'], 'use_post_dislike' => [1, '비추천 기능'], 'use_print' => [1, '본문 인쇄 기능'], 'use_sns' => [1, 'SNS 보내기 기능'], 'use_prev_next_post' => [1, '이전글, 다음글 버튼'], 'use_blame' => [1, '신고 기능'], 'blame_blind_count' => [1, '신고 시 숨김'], 'show_post_ip' => [1, 'IP 보이기'], 'content_target_blank' => [1, 'Link 새창'], 'use_auto_url' => [1, '본문 URL Link 생성'], 'use_copy_post_url' => [1, '주소 복사 버튼'], 'use_url_qrcode' => [1, '글 주소 QR 코드'], 'use_attached_url_qrcode' => [1, '첨부된 Link QR 코드'], 'need_like_for_download' => [1, '다운로드 제한 (추천 필수)'], 'need_comment_for_download' => [1, '다운로드 제한 (댓글 필수)'], 'show_user_thumb_in_post' => [1, '회원 프로필 이미지'], 'show_user_icon_in_post' => [1, '회원 아이콘 이미지'], 'use_post_user_regdate' => [1, '회원 가입일'], // 작성 'write_header_content' => [null, '작성폼 상단 내용'], 'mobile_write_header_content' => [null, '모바일 작성폼 상단 내용'], 'post_default_subject' => [null, '글쓰기 시 기본 제목'], 'post_default_content' => [null, '글쓰기 시 기본 내용'], 'use_post_dhtml' => [1, '본문 에디터 사용'], 'save_external_image' => [0, '외부 이미지 가져오기'], 'post_subject_min_length' => [0, '최소 글수 제한 (제목)'], 'post_subject_max_length' => [0, '최대 글수 제한 (제목)'], 'post_content_min_length' => [0, '최소 글수 제한 (내용)'], 'post_content_max_length' => [0, '최대 글수 제한 (내용)'], 'use_category_required' => [0, '분류 필수 선택'], 'use_post_secret' => [0, '비밀글 사용'], 'use_post_secret_selected' => [0, '비밀글 기본 선택'], 'use_post_tag' => [0, '태그 사용'], 'link_num' => [0, 'URL Link 개수'], 'use_upload_file' => [0, '첨부파일 사용'], 'upload_file_num' => [0, '첨부파일 개수 제한'], 'upload_file_max_size' => [0, '첨부파일 용량 제한'], 'upload_only_img_file' => [0, '첨부파일 이미지 허용'], 'upload_file_extension' => [null, '첨부파일 허용 확장자'], 'use_only_one_post' => [0, '하루에 한 글만 작성'], 'use_post_captcha' => [0, 'Captcha 사용'], // 댓글 'use_comment' => [1, '댓글 사용 여부'], 'comment_per_page' => [20, '댓글 목록 수'], 'comment_page_count' => [10, '댓글 페이지 수'], 'use_comment_like' => [1, '댓글 추천 기능'], 'use_comment_dislike' => [1, '댓글 비추천 기능'], 'show_user_thumb_in_comment' => [1, '회원 프로필 이미지'], 'show_user_icon_in_comment' => [1, '회원 아이콘 이미지'], 'update_order_on_comment' => [1, '댓글 작성시 글 수정 시각 갱신'], 'comment_default_content' => [null, '댓글 기본 내용'], 'comment_min_length' => [0, '최소 글수 제한'], 'comment_max_length' => [0, '최대 글수 제한'], 'use_comment_secret' => [0, '비밀글 사용'], 'use_comment_secret_selected' => [0, '비밀글 기본 선택'], 'show_comment_ip' => [1, 'IP 보이기'], 'use_comment_blame' => [1, '댓글 신고 기능'], 'comment_blame_blind_count' => [1, '댓글 신고 시 숨김'], 'protect_delete_comment' => [0, '댓글 보호 기능 (삭제 시)'], 'protect_update_comment' => [0, '댓글 보호 기능 (수정 시)'], // 일반 'block_delete' => [0, '관리자만 삭제'], 'protect_post_day' => [0, '게시글 수정/삭제 금지 기간'], 'protect_comment_day' => [0, '댓글 수정/삭제 금지 기간'], 'protect_delete_post' => [0, '게시글 보호 기능 (삭제 시)'], 'protect_update_post' => [0, '게시글 보호 기능 (수정 시)'], 'use_category' => [0, '분류 기능'], 'use_personal' => [0, '1:1 게시판'], 'use_anonymous' => [0, '익명 게시판'], 'anonymous_except_admin' => [0, '관리자 익명 제외'], 'anonymous_name' => ['$NUM', '익명 이름'], 'use_download_log' => [0, '다운로드 기록'], 'use_post_history' => [1, '게시물 변경 기록'], 'use_link_click_log' => [1, 'Link 클릭 기록'], 'use_comment_history' => [1, '댓글 변경 기록'], // 알람 'send_email_post_super_admin' => [0, '이메일 발송(원글 작성) - 최고 관리자'], 'send_email_post_writer' => [0, '이메일 발송(원글 작성) - 원글 작성자'], 'send_email_comment_super_admin' => [0, '이메일 발송(댓글 작성) - 최고 관리자'], 'send_email_comment_post_writer' => [0, '이메일 발송(댓글 작성) - 원글 작성자'], 'send_email_comment_comment_writer' => [0, '이메일 발송(댓글) - 댓글 작성자'], 'send_email_blame_super_admin' => [0, '이메일 발송(원글 신고) - 최고 관리자'], 'send_email_blame_post_writer' => [0, '이메일 발송(원글 신고) - 원글 작성자'], 'send_email_comment_blame_super_admin' => [0, '이메일 발송(댓글 신고) - 최고 관리자'], 'send_email_comment_blame_post_writer' => [0, '이메일 발송(댓글 신고) - 원글 작성자'], 'send_email_comment_blame_comment_writer' => [0, '이메일 발송(댓글 신고) - 댓글 작성자'], 'send_telegram_post_super_admin' => [0, '텔레그램 발송 (원글 작성 시)'], 'send_telegram_comment_super_admin' => [0, '텔레그램 발송 (댓글 작성 시)'], 'send_telegram_blame_super_admin' => [0, '텔레그램 발송 (원글 신고 발생 시)'], 'send_telegram_comment_blame_super_admin' => [0, '텔레그램 발송 (댓글 신고 발생 시)'], // 권한 'access_post_list' => [null, '목록'], 'access_post_view' => [null, '글 열람'], 'access_post_write' => [null, '글 작성'], 'access_comment_list' => [null, '댓글 목록'], 'access_comment_write' => [null, '댓글 작성'], 'access_file_upload' => [null, '파일 업로드'], 'access_file_download' => [null, '파일 다운로드'] ]; /* * 기본 정보 저장 */ if($tmpDefaultAdminAttributes) { foreach ($tmpDefaultAdminAttributes as $attribute => $row) { $boardMetaModel->save($boardID, [ $attribute => $row[0] ]); } } /* * 그룹, 전체 적용 */ $groupData = []; // 그룹적용 $allData = []; // 전체적용 $defaultData = [ // 그룹, 전체 적용 값 'pc_header_content', 'pc_footer_content', 'mobile_header_content', 'mobile_footer_content', 'use_inform_modal', 'inform_content' ]; foreach ($defaultData as $field) { if (isset($posts['grp'][$field])) { $groupData[$field] = $posts[$field]; } if (isset($posts['all'][$field])) { $allData[$field] = $posts[$field]; } } if ($groupData) { $brdGroupData = $this->findByGroup($posts['board_group_id']); foreach ($brdGroupData as $bKey => $bVal) { if ($bVal->id === $boardID) { continue; } $boardMetaModel->save($bVal->id, $groupData); } } if ($allData) { $brdAllData = $this->all(); foreach ($brdAllData as $bKey => $bVal) { if ($bVal->id === $boardID) { continue; } $boardMetaModel->save($bVal->id, $allData); } } DB::commit(); } catch (Exception $e) { $response = $response::fromException($e); DB::rollBack(); } return $response; } /** * 게시판 설정 수정 */ public function updater(int $boardID, Request $request, ResponseData $response): ResponseData { DB::beginTransaction(); try { $posts = $request->all(); $this->find($boardID)->update([ 'board_group_id' => $posts['board_group_id'], 'code' => $posts['code'], 'name' => $posts['name'], 'sort' => $posts['sort'], 'is_search' => $posts['is_search'], 'is_display' => $posts['is_display'], 'updated_at' => now() ]); $boardMetaModel = new boardMeta(); $boardMetaModel->save($boardID, [ 'pc_header_content' => $posts['pc_header_content'], 'pc_footer_content' => $posts['pc_footer_content'], 'mobile_header_content' => $posts['mobile_header_content'], 'mobile_footer_content' => $posts['mobile_footer_content'], 'use_inform_modal' => $posts['use_inform_modal'], 'inform_content' => $posts['inform_content'] ]); /* * 그룹, 전체 적용 */ $groupData = []; // 그룹적용 $allData = []; // 전체적용 $defaultData = [ // 그룹, 전체 적용 값 'pc_header_content', 'pc_footer_content', 'mobile_header_content', 'mobile_footer_content', 'use_inform_modal', 'inform_content' ]; foreach ($defaultData as $field) { if (isset($posts['grp'][$field])) { $groupData[$field] = $posts[$field]; } if (isset($posts['all'][$field])) { $allData[$field] = $posts[$field]; } } if ($groupData) { $brdGroupData = $this->findByGroup($posts['board_group_id']); foreach ($brdGroupData as $bKey => $bVal) { if ($bVal->id === $boardID) { continue; } $boardMetaModel->save($bVal->id, $groupData); } } if ($allData) { $brdAllData = $this->all(); foreach ($brdAllData as $bKey => $bVal) { if ($bVal->id === $boardID) { continue; } $boardMetaModel->save($bVal->id, $allData); } } DB::commit(); } catch (Exception $e) { $response = $response::fromException($e); DB::rollBack(); } return $response; } /** * 게시판 공지글 조회 * 공지글은 최신순으로 정렬 */ public function getNotices(SearchData $params): object { $sql = " SELECT COUNT(*) AS total FROM tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id WHERE BRD.code = ? AND BRD.is_display = 1 AND PST.is_notice = 1 AND PST.is_delete = 0 OR PST.id IN (SELECT id FROM tb_post WHERE PST.is_speaker = 1 AND PST.is_delete = 0); "; $total = DB::selectOne($sql, [$params->code])->total; $sql = " SELECT BRD.code, BRD.name AS boardName, BCA.name AS categoryName, PST.id, PST.board_id, PST.board_category_id, PST.user_id, PST.thumbnail, PST.subject, PST.content, PST.sid, PST.username, PST.email, PST.comment_rows, PST.is_reply, PST.is_personal, PST.is_secret, PST.is_notice, PST.is_speaker, PST.is_html, PST.use_comment, PST.receive_email, PST.hit, PST.like, PST.dislike, PST.blame, PST.ip_address, PST.user_agent, PST.device_type, PST.file_rows, PST.image_rows, PST.link_rows, PST.tag_rows, PST.is_delete, PST.created_at FROM tb_post PST INNER JOIN tb_board BRD ON BRD.id = PST.board_id LEFT JOIN tb_board_category BCA ON BCA.id = PST.board_category_id LEFT JOIN users USR ON USR.id = PST.user_id WHERE BRD.code = ? AND BRD.is_display = 1 AND PST.is_notice = 1 AND PST.is_delete = 0 OR PST.id IN (SELECT id FROM tb_post WHERE PST.is_speaker = 1 AND PST.is_delete = 0) ORDER BY PST.id DESC, PST.created_at DESC; "; $list = $this->setRawAttributes(DB::select($sql, [$params->code]))->getAttributes(); return (object)[ 'total' => $total, 'list' => $list ]; } /** * 게시글 목록 조회 */ public function getPosts(SearchData $params): object { // 검색 쿼리 생성 $where = $this->buildWhereQuery($params); // 정렬 기준 생성 $orderBy = $this->sortQuery($params); $sql = sprintf(" SELECT COUNT(*) AS total FROM tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id WHERE BRD.code = ? AND BRD.is_display = 1 AND PST.is_notice = 0 AND PST.is_speaker = 0 AND PST.is_delete = 0 %s; ", $where); $total = DB::selectOne($sql, [$params->code])->total; $sql = sprintf(" SELECT BRD.code, BRD.name AS boardName, BCA.name AS categoryName, PST.id, PST.board_id, PST.board_category_id, PST.user_id, PST.thumbnail, PST.subject, PST.content, PST.sid, PST.username, PST.email, PST.comment_rows, PST.is_reply, PST.is_personal, PST.is_secret, PST.is_notice, PST.is_speaker, PST.is_html, PST.use_comment, PST.receive_email, PST.hit, PST.like, PST.dislike, PST.blame, PST.ip_address, PST.user_agent, PST.device_type, PST.file_rows, PST.image_rows, PST.link_rows, PST.tag_rows, PST.is_delete, PST.created_at FROM tb_post PST INNER JOIN tb_board BRD ON BRD.id = PST.board_id LEFT JOIN tb_board_category BCA ON BCA.id = PST.board_category_id LEFT JOIN users USR ON USR.id = PST.user_id WHERE BRD.code = ? AND BRD.is_display = 1 AND PST.is_notice = 0 AND PST.is_speaker = 0 AND PST.is_delete = 0 %s ORDER BY %s LIMIT ?, ?; ", $where, $orderBy); $list = $this->getPaginator( DB::select($sql, [$params->code, $params->offset, $params->perPage]), $total, $params->perPage, $params->page, $params->path ); return (object)[ 'total' => $total, 'list' => $list ]; } /** * 게시글 목록 조회 */ public function getUserPosts(int $userID, SearchData $params): object { $sql = " SELECT COUNT(*) AS total FROM tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id WHERE BRD.is_display = 1 AND PST.is_notice = 0 AND PST.is_speaker = 0 AND PST.is_delete = 0 AND PST.user_id = ? AND PST.is_personal = 0; "; $total = DB::selectOne($sql, [$userID])->total; $sql = " SELECT BRD.code, BRD.name AS boardName, BCA.name AS categoryName, PST.id, PST.board_id, PST.board_category_id, PST.user_id, PST.thumbnail, PST.subject, PST.content, PST.sid, PST.username, PST.email, PST.comment_rows, PST.is_reply, PST.is_personal, PST.is_secret, PST.is_notice, PST.is_speaker, PST.is_html, PST.use_comment, PST.receive_email, PST.hit, PST.like, PST.dislike, PST.blame, PST.ip_address, PST.user_agent, PST.device_type, PST.file_rows, PST.image_rows, PST.link_rows, PST.tag_rows, PST.is_delete, PST.created_at FROM tb_post PST INNER JOIN tb_board BRD ON BRD.id = PST.board_id LEFT JOIN tb_board_category BCA ON BCA.id = PST.board_category_id LEFT JOIN users USR ON USR.id = PST.user_id WHERE BRD.is_display = 1 AND PST.is_notice = 0 AND PST.is_speaker = 0 AND PST.is_delete = 0 AND PST.user_id = ? AND PST.is_personal = 0 ORDER BY PST.created_at DESC, PST.id DESC LIMIT ?, ?; "; $list = $this->getPaginator( DB::select($sql, [$userID, $params->offset, $params->perPage]), $total, $params->perPage, $params->page, $params->path ); return (object)[ 'total' => $total, 'list' => $list ]; } /** * 게시판 최근 게시글 조회 */ public function getLatest(?string $code, int $page, int $perPage): object { $sql = " SELECT COUNT(*) AS total FROM (SELECT @code := ?) V, tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id WHERE CASE WHEN @code IS NOT NULL THEN BRD.code = @code ELSE (PST.is_notice = 0 AND PST.is_speaker = 0) END AND BRD.is_display = 1 AND PST.is_delete = 0; "; $total = DB::selectOne($sql, [$code])->total; $sql = " SELECT BRD.code, BRD.name AS boardName, BCA.name AS categoryName, PST.id, PST.board_id, PST.board_category_id, PST.user_id, PST.thumbnail, PST.subject, PST.content, PST.sid, PST.username, PST.email, PST.comment_rows, PST.is_reply, PST.is_personal, PST.is_secret, PST.is_notice, PST.is_speaker, PST.is_html, PST.use_comment, PST.receive_email, PST.hit, PST.like, PST.dislike, PST.blame, PST.ip_address, PST.user_agent, PST.device_type, PST.file_rows, PST.image_rows, PST.link_rows, PST.tag_rows, PST.is_delete, PST.created_at FROM (SELECT @code := ?) V, tb_post PST INNER JOIN tb_board BRD ON BRD.id = PST.board_id LEFT JOIN tb_board_category BCA ON BCA.id = PST.board_category_id LEFT JOIN users USR ON USR.id = PST.user_id WHERE CASE WHEN @code IS NOT NULL THEN BRD.code = @code ELSE (PST.is_notice = 0 AND PST.is_speaker = 0) END AND BRD.is_display = 1 AND PST.is_delete = 0 ORDER BY PST.created_at DESC, PST.id DESC LIMIT ?, ?; "; $list = $this->getPaginator( DB::select($sql, [$code, $this->getPageOffset($page), $perPage]), $total, $perPage, $page, ($code ? route('board.list', $code) : null) ); return (object)[ 'total' => $total, 'list' => $list ]; } /** * 게시판 최근 게시글 조회 */ public function getSearch(SearchData $params): object { // 검색 쿼리 생성 $where = $this->buildWhereQuery($params); // 정렬 기준 생성 $orderBy = $this->sortQuery($params); $sql = sprintf(" SELECT COUNT(*) AS total FROM tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id WHERE TRUE AND BRD.is_display = 1 AND PST.is_notice = 0 AND PST.is_speaker = 0 AND PST.is_delete = 0 %s; ", $where); $total = DB::selectOne($sql)->total; $sql = sprintf(" SELECT BRD.code, BRD.name AS boardName, BCA.name AS categoryName, PST.id, PST.board_id, PST.board_category_id, PST.user_id, PST.thumbnail, PST.subject, PST.content, PST.sid, PST.username, PST.email, PST.comment_rows, PST.is_reply, PST.is_personal, PST.is_secret, PST.is_notice, PST.is_speaker, PST.is_html, PST.use_comment, PST.receive_email, PST.hit, PST.like, PST.dislike, PST.blame, PST.ip_address, PST.user_agent, PST.device_type, PST.file_rows, PST.image_rows, PST.link_rows, PST.tag_rows, PST.is_delete, PST.created_at FROM tb_post PST INNER JOIN tb_board BRD ON BRD.id = PST.board_id LEFT JOIN tb_board_category BCA ON BCA.id = PST.board_category_id LEFT JOIN users USR ON USR.id = PST.user_id WHERE TRUE AND BRD.is_display = 1 AND PST.is_notice = 0 AND PST.is_speaker = 0 AND PST.is_delete = 0 %s ORDER BY %s LIMIT ?, ?; ", $where, $orderBy); $list = $this->getPaginator( DB::select($sql, [$params->offset, $params->perPage]), $total, $params->perPage, $params->page ); return (object)[ 'total' => $total, 'list' => $list ]; } /** * 게시판 검색 쿼리 생성 */ private function buildWhereQuery(?SearchData $params): string { $sql = ""; if(!$params) { return $sql; } // 분류 지정 if($params->category) { $sql .= sprintf(" AND PST.board_category_id = %d", $params->category); } // 검색 if($params->keyword) { $sql .= " AND BRD.is_search = 1 "; switch ($params->field) { case 1 : // 제목 + 내용 $sql .= sprintf("AND (PST.subject LIKE '%%%s%%' OR PST.content LIKE '%%%s%%')", $params->keyword, $params->keyword); break; case 2 : // 제목 $sql .= sprintf("AND PST.subject LIKE '%%%s%%'", $params->keyword); break; case 3 : // 글 작성자 $sql .= sprintf("AND (PST.username LIKE '%%%s%%' OR PST.nickname LIKE '%%%s%%')", $params->keyword); break; case 4 : // 댓글 내용 $sql .= sprintf("AND PST.id IN (SELECT post_id FROM tb_comment WHERE content LIKE '%%%s%%')", $params->keyword); break; case 5 : // 댓글 작성자 $sql .= sprintf("AND PST.id IN (SELECT post_id FROM tb_comment WHERE (username LIKE '%%%s%%' OR nickname LIKE '%%%s%%'))", $params->keyword, $params->keyword); break; } } if($params->code) { $boardMeta = $params->boardMeta; // 1:1 문의 회원 번호 조회 if ($boardMeta->item('use_personal', 0)) { $sql .= sprintf(" AND PST.user_id = %d", UID); } } return $sql; } /** * 게시판 정렬 방법 */ private function sortQuery(?SearchData $params): string { $sql = 'PST.created_at DESC, PST.id DESC'; if(!$params) { return $sql; } switch($params->sort) { default:case 1: // 날짜순 return $sql; case 2: // 조회수 return 'PST.hit DESC, PST.id DESC'; case 3: // 댓글순 return 'PST.comment_rows DESC, PST.id DESC'; case 4: // 추천순 return 'PST.like DESC, PST.id DESC'; } } /** * 게시글 수 갱신 */ public function updatePostRows(int $boardID): int { $sql = ' UPDATE tb_board A SET A.post_rows = ( (SELECT COUNT(*) AS total FROM tb_post WHERE board_id = A.id AND is_delete = 0) ) WHERE A.id = ?; '; return DB::update($sql, [$boardID]); } /** * 댓글 개수 갱신 */ public function updateCommentRows(int $boardID): int { $sql = ' UPDATE tb_board A SET A.comment_rows = ( SELECT COUNT(*) AS total FROM tb_comment CMT WHERE CMT.board_id = A.id AND CASE WHEN ( CMT.is_delete = 1 AND ((SELECT (COUNT(*) - 1) FROM tb_comment WHERE lft BETWEEN CMT.lft AND CMT.rgt) <= 0) AND ((SELECT (COUNT(*) - 1) FROM tb_comment WHERE CMT.rgt BETWEEN lft AND rgt) <= 0) ) THEN FALSE ELSE TRUE END ) WHERE A.id = ?; '; return DB::update($sql, [$boardID]); } /** * 삭제 */ public function remove(int $boardID): mixed { return DB::transaction(function() use($boardID) { $board = $this->findOrNew($boardID); if($board->exists) { self::deleting(function($board) { // 게시판 분류 삭제 $board->boardCategory()->each(function($category) { $category->delete(); }); // 메타 삭제 $board->boardMeta()->each(function($meta) { $meta->delete(); }); // 관리자 삭제 $board->boardAdmin()->each(function($admin) { $admin->delete(); }); // 게시글 삭제 $board->post()->each(function($post) { $post->delete(); }); }); $board->delete(); } return true; }); } }