belongsTo(Board::class)->withDefault(); } public function boardCategory() { return $this->belongsTo(BoardCategory::class)->withDefault(); } public function user() { return $this->belongsTo(User::class)->withDefault(); } public function postBlame() { return $this->hasMany(PostBlame::class); } public function postBookmark() { return $this->hasMany(PostBookmark::class); } public function postDeleted() { return $this->hasMany(PostDeleted::class); } public function postFile() { return $this->hasMany(PostFile::class); } public function postFileDownLog() { return $this->hasMany(PostFileDownLog::class); } public function postHistory() { return $this->hasMany(PostHistory::class); } public function postLike() { return $this->hasMany(PostLike::class); } public function postLink() { return $this->hasMany(PostLink::class); } public function postLinkClickLog() { return $this->hasMany(PostLinkClickLog::class); } public function postMeta() { return $this->hasMany(PostMeta::class); } public function postTag() { return $this->hasMany(PostTag::class); } public function comments() { return $this->hasMany(Comment::Class); } /** * 게시물 조회 */ public function data(SearchData $params) { $query = $this->query(); $query->select( 'tb_board.name AS boardName', 'tb_board.code', 'tb_post.*', 'users.sid', 'users.name' ); if($params->keyword) { switch ($params->field) { case 'tb_post.id' : case 'users.id' : case 'users.sid' : $query->where($params->field, '=', $params->keyword); break; case 'tb_post.subject' : case 'tb_post.content' : case 'users.name' : case 'users.email' : $query->where($params->field, 'LIKE', "%{$params->keyword}%"); break; } } $query->where('tb_post.is_delete', '=', 0); if($params->startDate || $params->endDate) { if($params->startDate) { $query->where('tb_post.created_at', '>=', $params->startDate . ' 00:00:00'); } if($params->endDate) { $query->where('tb_post.created_at', '<=', $params->endDate . ' 23:59:59'); } } if($params->boardID) { $query->where('tb_post.board_id', '=', $params->boardID); } $query->join('tb_board', 'tb_board.id', '=', 'tb_post.board_id'); $query->leftJoin('users', 'users.id', '=', 'tb_post.user_id'); $query->orderByDesc('tb_post.id'); $list = $query->paginate($params->perPage, ['*'], 'page', $params->page); $total = $query->count(); $rows = $list->count(); return (object)[ 'total' => $total, 'rows' => $rows, 'list' => $list ]; } /** * 게시글 등록 */ public function register(array $params): Post { return $this->create($params); } /** * 게시글 수정 */ public function updater(int $postID, array $params): Post { return $this->updateOrCreate([$this->primaryKey => $postID], $params); } /** * 게시글 임시 삭제 */ public function remove(Post $post, ?User $user): mixed { return DB::transaction(function() use($post, $user) { // 게시글 삭제 여부 승인 $this->updater($post->id, [ 'is_delete' => 1, 'deleted_at' => now() ]); // 게시글 삭제 정보 추가 (new PostDeleted)->register([ 'board_id' => $post->board_id, 'post_id' => $post->id, 'user_id' => $user?->id, 'ip_address' => IP_ADDRESS, 'user_agent' => USER_AGENT, 'created_at' => now() ]); return true; }); } /** * 게시글 조회 */ public function get(int $postID): Post { return $this->from('tb_post AS PST')->select('PST.*') ->selectRaw( '(SELECT id FROM tb_post WHERE id < PST.id AND board_id = PST.board_id AND is_delete = 0 ORDER BY id DESC LIMIT 1) AS beforePostID' )->selectRaw( '(SELECT id FROM tb_post WHERE id > PST.id AND board_id = PST.board_id AND is_delete = 0 ORDER BY id ASC LIMIT 1) AS nextPostID' )->with(['board', 'user'])->where([ ['PST.id', $postID], ['PST.is_delete', 0] ])->firstOrNew(); } /** * 댓글 갯수 갱신 */ public function updateCommentRows(int $postID): int { $sql = " UPDATE tb_post A SET A.comment_rows = ( SELECT COUNT(*) AS total FROM tb_comment CMT WHERE CMT.post_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, [$postID]); } /** * 파일 첨부 갯수 갱신 */ public function updateFileRows(int $postID): int { $sql = " UPDATE tb_post A SET A.file_rows = (SELECT COUNT(*) AS total FROM tb_post_file WHERE post_id = A.id) WHERE A.id = ?; "; return DB::update($sql, [$postID]); } /** * 이미지 파일 갯수 갱신 */ public function updateImageRows(int $postID): int { $sql = " UPDATE tb_post A SET A.image_rows = ((SELECT COUNT(*) AS total FROM tb_post_file WHERE post_id = A.id AND is_image = 1) + A.image_rows) WHERE A.id = ?; "; return DB::update($sql, [$postID]); } /** * 게시글 태그 갯수 갱신 */ public function updateTagRows(int $postID): int { $sql = " UPDATE tb_post A SET A.tag_rows = (SELECT COUNT(*) AS total FROM tb_post_tag WHERE post_id = A.id) WHERE A.id = ?; "; return DB::update($sql, [$postID]); } /** * 게시글 링크 갯수 갱신 */ public function updateLinkRows(int $postID): int { $sql = " UPDATE tb_post A SET A.link_rows = (SELECT COUNT(*) AS total FROM tb_post_link WHERE post_id = A.id) WHERE A.id = ?; "; return DB::update($sql, [$postID]); } /** * 게시글 조회 수 증가 */ public function increaseHit(int $postID): int { return $this->where('id', $postID)->increment('hit'); } /** * 게시글 신고 수 증가 */ public function increaseBlame(int $postID): int { return $this->where('id', $postID)->increment('blame'); } /** * 게시글 신고 수 증감 */ public function decreaseBlame(int $postID): int { return $this->where('id', $postID)->where('blame', '>', '0')->decrement('blame', 1); } /** * 게시글 좋아요 수 증가 */ public function increaseLike(int $postID): int { return $this->where('id', $postID)->increment('like'); } /** * 게시글 좋아요 수 증감 */ public function decreaseLike(int $postID): int { return $this->where('id', $postID)->where('like', '>', '0')->decrement('like', 1); } /** * 게시글 싫어요 수 증가 */ public function increaseDisLike(int $postID): int { return $this->where('id', $postID)->increment('dislike'); } /** * 게시글 싫어요 수 증감 */ public function decreaseDisLike(int $postID): int { return $this->where('id', $postID)->where('dislike', '>', '0')->decrement('dislike'); } /** * 게시글 존재 여부 */ public function isExists(int $postID) { $sql = " SELECT IF(COUNT(*) > 0, 1, 0) AS isExists FROM tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id WHERE PST.id = ? AND PST.is_delete = 0; "; return DB::selectOne($sql, [$postID])->isExists; } /** * 게시글의 현재 페이지 번호 */ public function findPageNumber(int $postID, int $perPage = DEFAULT_LIST_PER_PAGE): int { $sql = " SELECT ROUND(COUNT(*) / :perPage) + 1 AS page FROM tb_post, (SELECT @postID := id, @boardID := board_id FROM tb_post WHERE id = :postID ) AS N WHERE id > @postID AND board_id = @boardID AND is_delete = 0; "; return DB::selectOne($sql, [ 'postID' => $postID, 'perPage' => $perPage ])->page; } /** * 추가 게시글 번호 */ public function lastedKey(): int { return intval(DB::selectOne( "SELECT AUTO_INCREMENT AS id FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'tb_post';" )->id); } /** * 게시글 조회수 증가 */ public function addHit(Post $post): bool { return views($post)->cooldown(now()->addYear())->record(); } }