PostService.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. <?php
  2. namespace App\Services;
  3. use Cache;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Http\Request;
  6. use App\Http\Requests\PostRequest;
  7. use App\Http\Traits\CommonTrait;
  8. use App\Http\Traits\BoardTrait;
  9. use App\Models\Board;
  10. use App\Models\BoardMeta;
  11. use App\Models\Post;
  12. use App\Models\PostMeta;
  13. use App\Models\PostLike;
  14. use App\Models\PostTag;
  15. use App\Models\PostLink;
  16. use App\Models\PostFile;
  17. use App\Models\PostHistory;
  18. use App\Models\PostDeleted;
  19. use App\Models\User;
  20. use App\Models\FileLib;
  21. use App\Models\PostBlame;
  22. use App\Models\PostBookmark;
  23. use App\Models\PostFileDownLog;
  24. use App\Models\PostLinkClickLog;
  25. use App\Models\EditorImage;
  26. use App\Models\EmailLib;
  27. use App\Models\Exp;
  28. use App\Models\DTO\ResponseData;
  29. use Exception;
  30. class PostService
  31. {
  32. use CommonTrait;
  33. use BoardTrait;
  34. public Board $boardModel;
  35. public BoardMeta $boardMetaModel;
  36. public User $userModel;
  37. public Post $postModel;
  38. public PostMeta $postMetaModel;
  39. public PostHistory $postHistoryModel;
  40. public PostBookmark $postBookmarkModel;
  41. public PostLike $postLikeModel;
  42. public PostTag $postTagModel;
  43. public PostFile $postFileModel;
  44. public PostFileDownLog $postFileDownLogModel;
  45. public PostBlame $postBlameModel;
  46. public PostLink $postLinkModel;
  47. public PostLinkClickLog $postLinkClickLogModel;
  48. public PostDeleted $postDeletedModel;
  49. public FileLib $fileLib;
  50. public EditorImage $editorImageModel;
  51. public function __construct()
  52. {
  53. $this->boardModel = new Board();
  54. $this->boardMetaModel = new BoardMeta();
  55. $this->postModel = new Post();
  56. $this->postMetaModel = new PostMeta();
  57. $this->postHistoryModel = new PostHistory();
  58. $this->postBookmarkModel = new PostBookmark();
  59. $this->postLikeModel = new PostLike();
  60. $this->postTagModel = new PostTag();
  61. $this->postFileModel = new PostFile();
  62. $this->postFileDownLogModel = new PostFileDownLog();
  63. $this->postBlameModel = new PostBlame();
  64. $this->postLinkModel = new PostLink();
  65. $this->postLinkClickLogModel = new PostLinkClickLog();
  66. $this->postDeletedModel = new PostDeleted();
  67. $this->userModel = new User();
  68. $this->fileLib = new FileLib();
  69. $this->editorImageModel = new EditorImage();
  70. }
  71. public function meta(int $postID): ?PostMeta
  72. {
  73. return $this->postMetaModel->getAllMeta($postID);
  74. }
  75. /**
  76. * 게시글 정보 조회
  77. */
  78. public function find(int $postID): Post
  79. {
  80. $post = $this->postModel->get($postID);
  81. if(!$post->exists) {
  82. return $post;
  83. }
  84. $code = $post->board->code;
  85. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  86. // 게시글 정보
  87. $post->viewURL = route('board.post.view', [$code, $postID]);
  88. $post->beforeViewURL = ($post->beforePostID ? route('board.post.view', [$code, $post->beforePostID]) : null);
  89. $post->nextViewURL = ($post->nextPostID ? route('board.post.view', [$code, $post->nextPostID]) : null);
  90. $post->createdAt = $post->created_at->format('Y.m.d H:i:s');
  91. $post->ipAddress = null;
  92. $post->isBookmark = false;
  93. $post->isLike = false;
  94. $post->isDislike = false;
  95. // 본문 URL 링크 자동 생성
  96. if ($boardMeta->item('use_auto_url', 0)) {
  97. $post->content = $this->urlAutoLink($post->content, $boardMeta->item('content_target_blank', 0)); // Link 새창 여부
  98. }
  99. // 익명 게시판일 경우
  100. if(
  101. $boardMeta->item('use_anonymous', 0)
  102. && (!$post->user->is_admin || !$boardMeta->item('anonymous_except_admin', 0))
  103. && $post->user->id
  104. ) {
  105. $post->username = $this->createAnonymousName(
  106. $boardMeta->item('anonymous_name'), $post->user_id, $post->id
  107. );
  108. }
  109. if($post->user->exists) {
  110. $post->user->thumb = $this->profileThumbSrc($post->user->thumb);
  111. $post->user->createdAt = $post->user->created_at->format('Y.m.d');
  112. }
  113. // IP 형식 처리
  114. $showPostIP = $boardMeta->item('show_post_ip'); // 노출 방법
  115. if ($showPostIP) {
  116. $ipDisplayStyle = ($showPostIP == 2 || IS_ADMIN ? '1111' : config('ip_display_style')); // IP 형식
  117. $post->ipAddress = $this->ipAddrMasking($post->ip_address, $ipDisplayStyle);
  118. }
  119. // 즐겨찾기
  120. if ($boardMeta->item('use_bookmark', 0)) {
  121. $post->isBookmark = $this->postBookmarkModel->isAlready($post, UID);
  122. }
  123. // 좋아요
  124. if ($boardMeta->item('use_post_like', 0)) {
  125. $post->isLike = $this->postLikeModel->isAlready($post, UID, LIKE);
  126. }
  127. // 싫어요
  128. if ($boardMeta->item('use_post_dislike', 0)) {
  129. $post->isDislike = $this->postLikeModel->isAlready($post, UID, DISLIKE);
  130. }
  131. // 태그
  132. $post->tags = $post->postTag;
  133. // 첨부파일
  134. $post->files = $post->postFile;
  135. // 링크 첨부
  136. $post->links = $post->postLink;
  137. return $post;
  138. }
  139. /**
  140. * 게시글 등록 처리
  141. */
  142. public function register(PostRequest $request, ResponseData $response): ResponseData
  143. {
  144. DB::beginTransaction();
  145. try {
  146. $user = $request->user();
  147. $boardID = intval($request->post('bid'));
  148. $boardMeta = $request->boardMeta;
  149. // 게시글 첨부 사진 저장
  150. $content = $this->getContent($request);
  151. $thumbnail = $this->getThumbnail($content,
  152. ($boardMeta->item('board_layout_type') == BOARD_LAYOUT_TYPE_1 ? NO_IMAGE_NORMAL_SRC : null)
  153. );
  154. $imageRows = $this->getImageRows($content);
  155. $videoRows = $this->getVideoRows($content);
  156. // 게시글 정보 저장
  157. $post = $this->postModel->register([
  158. 'board_id' => $boardID,
  159. 'board_category_id' => $request->post('category'),
  160. 'user_id' => $user?->id,
  161. 'thumbnail' => $thumbnail,
  162. 'subject' => trim($request->post('subject')),
  163. 'content' => $content,
  164. 'sid' => $user?->sid,
  165. 'username' => $request->post('username', $user?->name),
  166. 'email' => $user?->email,
  167. 'password' => $request->post('password'),
  168. 'comment_rows' => 0,
  169. 'comment_updated_at' => null,
  170. 'is_reply' => 0,
  171. 'is_personal' => $boardMeta->item('use_personal', 0),
  172. 'is_secret' => ($boardMeta->item('use_post_secret', 0) == '2' ? 1 : $request->post('is_secret', 0)),
  173. 'is_notice' => $request->post('is_notice', 0),
  174. 'is_speaker' => $request->post('is_speaker', 0),
  175. 'is_html' => $boardMeta->item('use_post_dhtml', 0),
  176. 'use_comment' => $boardMeta->item('use_comment', 0),
  177. 'receive_email' => 0,
  178. 'hit' => 0,
  179. 'like' => 0,
  180. 'dislike' => 0,
  181. 'blame' => 0,
  182. 'device_type' => DEVICE_TYPE,
  183. 'file_rows' => 0,
  184. 'image_rows' => $imageRows,
  185. 'video_rows' => $videoRows,
  186. 'link_rows' => 0,
  187. 'tag_rows' => 0,
  188. 'is_delete' => 0,
  189. 'ip_address' => IP_ADDRESS,
  190. 'user_agent' => USER_AGENT,
  191. 'deleted_at' => null,
  192. 'updated_at' => null,
  193. 'created_at' => now()
  194. ]);
  195. // 게시글 Tag 저장
  196. $this->postTagModel->register($post, $request->post('tags'));
  197. // 게시글 Link 저장
  198. $this->postLinkModel->register($post, $request->post('links'));
  199. // 게시글 File 저장
  200. $this->postFileModel->register($post, $request->file('files'));
  201. // 게시글 기록 저장
  202. if ($boardMeta->use_post_history) {
  203. $this->postHistoryModel->register($post,'게시글 등록');
  204. }
  205. // 게시판 게시글 수 갱신
  206. $this->boardModel->updatePostRows($boardID);
  207. // 태그 캐시 삭제
  208. Cache::forget('tags');
  209. $response->post = $post;
  210. DB::commit();
  211. } catch (Exception $e) {
  212. $response = $response::fromException($e);
  213. DB::rollBack();
  214. }
  215. return $response;
  216. }
  217. /**
  218. * 게시글 수정 처리
  219. */
  220. public function updater(PostRequest $request, ResponseData $response): ResponseData
  221. {
  222. DB::beginTransaction();
  223. try {
  224. $user = $request->user();
  225. $boardMeta = $request->boardMeta;
  226. $boardID = intval($request->post('bid'));
  227. $postID = intval($request->post('pid'));
  228. // 게시글 첨부 사진 저장
  229. $content = $this->getContent($request);
  230. $thumbnail = $this->getThumbnail($content,
  231. ($boardMeta->item('board_layout_type') == BOARD_LAYOUT_TYPE_1 ? NO_IMAGE_NORMAL_SRC : null)
  232. );
  233. $imageRows = $this->getImageRows($content);
  234. $videoRows = $this->getVideoRows($content);
  235. // 게시글 기록 저장
  236. if ($boardMeta->item('use_post_history', 0)) {
  237. $this->postHistoryModel->updater($request->post, '게시글 수정');
  238. }
  239. // 게시글 정보 저장
  240. $post = $this->postModel->updater($postID, [
  241. 'board_id' => $boardID,
  242. 'board_category_id' => $request->post('category'),
  243. 'user_id' => $user?->id,
  244. 'thumbnail' => $thumbnail,
  245. 'subject' => trim($request->post('subject')),
  246. 'content' => $content,
  247. 'sid' => $user?->sid,
  248. 'username' => $request->post('username', $user?->name),
  249. 'email' => $user?->email,
  250. 'password' => $request->post('password'),
  251. 'is_personal' => $boardMeta->item('use_personal', 0),
  252. 'is_secret' => ($boardMeta->item('use_post_secret', 0) == '2' ? 1 : $request->post('is_secret', 0)),
  253. 'is_notice' => $request->post('is_notice', 0),
  254. 'is_speaker' => $request->post('is_speaker', 0),
  255. 'is_html' => $boardMeta->item('use_post_dhtml', 0),
  256. 'use_comment' => $boardMeta->item('use_comment', 0),
  257. 'receive_email' => 0,
  258. 'device_type' => DEVICE_TYPE,
  259. 'file_rows' => 0,
  260. 'image_rows' => $imageRows,
  261. 'video_rows' => $videoRows,
  262. 'link_rows' => 0,
  263. 'tag_rows' => 0,
  264. 'ip_address' => IP_ADDRESS,
  265. 'user_agent' => USER_AGENT,
  266. 'updated_at' => now()
  267. ]);
  268. // 게시글 Tag 저장
  269. $this->postTagModel->updater($post, $request->post('tags'));
  270. // 게시글 Link 저장
  271. $this->postLinkModel->updater($post, $request->post('links'));
  272. // 게시글 File 저장
  273. $this->postFileModel->updater($post, $request->post('file_is_delete', []), $request->file('files'));
  274. // 태그 캐시 삭제
  275. Cache::forget('tags');
  276. DB::commit();
  277. } catch (Exception $e) {
  278. $response = $response::fromException($e);
  279. DB::rollBack();
  280. }
  281. return $response;
  282. }
  283. /**
  284. * 게시글 삭제
  285. */
  286. public function delete(Request $request, ResponseData $response): ResponseData
  287. {
  288. DB::beginTransaction();
  289. try {
  290. $post = $request->post;
  291. // 게시글 존재 확인
  292. if (!$post->exists) {
  293. throw new Exception('게시글이 존재 하지 않습니다.');
  294. }
  295. $user = $request->user();
  296. // 게시글 삭제 여부 승인
  297. $this->postModel->remove($post, $user);
  298. // 태그 캐시 삭제
  299. Cache::forget('tags');
  300. DB::commit();
  301. } catch (Exception $e) {
  302. $response = $response::fromException($e);
  303. DB::rollBack();
  304. }
  305. return $response;
  306. }
  307. /**
  308. * 게시글 즐겨찾기
  309. */
  310. public function bookmark(Request $request, ResponseData $response): ResponseData
  311. {
  312. DB::beginTransaction();
  313. try {
  314. $post = $this->postModel->findOrNew(
  315. $request->input('pid')
  316. );
  317. // 게시글 존재 확인
  318. if (!$post->exists) {
  319. throw new Exception('게시글이 존재 하지 않습니다.');
  320. }
  321. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  322. if (!$boardMeta->item('use_bookmark', 0)) {
  323. throw new Exception('즐겨찾기 기능은 사용하지 않습니다.');
  324. }
  325. $userID = $request->user()->id;
  326. if ($this->postBookmarkModel->isAlready($post, $userID)) {
  327. $this->postBookmarkModel->remove($post, $userID);
  328. } else {
  329. $this->postBookmarkModel->register([
  330. 'board_id' => $post->board_id,
  331. 'post_id' => $post->id,
  332. 'user_id' => $userID,
  333. 'ip_address' => IP_ADDRESS,
  334. 'user_agent' => USER_AGENT,
  335. 'created_at' => now()
  336. ]);
  337. }
  338. // 즐겨찾기 수 저장
  339. $this->postMetaModel->save($post->id, [
  340. 'bookmark_rows' => $this->postBookmarkModel->rows($post)
  341. ]);
  342. $response->post = $post;
  343. DB::commit();
  344. } catch (Exception $e) {
  345. $response = $response::fromException($e);
  346. DB::rollBack();
  347. }
  348. return $response;
  349. }
  350. /**
  351. * 게시글 신고
  352. */
  353. public function blame(Request $request, ResponseData $response): ResponseData
  354. {
  355. DB::beginTransaction();
  356. try {
  357. $post = $this->postModel->findOrNew(
  358. $request->input('pid')
  359. );
  360. // 게시글 존재 확인
  361. if(!$post->exists) {
  362. throw new Exception('게시글이 존재 하지 않습니다.');
  363. }
  364. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  365. if (!$boardMeta->item('use_blame', 0)) {
  366. throw new Exception('신고 기능은 사용하지 않습니다.');
  367. }
  368. $userID = $request->user()->id;
  369. // 이미 신고했는지 확인
  370. if ($this->postBlameModel->isAlready($post, $userID)) {
  371. throw new Exception('이미 신고하셨습니다.');
  372. }
  373. $this->postBlameModel->register([
  374. 'board_id' => $post->board_id,
  375. 'post_id' => $post->id,
  376. 'user_id' => $userID,
  377. 'type' => $request->post('type'),
  378. 'reason' => $request->post('reason'),
  379. 'status' => 0,
  380. 'memo' => null,
  381. 'ip_address' => IP_ADDRESS,
  382. 'user_agent' => USER_AGENT,
  383. 'created_at' => now()
  384. ]);
  385. // 게시글 신고 수 증가
  386. $this->postModel->increaseBlame($post->id);
  387. $response->post = $post;
  388. DB::commit();
  389. } catch (Exception $e) {
  390. $response = $response::fromException($e);
  391. DB::rollBack();
  392. }
  393. return $response;
  394. }
  395. /**
  396. * 게시글 좋아요
  397. */
  398. public function like(Request $request, ResponseData $response): ResponseData
  399. {
  400. DB::beginTransaction();
  401. try {
  402. $post = $this->postModel->findOrNew(
  403. $request->input('pid')
  404. );
  405. // 게시글 존재 확인
  406. if(!$post->exists) {
  407. throw new Exception('게시글이 존재 하지 않습니다.');
  408. }
  409. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  410. if (!$boardMeta->item('use_post_like', 0)) {
  411. throw new Exception('추천 기능은 사용하지 않습니다.');
  412. }
  413. $userID = $request->user()->id;
  414. $saveData = [
  415. 'board_id' => $post->board_id,
  416. 'post_id' => $post->id,
  417. 'user_id' => $userID,
  418. 'type' => LIKE,
  419. 'ip_address' => IP_ADDRESS,
  420. 'user_agent' => USER_AGENT,
  421. 'created_at' => now()
  422. ];
  423. $likeInfo = $this->postLikeModel->info($post, $userID);
  424. if ($likeInfo->exists) { // 이미 추천함
  425. $this->postLikeModel->remove($post, $userID);
  426. if ($likeInfo->type == LIKE) {
  427. $this->postModel->decreaseLike($post->id);
  428. } else if ($likeInfo->type == DISLIKE) {
  429. $this->postLikeModel->register($saveData);
  430. $this->postModel->increaseLike($post->id);
  431. $this->postModel->decreaseDisLike($post->id);
  432. }
  433. } else { // 추천
  434. $this->postLikeModel->register($saveData);
  435. $this->postModel->increaseLike($post->id);
  436. }
  437. $response->post = $post;
  438. DB::commit();
  439. } catch (Exception $e) {
  440. $response = $response::fromException($e);
  441. DB::rollBack();
  442. }
  443. return $response;
  444. }
  445. /**
  446. * 게시글 싫어요
  447. */
  448. public function dislike(Request $request, ResponseData $response): ResponseData
  449. {
  450. DB::beginTransaction();
  451. try {
  452. $post = $this->postModel->findOrNew(
  453. $request->input('pid')
  454. );
  455. // 게시글 존재 확인
  456. if(!$post->exists) {
  457. throw new Exception('게시글이 존재 하지 않습니다.');
  458. }
  459. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  460. if (!$boardMeta->item('use_post_dislike', 0)) {
  461. throw new Exception('비추천 기능은 사용하지 않습니다.');
  462. }
  463. $userID = $request->user()->id;
  464. $saveData = [
  465. 'board_id' => $post->board_id,
  466. 'post_id' => $post->id,
  467. 'user_id' => $userID,
  468. 'type' => DISLIKE,
  469. 'ip_address' => IP_ADDRESS,
  470. 'user_agent' => USER_AGENT,
  471. 'created_at' => now()
  472. ];
  473. $likeInfo = $this->postLikeModel->info($post, $userID);
  474. if ($likeInfo->exists) { // 이미 추천함
  475. $this->postLikeModel->remove($post, $userID);
  476. if ($likeInfo->type == DISLIKE) {
  477. $this->postModel->decreaseDisLike($post->id);
  478. } else if ($likeInfo->type == LIKE) {
  479. $this->postLikeModel->register($saveData);
  480. $this->postModel->increaseDisLike($post->id);
  481. $this->postModel->decreaseLike($post->id);
  482. }
  483. } else {
  484. $this->postLikeModel->register($saveData);
  485. $this->postModel->increaseDisLike($post->id);
  486. }
  487. $response->post = $post;
  488. DB::commit();
  489. } catch (Exception $e) {
  490. $response = $response::fromException($e);
  491. DB::rollBack();
  492. }
  493. return $response;
  494. }
  495. /**
  496. * 게시글 첨부파일 다운로드
  497. */
  498. public function download(Request $request): object
  499. {
  500. $ret = (object)[
  501. 'path' => null,
  502. 'name' => null
  503. ];
  504. $file = $this->postFileModel->info(
  505. $request->post('fid')
  506. );
  507. if (!$file->exists) {
  508. return $ret;
  509. }
  510. // 다운로드 횟수 증가
  511. $file->increaseDownload($file->id);
  512. // 다운로드 기록
  513. $boardMeta = $this->boardMetaModel->getAllMeta($file->board_id);
  514. if ($boardMeta->item('use_download_log', 0)) {
  515. $this->postFileDownLogModel->register([
  516. 'post_file_id' => $file->id,
  517. 'board_id' => $file->board_id,
  518. 'post_id' => $file->post_id,
  519. 'user_id' => $file->user_id,
  520. 'ip_address' => IP_ADDRESS,
  521. 'user_agent' => USER_AGENT,
  522. 'created_at' => now()
  523. ]);
  524. }
  525. $ret->path = $file->file_path;
  526. $ret->name = $file->origin_name;
  527. return $ret;
  528. }
  529. /**
  530. * 게시글 Link 클릭
  531. */
  532. public function linked(Request $request): string|null
  533. {
  534. $link = $this->postLinkModel->info(
  535. $request->post('lid')
  536. );
  537. if (!$link->exists) {
  538. return null;
  539. }
  540. // Link 클릭 횟수 증가
  541. $link->increaseHit($link->id);
  542. // Link 클릭 기록
  543. $boardMeta = $this->boardMetaModel->getAllMeta($link->board_id);
  544. if ($boardMeta->item('use_link_click_log', 0)) {
  545. $this->postLinkClickLogModel->register([
  546. 'post_link_id' => $link->id,
  547. 'board_id' => $link->board_id,
  548. 'post_id' => $link->post_id,
  549. 'user_id' => $link->user_id,
  550. 'ip_address' => IP_ADDRESS,
  551. 'user_agent' => USER_AGENT,
  552. 'created_at' => now()
  553. ]);
  554. }
  555. return ($link->url ?? null);
  556. }
  557. /**
  558. * 게시글 보기 조회 수 증가
  559. */
  560. public function addHit(Post $post): void
  561. {
  562. if($this->postModel->addHit($post)) {
  563. $this->postModel->increaseHit($post->id);
  564. }
  565. }
  566. /**
  567. * 게시글 작성 개수
  568. */
  569. public function userPostRows(Board $board, ?User $user): int
  570. {
  571. return $this->postModel->where([
  572. ['board_id', $board->id],
  573. ['user_id', $user?->id],
  574. ['ip_address', IP_ADDRESS]
  575. ])->whereRaw('DATE(created_at) = CURDATE()')->count();
  576. }
  577. /**
  578. * 게시글 추천 여부
  579. */
  580. public function userPostIsLike(Post $post, User $user): int
  581. {
  582. return $this->postLikeModel->where([
  583. ['board_id', $post->board_id],
  584. ['post_id', $post->id],
  585. ['user_id', $user->id]
  586. ])->orWhere('ip_address', IP_ADDRESS)->exists();
  587. }
  588. /**
  589. * 첨부 사진 저장
  590. */
  591. private function getContent(PostRequest $request): string
  592. {
  593. // 게시글 이미지 저장
  594. $boardMeta = $request->boardMeta;
  595. $postID = $this->postModel->lastedKey();
  596. $content = trim($request->post('content'));
  597. if ($boardMeta->item('save_external_image', 0)) {
  598. // link
  599. $content = $this->fileLib->saveImageFromUrl($content, UPLOAD_PATH_POST, $postID);
  600. }
  601. // blob
  602. $content = $this->fileLib->saveImageFromBlob($content, UPLOAD_PATH_POST, $postID);
  603. // 이미지 DB 기록
  604. $images = $this->fileLib->getImageFromContent($content);
  605. if(count($images) > 0) {
  606. foreach($images as $img) {
  607. $this->editorImageModel->register([
  608. 'target_type' => EDITOR_IMG_TYPE_1,
  609. 'target_id' => $postID,
  610. 'user_id' => UID,
  611. 'origin_name' => $img->origin,
  612. 'file_name' => $img->name,
  613. 'file_path' => $img->path,
  614. 'file_url' => $img->url,
  615. 'file_size' => $img->size,
  616. 'file_type' => $img->type,
  617. 'width' => $img->width,
  618. 'height' => $img->height,
  619. 'ip_address' => IP_ADDRESS,
  620. 'user_agent' => USER_AGENT
  621. ]);
  622. }
  623. }
  624. return $content;
  625. }
  626. /**
  627. * 게시글 경험치 지급
  628. */
  629. public function setUserExp(Post $post, User $user, int $type): bool
  630. {
  631. if(!$post->exists) {
  632. return false;
  633. }
  634. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  635. if (!$boardMeta->item('use_exp', 0)) {
  636. return false;
  637. }
  638. $column = MAP_EXP_TYPE[$type];
  639. $content = MAP_EXP_CONTENT[$type];
  640. $value = intval($boardMeta->{$column});
  641. $relatedID = sprintf("%d-%d", $post->board_id, $post->id);
  642. // 경험치 지급 구분
  643. return (new Exp)->register([
  644. 'user_id' => $user->id,
  645. 'content' => $content,
  646. 'value' => $value,
  647. 'type' => $type,
  648. 'related_id' => $relatedID,
  649. 'method' => request()->getMethod(),
  650. 'created_at' => now()
  651. ]);
  652. }
  653. /**
  654. * 게시글 관련 메일 발송
  655. */
  656. public function sendEmailNotify(Post $post, string $sendMailFormType): bool
  657. {
  658. if (!in_array($sendMailFormType, MAP_SEND_MAIL_TYPE)) {
  659. return false;
  660. }
  661. $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
  662. $sendMailType = str_replace('_form', '', $sendMailFormType);
  663. // 최고 관리자에게 발송
  664. $admin = ($boardMeta->item($sendMailType . '_super_admin', 0) ? $this->userModel->getMaster() : null);
  665. // 게시글 작성자에게 발송
  666. $postWriter = ($boardMeta->item($sendMailType . '_post_writer', 0) ? $post->user : null);
  667. if (!$admin && !$postWriter) {
  668. return false;
  669. }
  670. return (new EmailLib)->send($sendMailFormType, $admin, $postWriter);
  671. }
  672. }