You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
5.8KB

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers;
  4. use App\Models\Board;
  5. use App\Repositories\BoardColumnRepository;
  6. use App\Repositories\BoardRepository;
  7. use App\Repositories\CardRepository;
  8. use App\Repositories\SwimLaneRepository;
  9. use App\Services\AuthService;
  10. use Core\Controller;
  11. use Core\Request;
  12. class BoardsController extends Controller
  13. {
  14. private function boards(): BoardRepository
  15. {
  16. return new BoardRepository(database());
  17. }
  18. private function columns(): BoardColumnRepository
  19. {
  20. return new BoardColumnRepository(database());
  21. }
  22. private function lanes(): SwimLaneRepository
  23. {
  24. return new SwimLaneRepository(database());
  25. }
  26. private function cards(): CardRepository
  27. {
  28. return new CardRepository(database());
  29. }
  30. public function index(): mixed
  31. {
  32. if ($guard = AuthService::requireLogin()) {
  33. return $guard;
  34. }
  35. $boards = $this->boards()->getAll();
  36. return $this->view('boards.index', [
  37. 'pageTitle' => 'Boards',
  38. 'boards' => $boards,
  39. ]);
  40. }
  41. public function create(): mixed
  42. {
  43. if ($guard = AuthService::requireLogin()) {
  44. return $guard;
  45. }
  46. return $this->view('boards.create', ['pageTitle' => 'New Board']);
  47. }
  48. public function store(Request $request): mixed
  49. {
  50. if ($guard = AuthService::requireLogin()) {
  51. return $guard;
  52. }
  53. $name = trim((string) $request->input('name', ''));
  54. if ($name === '') {
  55. return $this->view('boards.create', [
  56. 'pageTitle' => 'New Board',
  57. 'error' => 'Board name is required.',
  58. 'old' => $request->all(),
  59. ]);
  60. }
  61. $username = AuthService::getCurrentUsername();
  62. $now = date('Y-m-d H:i:s');
  63. $board = new Board();
  64. $board->name = $name;
  65. $board->slug = $this->boards()->uniqueSlug($this->generateSlug($name));
  66. $board->importFromPrintstream = $request->input('import_from_printstream') === 'on';
  67. $board->printstreamJobName = trim((string) $request->input('printstream_job_name', ''));
  68. $board->createdAt = $now;
  69. $board->createdBy = $username;
  70. $board->updatedAt = $now;
  71. $board->updatedBy = $username;
  72. $this->boards()->insert($board);
  73. return $this->redirect('/board/' . $board->slug);
  74. }
  75. public function show(string $slug): mixed
  76. {
  77. if ($guard = AuthService::requireLogin()) {
  78. return $guard;
  79. }
  80. $board = $this->boards()->findBySlug($slug);
  81. if ($board === null) {
  82. return \Core\Response::notFound('Board not found.');
  83. }
  84. $columns = $this->columns()->findByBoardId($board->id);
  85. $lanes = $this->lanes()->findByBoardId($board->id);
  86. $allCards = $this->cards()->findByBoardId($board->id);
  87. $cardsJson = json_encode(
  88. array_map(fn($c) => $c->toJsonArray(), $allCards),
  89. JSON_THROW_ON_ERROR
  90. );
  91. return $this->fragment('boards.show', [
  92. 'board' => $board,
  93. 'columns' => $columns,
  94. 'lanes' => $lanes,
  95. 'cardsJson' => $cardsJson,
  96. ]);
  97. }
  98. public function edit(string $slug): mixed
  99. {
  100. if ($guard = AuthService::requireLogin()) {
  101. return $guard;
  102. }
  103. $board = $this->boards()->findBySlug($slug);
  104. if ($board === null) {
  105. return \Core\Response::notFound('Board not found.');
  106. }
  107. return $this->view('boards.edit', [
  108. 'pageTitle' => 'Edit Board',
  109. 'board' => $board,
  110. ]);
  111. }
  112. public function update(Request $request, string $slug): mixed
  113. {
  114. if ($guard = AuthService::requireLogin()) {
  115. return $guard;
  116. }
  117. $board = $this->boards()->findBySlug($slug);
  118. if ($board === null) {
  119. return \Core\Response::notFound('Board not found.');
  120. }
  121. $newName = trim((string) $request->input('name', ''));
  122. if ($newName === '') {
  123. return $this->view('boards.edit', [
  124. 'pageTitle' => 'Edit Board',
  125. 'board' => $board,
  126. 'error' => 'Board name is required.',
  127. ]);
  128. }
  129. $board->name = $newName;
  130. $board->slug = $this->boards()->uniqueSlug($this->generateSlug($newName), $board->id);
  131. $board->importFromPrintstream = $request->input('import_from_printstream') === 'on';
  132. $board->printstreamJobName = trim((string) $request->input('printstream_job_name', ''));
  133. $board->updatedAt = date('Y-m-d H:i:s');
  134. $board->updatedBy = AuthService::getCurrentUsername();
  135. $this->boards()->update($board);
  136. return $this->redirect('/board/' . $board->slug);
  137. }
  138. public function destroy(string $slug): mixed
  139. {
  140. if ($guard = AuthService::requireLogin()) {
  141. return $guard;
  142. }
  143. $board = $this->boards()->findBySlug($slug);
  144. if ($board === null) {
  145. return $this->redirect('/boards');
  146. }
  147. $this->cards()->deleteByBoardId($board->id);
  148. $this->columns()->deleteByBoardId($board->id);
  149. $this->lanes()->deleteByBoardId($board->id);
  150. $this->boards()->delete($board->id);
  151. return $this->redirect('/boards');
  152. }
  153. private function generateSlug(string $text): string
  154. {
  155. $slug = strtolower($text);
  156. $slug = preg_replace('/[^a-z0-9\s-]/', '', $slug) ?? $slug;
  157. $slug = preg_replace('/[\s-]+/', '-', trim($slug)) ?? $slug;
  158. return trim($slug, '-');
  159. }
  160. }

Powered by TurnKey Linux.