| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710 |
- <?php
- namespace App\Services;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- use App\Http\Requests\CommentRequest;
- use App\Http\Traits\CommonTrait;
- use App\Http\Traits\BoardTrait;
- use App\Models\User;
- use App\Models\Board;
- use App\Models\BoardMeta;
- use App\Models\Post;
- use App\Models\Comment;
- use App\Models\CommentMeta;
- use App\Models\CommentHistory;
- use App\Models\CommentLike;
- use App\Models\CommentBlame;
- use App\Models\CommentDeleted;
- use App\Models\FileLib;
- use App\Models\EmailLib;
- use App\Models\EditorImage;
- use App\Models\Exp;
- use App\Models\DTO\ResponseData;
- use App\Models\DTO\SearchData;
- use Exception;
- class CommentService
- {
- use CommonTrait;
- use BoardTrait;
- public Board $boardModel;
- public BoardMeta $boardMetaModel;
- public Post $postModel;
- public Comment $commentModel;
- public CommentMeta $commentMetaModel;
- public CommentHistory $commentHistoryModel;
- public CommentLike $commentLikeModel;
- public CommentBlame $commentBlameModel;
- public CommentDeleted $commentDeletedModel;
- public User $userModel;
- public FileLib $fileLib;
- public EmailLib $emailLib;
- public EditorImage $editorImageModel;
- public function __construct()
- {
- $this->boardModel = new Board();
- $this->boardMetaModel = new BoardMeta();
- $this->postModel = new Post();
- $this->commentModel = new Comment();
- $this->commentMetaModel = new CommentMeta();
- $this->commentHistoryModel = new CommentHistory();
- $this->commentLikeModel = new CommentLike();
- $this->commentBlameModel = new CommentBlame();
- $this->commentDeletedModel = new CommentDeleted();
- $this->userModel = new User();
- $this->fileLib = new FileLib();
- $this->emailLib = new EmailLib();
- $this->editorImageModel = new EditorImage();
- }
- public function meta(int $commentID): ?CommentMeta
- {
- return $this->commentMetaModel->getAllMeta($commentID);
- }
- public function find(int $commentID): Comment
- {
- return $this->_filter($this->commentModel->get($commentID));
- }
- /**
- * 댓글 전체 수
- */
- public function total(int $postID): int
- {
- return $this->commentModel->total($postID);
- }
- /**
- * 전체 댓글 목록 조회
- */
- public function list(string $code, int $postID, SearchData $params): object
- {
- $comments = $this->commentModel->getList($code, $postID, $params->page, $params->offset, $params->perPage, $params->sort);
- if($comments->total > 0) {
- $num = listNum($comments->total, $params->page, $params->perPage);
- foreach($comments->list as $i => $row) {
- $row = $this->commentModel->newInstance(get_object_vars($row), true);
- $row->num = $num--;
- $comments->list[$i] = $this->_filter($row);
- }
- }
- return $comments;
- }
- /**
- * 회원 댓글 조회
- */
- public function userList(int $userID, SearchData $params): object
- {
- $comments = $this->commentModel->getUserList($userID, $params);
- if($comments->total > 0) {
- $num = listNum($comments->total, $params->page, $params->perPage);
- foreach($comments->list as $i => $row) {
- $row = $this->commentModel->newInstance(get_object_vars($row), true);
- $row->num = $num--;
- $row->page = $this->commentModel->findPageNumber($row->id, $params->perPage);
- $comments->list[$i] = $this->_filter($row);
- }
- }
- return $comments;
- }
- /**
- * 댓글 정보 가공
- */
- private function _filter(Comment $comment): Comment
- {
- if(!$comment->exists) {
- return $comment;
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($comment->board_id);
- $comment->user->thumb = $this->profileThumbSrc($comment->user->thumb);
- $comment->viewURL = route('board.post.view', [
- $comment->board->code, $comment->post_id
- ]);
- // 익명 게시판일 경우
- if(
- $boardMeta->item('use_anonymous', 0)
- && (!$comment->user->is_admin || !$boardMeta->item('anonymous_except_admin', 0))
- && $comment->user->id
- ) {
- $comment->username = $this->createAnonymousName(
- $boardMeta->item('anonymous_name'), $comment->user->id, $comment->post_id
- );
- }
- // 댓글 설정 정보
- $commentMeta = $this->meta($comment->id);
- // 관리자에 의한 삭제
- $comment->isBlind = $commentMeta->item('is_blind', 0);
- // IP 표시 형식
- $showCommentIP = $boardMeta->item('show_comment_ip'); // 노출 방법
- if ($showCommentIP) {
- $ipDisplayStyle = ($showCommentIP == 2 || IS_ADMIN ? '1111' : config('ip_display_style')); // IP 형식
- $comment->ipAddress = $this->ipAddrMasking($comment->ip_address, $ipDisplayStyle);
- }
- // 신고 누적으로 숨김
- $comment->isBlame = false;
- if($commentBlameBlindCount = $boardMeta->item('comment_blame_blind_count', 0)) {
- $comment->isBlame = ($comment->blame >= $commentBlameBlindCount);
- }
- // 좋아요
- $comment->isLike = $this->commentLikeModel->isAlready($comment, UID, LIKE);
- // 싫어요
- $comment->isDislike = $this->commentLikeModel->isAlready($comment,UID, DISLIKE);
- // 작성일시
- $comment->createdAt = $this->dateFormat($comment->created_at);
- return $comment;
- }
- /**
- * 댓글 등록
- */
- public function register(CommentRequest $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $user = $request->user();
- $boardMeta = $request->boardMeta;
- $boardID = intval($request->post('bid'));
- $postID = intval($request->post('pid'));
- $content = $this->getContent($request);
- // 댓글 정보 저장
- $comment = $this->commentModel->register([
- 'board_id' => $boardID,
- 'post_id' => $postID,
- 'user_id' => $user?->id,
- 'parent_id' => null,
- 'is_reply' => 0,
- 'content' => $content,
- 'sid' => $user?->sid,
- 'username' => $request->post('username', $user?->name),
- 'email' => $user?->email,
- 'password' => $request->post('password'),
- 'reply' => 0,
- 'like' => 0,
- 'dislike' => 0,
- 'blame' => 0,
- 'device_type' => DEVICE_TYPE,
- 'is_secret' => ($boardMeta->item('use_comment_secret', 0) == '2' ? 1 : $request->post('is_secret', 0)),
- 'is_delete' => 0,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'deleted_at' => null,
- 'updated_at' => null,
- 'created_at' => now()
- ]);
- // 게시판 댓글 수 갱신
- $this->boardModel->updateCommentRows($boardID);
- // 게시글 댓글 수 갱신
- $this->postModel->updateCommentRows($postID);
- // 댓글 Meta 저장
- $this->commentMetaModel->save($comment->id, [
- 'is_blind' => 0,
- 'exec_blind_key' => null
- ]);
- // 댓글 기록 저장
- if ($boardMeta->item('use_comment_history', 0)) {
- $this->commentHistoryModel->register($comment, '댓글 등록');
- }
- $response->comment = $comment;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 댓글 수정
- */
- public function updater(CommentRequest $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $user = $request->user();
- $boardMeta = $request->boardMeta;
- $boardID = intval($request->post('bid'));
- $postID = intval($request->post('pid'));
- $commentID = intval($request->post('cid'));
- $content = $this->getContent($request);
- // 댓글 기록 저장
- if($boardMeta->item('use_comment_history', 0)) {
- $this->commentHistoryModel->updater($request->comment, '댓글 수정');
- }
- // 댓글 수정
- $comment = $this->commentModel->updater($commentID, [
- 'board_id' => $boardID,
- 'post_id' => $postID,
- 'user_id' => $user?->id,
- 'content' => $content,
- 'is_secret' => $request->post('is_secret', 0),
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'updated_at' => now()
- ]);
- // 댓글 작성시 글 수정 시각 갱신
- if($boardMeta->item('update_order_on_comment', 0)) {
- $this->postModel->updater($postID, [
- 'updated_at' => now()
- ]);
- }
- $response->comment = $comment;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 댓글 답글
- */
- public function reply(CommentRequest $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $user = $request->user();
- $boardMeta = $request->boardMeta;
- $boardID = intval($request->post('bid'));
- $postID = intval($request->post('pid'));
- $commentID = intval($request->post('cid'));
- $content = $this->getContent($request);
- // 답글 저장
- $newComment = $this->commentModel->reply($commentID, [
- 'board_id' => $boardID,
- 'post_id' => $postID,
- 'user_id' => $user?->id,
- 'parent_id' => null,
- 'is_reply' => 0,
- 'content' => $content,
- 'sid' => $user?->sid,
- 'username' => $request->post('username', $user?->name),
- 'email' => $user?->email,
- 'password' => $request->post('password'),
- 'reply' => 0,
- 'like' => 0,
- 'dislike' => 0,
- 'blame' => 0,
- 'device_type' => DEVICE_TYPE,
- 'is_secret' => ($boardMeta->item('use_comment_secret', 0) == '2' ? 1 : $request->post('is_secret', 0)),
- 'is_delete' => 0,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'deleted_at' => null,
- 'updated_at' => null,
- 'created_at' => now()
- ]);
- // 부모 댓글 답변 여부 등록
- $this->commentModel->updater($commentID, [
- 'is_reply' => 1
- ]);
- // 게시판 댓글 수 갱신
- $this->boardModel->updateCommentRows($boardID);
- // 게시글 댓글 수 갱신
- $this->postModel->updateCommentRows($postID);
- // 부모 댓글 수 갱신
- $this->commentModel->updateCommentRows($commentID);
- // 댓글 Meta 저장
- $this->commentMetaModel->save($newComment->id, [
- 'is_blind' => 0,
- 'exec_blind_key' => null
- ]);
- // 답글 등록 기록
- if($boardMeta->item('use_comment_history', 0)) {
- $this->commentHistoryModel->register($newComment, '답글 등록');
- }
- $response->comment = $newComment;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 댓글 삭제
- */
- public function delete(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $comment = $request->comment;
- // 댓글 존재 확인
- if (!$comment->exists) {
- throw new Exception('댓글이 존재 하지 않습니다.');
- }
- $userID = $request->user()?->id;
- // 댓글 삭제 여부 승인
- $this->commentModel->updater($comment->id, [
- 'is_delete' => 1,
- 'deleted_at' => now()
- ]);
- // 댓글 삭제 정보 추가
- $this->commentDeletedModel->register([
- 'board_id' => $comment->board_id,
- 'post_id' => $comment->post_id,
- 'comment_id' => $comment->id,
- 'user_id' => $userID,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ]);
- // 게시판 댓글 수 갱신
- $this->boardModel->updateCommentRows($comment->board_id);
- // 게시판 댓글 수 갱신
- $this->postModel->updateCommentRows($comment->post_id);
- // 부모 댓글 수 갱신
- $this->commentModel->updateCommentRows($comment->id);
- $response->comment = $comment;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 댓글 신고
- */
- public function blame(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $comment = $this->commentModel->findOrNew(
- $request->post('cid')
- );
- // 댓글 존재 확인
- if (!$comment->exists) {
- throw new Exception('댓글이 존재 하지 않습니다.');
- }
- $userID = $request->user()->id;
- // 이미 신고했는지 확인
- if ($this->commentBlameModel->isAlready($comment, $userID)) {
- throw new Exception('이미 신고하셨습니다.');
- }
- $this->commentBlameModel->register([
- 'board_id' => $comment->board_id,
- 'post_id' => $comment->post_id,
- 'comment_id' => $comment->id,
- 'user_id' => $userID,
- 'type' => $request->post('type'),
- 'reason' => $request->post('reason'),
- 'status' => 0,
- 'memo' => null,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ]);
- $this->commentModel->increaseBlame($comment->id);
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 댓글 좋아요
- */
- public function like(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $comment = $this->commentModel->findOrNew(
- $request->post('cid')
- );
- // 댓글 존재 확인
- if (!$comment->exists) {
- throw new Exception('댓글이 존재 하지 않습니다.');
- }
- $userID = $request->user()->id;
- $saveData = [
- 'board_id' => $comment->board_id,
- 'post_id' => $comment->post_id,
- 'comment_id' => $comment->id,
- 'user_id' => $userID,
- 'type' => LIKE,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ];
- $likeInfo = $this->commentLikeModel->info($comment, $userID);
- if ($likeInfo->exists) {
- $this->commentLikeModel->remove($comment, $userID);
- if ($likeInfo->type == LIKE) {
- $this->commentModel->decreaseLike($comment->id);
- } else if ($likeInfo->type == DISLIKE) {
- $this->commentLikeModel->register($saveData);
- $this->commentModel->increaseLike($comment->id);
- $this->commentModel->decreaseDisLike($comment->id);
- }
- } else {
- $this->commentLikeModel->register($saveData);
- $this->commentModel->increaseLike($comment->id);
- }
- $response->comment = $comment;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 댓글 싫어요
- */
- public function dislike(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $comment = $this->commentModel->findOrNew(
- $request->post('cid')
- );
- // 댓글 존재 확인
- if (!$comment->exists) {
- throw new Exception('댓글이 존재 하지 않습니다.');
- }
- $userID = $request->user()->id;
- $saveData = [
- 'board_id' => $comment->board_id,
- 'post_id' => $comment->post_id,
- 'comment_id' => $comment->id,
- 'user_id' => $userID,
- 'type' => DISLIKE,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ];
- $likeInfo = $this->commentLikeModel->info($comment, $userID);
- if ($likeInfo->exists) {
- $this->commentLikeModel->remove($comment, $userID);
- if ($likeInfo->type == DISLIKE) {
- $this->commentModel->decreaseDisLike($comment->id);
- } else if ($likeInfo->type == LIKE) {
- $this->commentLikeModel->register($saveData);
- $this->commentModel->increaseDisLike($comment->id);
- $this->commentModel->decreaseLike($comment->id);
- }
- } else {
- $this->commentLikeModel->register($saveData);
- $this->commentModel->increaseDisLike($comment->id);
- }
- $response->comment = $comment;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글에 내 댓글이 몇개인지 확인
- */
- public function userCommentRows(Post $post, User $user): int
- {
- return $this->commentModel->where([
- ['board_id', $post->board_id],
- ['post_id', $post->id],
- ['user_id', $user->id],
- ])->count();
- }
- /**
- * 댓글 에디터 내용 처리
- */
- private function getContent(CommentRequest $request): string
- {
- // 게시글 이미지 저장
- $boardMeta = $request->boardMeta;
- $postID = $request->pid;
- $commentID = $this->commentModel->lastedKey();
- $content = trim($request->post('content'));
- if ($boardMeta->use_personal)
- {
- $addPath = ($postID . DIRECTORY_SEPARATOR . $commentID);
- if ($boardMeta->save_external_image) {
- // link
- $content = $this->fileLib->saveImageFromUrl($content, UPLOAD_PATH_COMMENT, $addPath);
- }
- // blob
- $content = $this->fileLib->saveImageFromBlob($content, UPLOAD_PATH_COMMENT, $addPath);
- // 이미지 DB 기록
- $images = $this->fileLib->getImageFromContent($content);
- if(count($images) > 0) {
- foreach($images as $img) {
- $this->editorImageModel->register([
- 'target_type' => EDITOR_IMG_TYPE_2,
- 'target_id' => $addPath,
- 'user_id' => UID,
- 'origin_name' => $img->origin,
- 'file_name' => $img->name,
- 'file_path' => $img->path,
- 'file_url' => $img->url,
- 'file_size' => $img->size,
- 'file_type' => $img->type,
- 'width' => $img->width,
- 'height' => $img->height,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT
- ]);
- }
- }
- }
- return $content;
- }
- /**
- * 댓글 경험치 지급
- */
- public function setUserExp(Comment $comment, User $user, int $type): bool
- {
- $boardMeta = $this->boardMetaModel->getAllMeta($comment->board_id);
- if (!$boardMeta->item('use_exp', 0)) {
- return false;
- }
- $column = MAP_EXP_TYPE[$type];
- $content = MAP_EXP_CONTENT[$type];
- $value = intval($boardMeta->{$column});
- $relatedID = sprintf("%d-%d-%d", $comment->board_id, $comment->post_id, $comment->id);
- // 경험치 지급 구분
- return (new Exp)->register([
- 'user_id' => $user->id,
- 'content' => $content,
- 'value' => $value,
- 'type' => $type,
- 'related_id' => $relatedID,
- 'method' => request()->getMethod(),
- 'created_at' => now()
- ]);
- }
- /**
- * 게시글 관련 메일 발송
- */
- public function sendEmailNotify(Comment $comment, string $sendMailFormType): bool
- {
- if(!in_array($sendMailFormType, MAP_SEND_MAIL_TYPE)) {
- return false;
- }
- $post = $comment->post;
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- $sendMailType = str_replace('_form', '', $sendMailFormType);
- // 최고 관리자에게 발송
- $admin = ($boardMeta->item($sendMailType . '_super_admin', 0) ? $this->userModel->getMaster() : null);
- // 게시글 작성자에게 발송
- $postWriter = ($boardMeta->item($sendMailType . '_post_writer', 0) ? $post->user : null);
- // 댓글 작성자에게 발송
- $commentWriter = ($boardMeta->item($sendMailType . '_comment_writer', 0) ? $comment->user : null);
- if(!$admin && !$postWriter && !$commentWriter) {
- return false;
- }
- // 1:1 문의 답변 완료 처리
- $post->updater($post->id, [
- 'is_reply' => 1
- ]);
- return (new EmailLib)->send($sendMailFormType, $admin, $postWriter, $commentWriter);
- }
- }
|