| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- <?php
- namespace App\Services;
- use Illuminate\Support\Facades\Cache;
- use App\Http\Traits\CommonTrait;
- use App\Http\Traits\BoardTrait;
- use App\Http\Requests\BoardRequest;
- use App\Models\Board;
- use App\Models\BoardMeta;
- use App\Models\BoardCategory;
- use App\Models\BoardAdmin;
- use App\Models\DTO\SearchData;
- use stdClass;
- class BoardService
- {
- use CommonTrait;
- use BoardTrait;
- public Board $boardModel;
- public BoardMeta $boardMetaModel;
- public BoardCategory $boardCategoryModel;
- public BoardAdmin $boardAdminModel;
- public function __construct()
- {
- $this->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();
- }
- }
|