PostTag.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Collection;
  6. use App\Models\DTO\SearchData;
  7. class PostTag extends Model
  8. {
  9. protected $table = 'tb_post_tag';
  10. protected $primaryKey = 'id';
  11. public $keyType = 'int';
  12. public $incrementing = true;
  13. public $timestamps = true;
  14. const CREATED_AT = 'created_at';
  15. const UPDATED_AT = null;
  16. protected $guarded = [];
  17. public function board()
  18. {
  19. return $this->belongsTo(Board::class);
  20. }
  21. public function post()
  22. {
  23. return $this->belongsTo(Post::class);
  24. }
  25. public function user()
  26. {
  27. return $this->belongsTo(User::class);
  28. }
  29. /**
  30. * 게시글 태그 조회
  31. */
  32. public function data(SearchData $params): object
  33. {
  34. $query = $this->query();
  35. $query->from(function($q) use($params) {
  36. $q->select(
  37. 'tb_board.name AS boardName',
  38. 'tb_board.code',
  39. 'tb_post_tag.*',
  40. 'tb_post.subject',
  41. 'tb_post.user_id',
  42. 'users.sid',
  43. 'users.name'
  44. );
  45. if($params->keyword) {
  46. switch ($params->field) {
  47. case 'tb_post_tag.id' :
  48. case 'users.id' :
  49. case 'users.sid' :
  50. $q->where($params->field, '=', $params->keyword);
  51. break;
  52. case 'tb_post.subject' :
  53. case 'tb_post_tag.tag' :
  54. case 'users.name' :
  55. case 'users.email' :
  56. $q->where($params->field, 'LIKE', "%{$params->keyword}%");
  57. break;
  58. }
  59. }
  60. if($params->startDate || $params->endDate) {
  61. if($params->startDate) {
  62. $q->where('tb_post_tag.created_at', '>=', $params->startDate . ' 00:00:00');
  63. }
  64. if($params->endDate) {
  65. $q->where('tb_post_tag.created_at', '<=', $params->endDate . ' 23:59:59');
  66. }
  67. }
  68. if($params->boardID) {
  69. $q->where('tb_post_tag.board_id', '=', $params->boardID);
  70. }
  71. $q->from('tb_post_tag');
  72. $q->join('tb_post', 'tb_post.id', '=', 'tb_post_tag.post_id');
  73. $q->join('tb_board', 'tb_board.id', '=', 'tb_post_tag.board_id');
  74. $q->leftJoin('users', 'users.id', '=', 'tb_post.user_id');
  75. }, 'TT');
  76. $query->select(
  77. 'TT.id',
  78. 'TT.boardName',
  79. 'TT.post_id',
  80. 'TT.board_id',
  81. 'TT.user_id',
  82. 'TT.created_at',
  83. 'TT.code',
  84. 'TT.subject',
  85. 'TT.sid',
  86. 'TT.name',
  87. DB::raw('GROUP_CONCAT(DISTINCT TT.tag SEPARATOR ", ") AS tag')
  88. );
  89. $query->groupBy('TT.id', 'TT.post_id', 'TT.board_id', 'TT.user_id', 'TT.created_at', 'TT.code', 'TT.subject', 'TT.sid', 'TT.name');
  90. $list = $query->paginate($params->perPage, ['*'], 'page', $params->page);
  91. $total = $this->count();
  92. $rows = $list->count();
  93. return (object)[
  94. 'total' => $total,
  95. 'rows' => $rows,
  96. 'list' => $list
  97. ];
  98. }
  99. /**
  100. * 게시글 태그 저장 (쉼표(,) 구분하여 값 삽입)
  101. */
  102. public function register(Post $post, ?string $tags): void
  103. {
  104. if ($tags) {
  105. foreach (explode(',', $tags) as $tag) {
  106. $tag = trim($tag);
  107. if ($tag) {
  108. $this->insert([
  109. 'board_id' => $post->board_id,
  110. 'post_id' => $post->id,
  111. 'tag' => $tag,
  112. 'ip_address' => IP_ADDRESS,
  113. 'user_agent' => USER_AGENT,
  114. 'created_at' => now()
  115. ]);
  116. }
  117. }
  118. $post->updateTagRows($post->id);
  119. }
  120. }
  121. /**
  122. * 게시글 태그 저장 (쉼표(,) 구분하여 값 삽입)
  123. */
  124. public function updater(Post $post, ?string $tags): void
  125. {
  126. // 기존 태그 삭제
  127. $this->remove($post);
  128. // 새로 등록
  129. $this->register($post, $tags);
  130. }
  131. /**
  132. * 게시글 태그 삭제
  133. */
  134. public function remove(Post $post): void
  135. {
  136. $this->where([
  137. ['board_id', $post->board_id],
  138. ['post_id', $post->id]
  139. ])->delete();
  140. }
  141. /**
  142. * 태그 목록 조회
  143. */
  144. public function getAllTags(): Collection
  145. {
  146. $sql = "
  147. SELECT
  148. PSTG.tag AS name,
  149. COUNT(DISTINCT PSTG.post_id) AS count
  150. FROM tb_post_tag PSTG
  151. INNER JOIN tb_post PST
  152. ON PST.id = PSTG.post_id
  153. WHERE PST.is_delete = 0
  154. GROUP BY PSTG.tag
  155. ORDER BY PSTG.tag ASC;
  156. ";
  157. return collect(DB::select($sql));
  158. }
  159. /**
  160. * 태그별 게시글 조회
  161. */
  162. public function getPostsByTag(SearchData $params): object
  163. {
  164. $sql = "
  165. SELECT COUNT(DISTINCT PST.id) AS total FROM tb_post PST JOIN tb_post_tag PSTG ON PST.id = PSTG.post_id WHERE PST.is_delete = 0 AND PSTG.tag = ?;
  166. ";
  167. $total = DB::selectOne($sql, [$params->name])->total;
  168. $sql = "
  169. SELECT
  170. PST.id,
  171. PST.board_id,
  172. PST.user_id,
  173. PST.thumbnail,
  174. PST.subject,
  175. PST.content,
  176. PST.created_at,
  177. BRD.name AS boardName,
  178. BRD.code AS boardCode,
  179. USR.sid AS userSID,
  180. USR.name AS userName,
  181. GROUP_CONCAT(DISTINCT PSTG_all.tag ORDER BY PSTG_all.tag SEPARATOR ', ') AS tags
  182. FROM tb_post PST
  183. INNER JOIN tb_post_tag PSTG ON PSTG.post_id = PST.id
  184. INNER JOIN tb_board BRD ON BRD.id = PST.board_id
  185. LEFT JOIN users USR ON USR.id = PST.user_id
  186. LEFT JOIN tb_post_tag PSTG_all ON PSTG_all.post_id = PST.id
  187. WHERE PST.is_delete = 0 AND PSTG.tag = ?
  188. GROUP BY
  189. PST.id, PST.board_id, PST.user_id, PST.subject, PST.created_at, BRD.name, BRD.code, USR.sid, USR.name
  190. ORDER BY
  191. PST.created_at DESC, PST.id DESC
  192. LIMIT ? OFFSET ?;
  193. ";
  194. $list = DB::select($sql, [
  195. $params->name,
  196. $params->perPage,
  197. $params->offset
  198. ]);
  199. $rows = count($list);
  200. return (object)[
  201. 'total' => $total,
  202. 'rows' => $rows,
  203. 'list' => $list
  204. ];
  205. }
  206. }