BoardCategory.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Support\Facades\DB;
  5. use App\Http\Traits\PagingTrait;
  6. use Kalnoy\Nestedset\NodeTrait;
  7. class BoardCategory extends Model
  8. {
  9. use PagingTrait;
  10. use NodeTrait;
  11. protected $table = 'tb_board_category';
  12. protected $primaryKey = 'id';
  13. public $keyType = 'int';
  14. public $incrementing = true;
  15. public $timestamps = true;
  16. const CREATED_AT = 'created_at';
  17. const UPDATED_AT = 'updated_at';
  18. protected $guarded = [];
  19. public function getParentIdName(): string
  20. {
  21. return 'parent_id';
  22. }
  23. public function getLftName(): string
  24. {
  25. return 'lft';
  26. }
  27. public function getRgtName(): string
  28. {
  29. return 'rgt';
  30. }
  31. /**
  32. * 게시판 분류 전체 조회
  33. */
  34. public function data(int $boardID, int $page, int $perPage): object
  35. {
  36. $sql = "SELECT COUNT(*) AS total FROM tb_board_category WHERE board_id = ?";
  37. $total = DB::selectOne($sql, [$boardID])->total;
  38. /*
  39. $sql = "SELECT
  40. CASE WHEN LEVEL > 1 THEN CONCAT(REPEAT(' ', level - 1), '┗> ') ELSE '' END AS tab,
  41. CASE WHEN LEVEL-1 > 0 THEN CONCAT(CONCAT(REPEAT('┗>', level - 2), '┗> '), bca.name)
  42. ELSE bca.name
  43. END AS title
  44. , bca.*
  45. , fnc.level
  46. FROM
  47. (
  48. SELECT fn_board_category() AS brd_category_key, @level AS level
  49. FROM (SELECT @startWith:= 0, @id:=@startWith, @level:=0) vars
  50. JOIN tb_board_category
  51. WHERE
  52. @id IS NOT NULL
  53. ) fnc
  54. JOIN tb_board_category bca ON fnc.brd_category_key = bca.brd_category_key
  55. AND board_id = ?
  56. LIMIT ?, ?";
  57. */
  58. $sql = 'CALL SP_BOARD_CATEGORY(?, ?, ?);';
  59. $params = [
  60. $boardID,
  61. (($page - 1) * $perPage),
  62. $perPage
  63. ];
  64. $list = $this->getPaginator(DB::select($sql, $params), $total, $perPage, $page);
  65. $row = $list->count();
  66. return (object)[
  67. 'total' => $total,
  68. 'rows' => $row,
  69. 'list' => $list
  70. ];
  71. }
  72. /**
  73. * 분류 목록 조회
  74. */
  75. public function getCategoryList(int $boardID): object
  76. {
  77. $total = DB::selectOne("SELECT COUNT(*) AS total FROM tb_board_category WHERE board_id = ?", [
  78. $boardID
  79. ])->total;
  80. $list = $this->where('board_id', $boardID)->withDepth()->defaultOrder()->get()->toTree();
  81. $rows = $list->count();
  82. return (object)[
  83. 'total' => $total,
  84. 'rows' => $rows,
  85. 'list' => $list
  86. ];
  87. }
  88. /**
  89. * 분류 조회
  90. */
  91. public function findCategory(int $categoryID): ?BoardCategory
  92. {
  93. return $this->newQuery()->find($categoryID);
  94. }
  95. /**
  96. * nested 분류 생성
  97. */
  98. public function register(array $params): bool
  99. {
  100. $parentID = $params['parent_id'];
  101. if (!$parentID) { // 부모 등록
  102. return (new BoardCategory($params))->save();
  103. } else { // 자식 등록
  104. return $this->findCategory($parentID)->appendNode(new BoardCategory($params));
  105. }
  106. }
  107. /**
  108. * 분류 수정
  109. */
  110. public function updater(array $params): bool
  111. {
  112. return $this->findCategory($params['id'])->update($params);
  113. }
  114. /**
  115. * 분류 삭제
  116. */
  117. public function remove(int $categoryID): int
  118. {
  119. return $this->destroy($categoryID);
  120. }
  121. /**
  122. * 분류 한 단계 위로
  123. */
  124. public function orderUp(int $categoryID): bool
  125. {
  126. return $this->findCategory($categoryID)->up();
  127. }
  128. /**
  129. * 분류 한 단계 아래로
  130. */
  131. public function orderDown(int $categoryID): bool
  132. {
  133. return $this->findCategory($categoryID)->down();
  134. }
  135. /**
  136. * 게시판 분류 조회
  137. */
  138. public function categories(int $boardID): object
  139. {
  140. $total = 0;
  141. $categories = $this->where('board_id', $boardID)->withDepth()->defaultOrder()->get()->toTree();
  142. if($categories->count() > 0) {
  143. foreach($categories as $i => $v) {
  144. $sql = '
  145. SELECT COUNT(*) AS `rows` FROM tb_post PST JOIN tb_board BRD ON BRD.id = PST.board_id
  146. WHERE 1
  147. AND BRD.id = ? AND BRD.is_display = 1 AND PST.board_category_id = ? AND PST.is_delete = 0;
  148. ';
  149. $total += $v->rows = DB::selectOne($sql, [$v->board_id, $v->board_category_id])->rows;
  150. $categories[$i] = $v;
  151. }
  152. }
  153. return (object)[
  154. 'total' => $total,
  155. 'list' => $categories
  156. ];
  157. }
  158. /**
  159. * 게시판 카테고리 PK 계산
  160. */
  161. public function nextKey(int $parentID, int $boardID): mixed
  162. {
  163. if ((string)$parentID === '0') {
  164. $result = $this->select('id')->where('board_id', $boardID)->get();
  165. $max = 0;
  166. foreach ($result as $key => $value) {
  167. $float = floatval($value->board_category_id);
  168. if ($float > $max) {
  169. $max = $float;
  170. }
  171. }
  172. return intval($max + 1);
  173. }
  174. if (strpos($parentID, '.') === false) {
  175. $result = $this->select('id')->where('board_id', $boardID)->where('id', 'like', $parentID . '.%')->get();
  176. $max = 0;
  177. foreach ($result as $key => $value) {
  178. $float = $value->board_category_id;
  179. if ($float > $max) {
  180. $max = $float;
  181. }
  182. }
  183. if ($max) {
  184. $keyExplode = explode('.', $max);
  185. $digit = substr($keyExplode[1], 0, 3) + 1;
  186. $ret = sprintf("%03d", $digit);
  187. return $keyExplode[0] . '.' . $ret;
  188. } else {
  189. return $parentID . '.001';
  190. }
  191. } else {
  192. $result = $this->select('id')->where('board_id', $boardID)->where('id', 'like', $parentID . '%')->get();
  193. $max = 0;
  194. foreach ($result as $key => $value) {
  195. $float = $value->board_category_id;
  196. if ($float > $max) {
  197. $max = $float;
  198. }
  199. }
  200. if ((string)$max === (string)$parentID) {
  201. return $parentID . '001';
  202. } else {
  203. $keyExplode = explode('.', $max);
  204. $parent_id_explode = explode('.', $parentID);
  205. $parent_idLen = strlen($parent_id_explode[1]);
  206. $digit = substr($keyExplode[1], 0, $parent_idLen + 3) + 1;
  207. $res = sprintf("%0" . ($parent_idLen + 3) . "d", $digit);
  208. return $keyExplode[0] . '.' . $res;
  209. }
  210. }
  211. }
  212. }