CommentController.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <?php
  2. namespace App\Http\Controllers\Board;
  3. use Illuminate\Http\Request;
  4. use App\Http\Controllers\Controller;
  5. use App\Http\Requests\CommentRequest;
  6. use App\Http\Traits\PagingTrait;
  7. use App\Services\BoardService;
  8. use App\Services\PostService;
  9. use App\Services\CommentService;
  10. use App\Models\Board;
  11. use App\Models\BoardMeta;
  12. use App\Models\Comment;
  13. use App\Models\DTO\SearchData;
  14. use App\Models\DTO\ResponseData;
  15. class CommentController extends Controller
  16. {
  17. use PagingTrait;
  18. protected BoardService $boardService;
  19. protected PostService $postService;
  20. protected CommentService $commentService;
  21. protected string $code; // 게시판 코드
  22. protected int $postID; // 게시글 번호
  23. protected Board $board; // 게시판 정보
  24. protected BoardMeta $boardMeta; // 게시판 설정 값
  25. protected ?Comment $comment; // 게시판 설정 값
  26. public function __construct(
  27. BoardService $boardService,
  28. PostService $postService,
  29. CommentService $commentService
  30. ) {
  31. $this->middleware(['front', 'authed']);
  32. // 인증 필수
  33. $this->middleware('auth')->only([
  34. 'blame', 'like', 'dislike'
  35. ]);
  36. // 댓글 읽기 권한 확인
  37. $this->middleware('comment.access')->only('index');
  38. // 댓글 쓰기 권한 확인
  39. $this->middleware('comment.create')->only(['store', 'reply']);
  40. // 댓글 수정 권한 확인
  41. $this->middleware('comment.update')->only('update');
  42. // 댓글 삭제 권한 확인
  43. $this->middleware('comment.delete')->only('delete');
  44. // 댓글/답글 속도 제한
  45. $this->middleware('throttle:commentWrite')->only(['store', 'reply']);
  46. $this->boardService = $boardService;
  47. $this->postService = $postService;
  48. $this->commentService = $commentService;
  49. }
  50. /**
  51. * 댓글 목록
  52. * @method GET
  53. * @see /board/{code}/{postID}/comment
  54. */
  55. public function index(Request $request, string $code, int $postID)
  56. {
  57. $params = SearchData::fromRequest($request);
  58. $this->board = $request->board;
  59. $this->boardMeta = $request->boardMeta;
  60. if($perPage = $this->boardMeta->item('comment_per_page', 0)) {
  61. $params->perPage = intval($perPage);
  62. $params->offset = $this->getPageOffset($params->page, $params->perPage);
  63. }
  64. if($pageCount = $this->boardMeta->item('comment_page_count', 0)) {
  65. $params->pageCount = intval($pageCount);
  66. }
  67. $params->sort = intval($request->query('sort', 1)); // 정렬 (최신순, 공감순, 댓글순)
  68. $comment = $this->commentService->list($code, $postID, $params);
  69. return view(layout('board.comment.index'), [
  70. 'boardMeta' => $this->boardMeta,
  71. 'comment' => $comment,
  72. 'params' => $params
  73. ]);
  74. }
  75. /**
  76. * 댓글 등록
  77. * @method POST
  78. * @see /board/{code}/{postID}/comment/store
  79. */
  80. public function store(CommentRequest $request, ResponseData $response, string $code): ResponseData
  81. {
  82. $this->board = $request->board;
  83. $this->boardMeta = $request->boardMeta;
  84. // 댓글 등록
  85. $result = $this->commentService->register($request, $response);
  86. if(!$result->success) {
  87. return $result;
  88. }
  89. $this->comment = $result->comment;
  90. // 댓글 작성 경험치 처리
  91. $this->commentService->setUserExp($this->comment, $this->comment->user, EXP_TYPE_8);
  92. // 최근 게시글 캐시 삭제
  93. $this->boardService->clearLatest($code);
  94. $result->cid = $this->comment->id;
  95. // 이메일 발송
  96. $this->commentService->sendEmailNotify($this->comment, (
  97. $this->boardMeta->item('use_personal', 0) ? SEND_MAIL_FORM_TYPE_12 : SEND_MAIL_FORM_TYPE_8
  98. ));
  99. unset($result->comment, $this->comment);
  100. return $result;
  101. }
  102. /**
  103. * 댓글 수정
  104. * @method PUT
  105. * @see /board/{code}/{postID}/comment/update
  106. */
  107. public function update(CommentRequest $request, ResponseData $response): ResponseData
  108. {
  109. // 댓글 수정
  110. $result = $this->commentService->updater($request, $response);
  111. if(!$result->success) {
  112. return $result;
  113. }
  114. $result->cid = $request->comment->id;
  115. unset($result->comment);
  116. return $result;
  117. }
  118. /**
  119. * 댓글 답글
  120. * @method POST
  121. * @see /board/{code}/{postID}/comment/reply
  122. */
  123. public function reply(CommentRequest $request, ResponseData $response, string $code): ResponseData
  124. {
  125. $this->board = $request->board;
  126. $this->boardMeta = $request->boardMeta;
  127. // 댓글 답글
  128. $result = $this->commentService->reply($request, $response);
  129. if(!$result->success) {
  130. return $result;
  131. }
  132. $this->comment = $result->comment;
  133. // 댓글 작성 경험치 처리
  134. $this->commentService->setUserExp($this->comment, $this->comment->user, EXP_TYPE_8);
  135. // 최근 게시글 캐시 삭제
  136. $this->boardService->clearLatest($code);
  137. $result->cid = $this->comment->id;
  138. // 이메일 발송
  139. $this->commentService->sendEmailNotify($this->comment, (
  140. $this->boardMeta->item('use_personal', 0) ? SEND_MAIL_FORM_TYPE_12 : SEND_MAIL_FORM_TYPE_8
  141. ));
  142. unset($result->comment, $this->comment);
  143. return $result;
  144. }
  145. /**
  146. * 댓글 삭제
  147. * @method DELETE
  148. * @see /board/{code}/{postID}/comment/delete
  149. */
  150. public function delete(Request $request, ResponseData $response, string $code): ResponseData
  151. {
  152. $request->validate([
  153. 'bid' => 'required|numeric|exists:tb_board,id',
  154. 'pid' => 'required|numeric|exists:tb_post,id',
  155. 'cid' => 'required|numeric|exists:tb_comment,id'
  156. ]);
  157. $result = $this->commentService->delete($request, $response);
  158. if(!$result->success) {
  159. return $result;
  160. }
  161. $this->comment = $request->comment;
  162. // 관리자인 경우
  163. if(IS_ADMIN) {
  164. $expType = EXP_TYPE_11;
  165. }else{
  166. $expType = EXP_TYPE_12;
  167. }
  168. // 댓글 삭제 경험치 처리
  169. $this->commentService->setUserExp($this->comment, $this->comment->user, $expType);
  170. // 최근 게시글 캐시 삭제
  171. $this->boardService->clearLatest($code);
  172. unset($result->comment, $this->comment);
  173. return $result;
  174. }
  175. /**
  176. * 댓글 신고
  177. * @method POST
  178. * @see /board/{code}/{postID}/comment/blame
  179. */
  180. public function blame(Request $request, ResponseData $response): ResponseData
  181. {
  182. $request->validate([
  183. 'bid' => 'required|numeric|exists:tb_board,id',
  184. 'pid' => 'required|numeric|exists:tb_post,id',
  185. 'cid' => 'required|numeric|exists:tb_comment,id',
  186. 'type' => 'required|numeric|in:1,2,3,4,5,6,7,8,9',
  187. 'reason' => 'nullable|string|max:1000'
  188. ]);
  189. $result = $this->commentService->blame($request, $response);
  190. if(!$result->success) {
  191. return $result;
  192. }
  193. $this->comment = $request->comment;
  194. // 이메일 발송
  195. $this->commentService->sendEmailNotify($this->comment, SEND_MAIL_FORM_TYPE_10);
  196. return $result;
  197. }
  198. /**
  199. * 댓글 좋아요
  200. * @method POST
  201. * @see /board/{code}/{postID}/comment/like
  202. */
  203. public function like(Request $request, ResponseData $response): ResponseData
  204. {
  205. $request->validate([
  206. 'bid' => 'required|numeric|exists:tb_board,id',
  207. 'pid' => 'required|numeric|exists:tb_post,id',
  208. 'cid' => 'required|numeric|exists:tb_comment,id'
  209. ]);
  210. $result = $this->commentService->like($request, $response);
  211. if(!$result->success) {
  212. return $result;
  213. }
  214. $this->comment = $result->comment;
  215. // 댓글 좋아요 경험치 처리
  216. $this->commentService->setUserExp($this->comment, $request->user(), EXP_TYPE_21);
  217. // 댓글 좋아요 받음 (상대방)
  218. $this->commentService->setUserExp($this->comment, $this->comment->user, EXP_TYPE_23);
  219. unset($result->comment, $this->comment);
  220. return $result;
  221. }
  222. /**
  223. * 댓글 싫어요
  224. * @method POST
  225. * @see /board/{code}/{postID}/comment/dislike
  226. */
  227. public function dislike(Request $request, ResponseData $response): ResponseData
  228. {
  229. $request->validate([
  230. 'bid' => 'required|numeric|exists:tb_board,id',
  231. 'pid' => 'required|numeric|exists:tb_post,id',
  232. 'cid' => 'required|numeric|exists:tb_comment,id'
  233. ]);
  234. $result = $this->commentService->dislike($request, $response);
  235. if(!$result->success) {
  236. return $result;
  237. }
  238. $this->comment = $result->comment;
  239. // 댓글 싫어요 경험치 처리
  240. $this->commentService->setUserExp($this->comment, $request->user(), EXP_TYPE_22);
  241. // 댓글 싫어요 받음 (상대방)
  242. $this->commentService->setUserExp($this->comment, $this->comment->user, EXP_TYPE_24);
  243. unset($result->comment, $this->comment);
  244. return $result;
  245. }
  246. }