boardModel = new Board(); $this->boardMetaModel = new BoardMeta(); $this->boardCategoryModel = new BoardCategory(); $this->boardAdminModel = new BoardAdmin(); } /** * 게시판 조회 */ public function find(string $code): Board { return $this->boardModel->findByCode($code); } /** * 게시판 설정 값 조회 */ public function meta(int $boardID): ?BoardMeta { return $this->boardMetaModel->getAllMeta($boardID); } /** * 게시판 분류 조회 */ public function categories(int $boardID): object|null { $boardMeta = $this->meta($boardID); $useCategory = $boardMeta->item('use_category', 0); $usePersonal = $boardMeta->item('use_personal', 0); if ($useCategory) { if (!$usePersonal || IS_ADMIN) { return $this->boardCategoryModel->categories($boardID); } } return null; } /** * 공지사항 조회 */ public function notices(BoardRequest $request): object|null { $notices = null; if($request->page == 1 && !$request->keyword && !$request->category) { $notices = $this->boardModel->getNotices( SearchData::fromRequest($request) ); if ($notices->total > 0) { foreach ($notices->list as $i => $row) { $notices->list[$i] = $this->_filter($row); } $notices->list = array_filter($notices->list); } } return $notices; } /** * 일반 게시글 혹은 검색 결과 */ public function posts(BoardRequest $request): object { $posts = $this->boardModel->getPosts( SearchData::fromRequest($request) ); if ($posts->total > 0) { $num = listNum($posts->total, $request->page, $request->perPage); foreach ($posts->list as $i => $row) { $row->num = $num--; $posts->list[$i] = $this->_filter($row); } $posts->list->filter(); } return $posts; } /** * 회원 작성 게시글 조회 */ public function userPosts(int $userID, SearchData $params): object { $posts = $this->boardModel->getUserPosts($userID, $params); if ($posts->total > 0) { $num = listNum($posts->total, $params->page, $params->perPage); foreach ($posts->list as $i => $row) { $row->num = $num--; $posts->list[$i] = $this->_filter($row); } $posts->list->filter(); } return $posts; } /** * 최신 게시글 검색 조회 */ public function search(SearchData $params): object { $search = $this->boardModel->getSearch($params); if ($search->total > 0) { $num = listNum($search->total, $params->page, $params->perPage); foreach ($search->list as $i => $row) { $row->num = $num--; $search->list[$i] = $this->_filter($row); } $search->list->filter(); } return $search; } /** * 게시판 최근 게시글 */ public function latest(?string $code, int $page = 1, int $perPage = DEFAULT_LIST_PER_PAGE) { $cacheName = sprintf('latest-board-%s-%d-%d', $code, $page, $perPage); if (!$latest = Cache::get($cacheName)) { $latest = $this->boardModel->getLatest($code, $page, $perPage); if($latest->total) { $num = listNum($latest->total, $page, $perPage); foreach ($latest->list as $i => $row) { $row->num = $num--; $latest->list[$i] = $this->_filter($row); } $latest->list->filter(); } Cache::tags('latest-board')->put($cacheName, $latest, CACHE_EXPIRE_TIME); } return $latest; } /** * 게시판 설정 값 조회 */ private function _config(string|null $code) { $boardMeta = $this->meta($code); return (object)[ 'use_category' => intval($boardMeta->item('use_category', 0)), 'subject_length' => (function($boardMeta) { // 게시판 설정 값 조회 if(DEVICE_TYPE_1) { return intval($boardMeta->item('subject_length', 0)); }else{ return intval($boardMeta->item('subject_mobile_length', 0)); } })($boardMeta), 'new_icon_hour' => intval($boardMeta->item('new_icon_hour', 24)), 'hot_icon_day' => intval($boardMeta->item('hot_icon_day', 7)), 'hot_icon_hit' => intval($boardMeta->item('hot_icon_hit', 100)), 'except_notice' => intval($boardMeta->item('except_notice', 0)), 'except_speaker' => intval($boardMeta->item('except_speaker', 0)), 'use_anonymous' => intval($boardMeta->item('use_anonymous', 0)), 'use_personal' => intval($boardMeta->item('use_personal', 0)), 'blame_blind_count' => intval($boardMeta->item('blame_blind_count', 0)) ]; } /** * 게시글 가공 */ private function _filter($postInfo) { if ($postInfo) { $config = $this->_config($postInfo->board_id); // 1:1 게시판에서는 전체공지 제외 if($config->use_personal && $postInfo->is_speaker) { return null; } // 공지 제외 if ($config->except_notice && $postInfo->is_notice) { return null; } // 전체 공지 제외 if ($config->except_speaker && $postInfo->is_speaker) { return null; } $postInfo->subject = $this->strCut($postInfo->subject, $config->subject_length); $postInfo->viewURL = route('board.post.view', [$postInfo->code, $postInfo->id]) . $this->queryString(); $postInfo->listURL = route('board.list', [$postInfo->code]); $postInfo->createdAt = $this->shortDate($postInfo->created_at); $datetime = (time() - strtotime($postInfo->created_at)); $postInfo->isNew = ($datetime <= ($config->new_icon_hour * 3600)); // 시간 내에 포함하면 표시 // 시간 내에 포함하거나 조회 수 이상이면 표시 $postInfo->isHot = ($config->hot_icon_day > 0 ? ($datetime <= ($config->hot_icon_day * 86400)) : true) && ($config->hot_icon_hit > 0 ? ($config->hot_icon_hit <= $postInfo->hit) : false); $postInfo->isBlame = ($config->blame_blind_count && $postInfo->blame >= $config->blame_blind_count); $postInfo->hit = number_format($postInfo->hit); $postInfo->like = number_format($postInfo->like); $postInfo->user = new stdClass(); $postInfo->user->name = ($config->use_anonymous ? '익명' : $postInfo->username); } return $postInfo; } /** * 게시판 캐시 삭제 */ public function clearLatest(string $code): void { Cache::tags('latest-board-' . $code)->flush(); } }