Просмотр файла app/Controllers/BoardController.php

Размер файла: 10.78Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Controllers;
  6.  
  7. use App\Classes\Validator;
  8. use App\Models\Board;
  9. use App\Models\File;
  10. use App\Models\Flood;
  11. use App\Models\Item;
  12. use Exception;
  13. use Illuminate\Database\Eloquent\Builder;
  14. use Illuminate\Http\Request;
  15.  
  16. class BoardController extends BaseController
  17. {
  18. /**
  19. * Главная страница
  20. *
  21. * @param int $id
  22. *
  23. * @return string
  24. */
  25. public function index(int $id = null): string
  26. {
  27. $board = null;
  28.  
  29. if ($id) {
  30. /** @var Board $board */
  31. $board = Board::query()->find($id);
  32.  
  33. if (! $board) {
  34. abort(404, __('boards.category_not_exist'));
  35. }
  36. }
  37.  
  38. $items = Item::query()
  39. ->when($board, static function (Builder $query) use ($board) {
  40. return $query->where('board_id', $board->id);
  41. })
  42. ->where('expires_at', '>', SITETIME)
  43. ->orderByDesc('updated_at')
  44. ->with('category', 'user', 'files')
  45. ->paginate(Item::BOARD_PAGINATE);
  46.  
  47. $boards = Board::query()
  48. ->where('parent_id', $board->id ?? 0)
  49. ->get();
  50.  
  51. return view('boards/index', compact('items', 'board', 'boards'));
  52. }
  53.  
  54. /**
  55. * Просмотр объявления
  56. *
  57. * @param int $id
  58. *
  59. * @return string
  60. */
  61. public function view(int $id): string
  62. {
  63. /** @var Item $item */
  64. $item = Item::query()
  65. ->with('category')
  66. ->find($id);
  67.  
  68. if (! $item) {
  69. abort(404, __('boards.item_not_exist'));
  70. }
  71.  
  72. if ($item->expires_at <= SITETIME && getUser() && getUser('id') !== $item->user_id) {
  73. abort('default', __('boards.item_not_active'));
  74. }
  75.  
  76. return view('boards/view', compact('item'));
  77. }
  78.  
  79. /**
  80. * Создание объявления
  81. *
  82. * @param Request $request
  83. * @param Validator $validator
  84. * @param Flood $flood
  85. *
  86. * @return string
  87. */
  88. public function create(Request $request, Validator $validator, Flood $flood): string
  89. {
  90. $bid = int($request->input('bid'));
  91.  
  92. if (! $user = getUser()) {
  93. abort(403);
  94. }
  95.  
  96. $boards = Board::query()
  97. ->where('parent_id', 0)
  98. ->with('children')
  99. ->orderBy('sort')
  100. ->get();
  101.  
  102. if ($boards->isEmpty()) {
  103. abort('default', __('boards.categories_not_created'));
  104. }
  105.  
  106. if ($request->isMethod('post')) {
  107. $title = $request->input('title');
  108. $text = $request->input('text');
  109. $price = int($request->input('price'));
  110. $phone = preg_replace('/\D/', '', $request->input('phone'));
  111.  
  112. /** @var Board $board */
  113. $board = Board::query()->find($bid);
  114.  
  115. $validator
  116. ->equal($request->input('token'), $_SESSION['token'], __('validator.token'))
  117. ->length($title, 3, 50, ['title' => __('validator.text')])
  118. ->length($text, 50, 5000, ['text' => __('validator.text')])
  119. ->phone($phone, ['phone' => __('validator.phone')], false)
  120. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
  121. ->notEmpty($board, ['category' => __('boards.category_not_exist')]);
  122.  
  123. if ($board) {
  124. $validator->empty($board->closed, ['category' => __('boards.category_closed')]);
  125. }
  126.  
  127. if ($validator->isValid()) {
  128. /** @var Item $item */
  129. $item = Item::query()->create([
  130. 'board_id' => $board->id,
  131. 'title' => $title,
  132. 'text' => $text,
  133. 'user_id' => $user->id,
  134. 'price' => $price,
  135. 'phone' => $phone,
  136. 'created_at' => SITETIME,
  137. 'updated_at' => SITETIME,
  138. 'expires_at' => strtotime('+1 month', SITETIME),
  139. ]);
  140.  
  141. $item->category->increment('count_items');
  142.  
  143. File::query()
  144. ->where('relate_type', Item::$morphName)
  145. ->where('relate_id', 0)
  146. ->where('user_id', $user->id)
  147. ->update(['relate_id' => $item->id]);
  148.  
  149. clearCache(['statBoards', 'recentBoards']);
  150. $flood->saveState();
  151.  
  152. setFlash('success', __('boards.item_success_added'));
  153. redirect('/items/' . $item->id);
  154. } else {
  155. setInput($request->all());
  156. setFlash('danger', $validator->getErrors());
  157. }
  158. }
  159.  
  160. $files = File::query()
  161. ->where('relate_type', Item::$morphName)
  162. ->where('relate_id', 0)
  163. ->where('user_id', $user->id)
  164. ->get();
  165.  
  166. return view('boards/create', compact('boards', 'bid', 'files'));
  167. }
  168.  
  169. /**
  170. * Редактирование объявления
  171. *
  172. * @param int $id
  173. * @param Request $request
  174. * @param Validator $validator
  175. *
  176. * @return string
  177. */
  178. public function edit(int $id, Request $request, Validator $validator): string
  179. {
  180. if (! $user = getUser()) {
  181. abort(403, __('main.not_authorized'));
  182. }
  183.  
  184. /** @var Item $item */
  185. $item = Item::query()->find($id);
  186.  
  187. if (! $item) {
  188. abort(404, __('boards.item_not_exist'));
  189. }
  190.  
  191. if ($request->isMethod('post')) {
  192. $bid = int($request->input('bid'));
  193. $title = $request->input('title');
  194. $text = $request->input('text');
  195. $price = int($request->input('price'));
  196. $phone = preg_replace('/\D/', '', $request->input('phone'));
  197.  
  198. /** @var Board $board */
  199. $board = Board::query()->find($bid);
  200.  
  201. $validator
  202. ->equal($request->input('token'), $_SESSION['token'], __('validator.token'))
  203. ->length($title, 3, 50, ['title' => __('validator.text')])
  204. ->length($text, 50, 5000, ['text' => __('validator.text')])
  205. ->phone($phone, ['phone' => __('validator.phone')], false)
  206. ->notEmpty($board, ['category' => __('boards.category_not_exist')])
  207. ->equal($item->user_id, $user->id, __('boards.item_not_author'));
  208.  
  209. if ($board) {
  210. $validator->empty($board->closed, ['category' => __('boards.category_closed')]);
  211. }
  212.  
  213. if ($validator->isValid()) {
  214. // Обновление счетчиков
  215. if ($item->board_id !== $board->id) {
  216. $board->increment('count_items');
  217. Board::query()->where('id', $item->board_id)->decrement('count_items');
  218. }
  219.  
  220. $item->update([
  221. 'board_id' => $board->id,
  222. 'title' => $title,
  223. 'text' => $text,
  224. 'price' => $price,
  225. 'phone' => $phone,
  226. ]);
  227.  
  228. clearCache(['statBoards', 'recentBoards']);
  229. setFlash('success', __('boards.item_success_edited'));
  230. redirect('/items/' . $item->id);
  231. } else {
  232. setInput($request->all());
  233. setFlash('danger', $validator->getErrors());
  234. }
  235. }
  236.  
  237. $boards = Board::query()
  238. ->where('parent_id', 0)
  239. ->with('children')
  240. ->orderBy('sort')
  241. ->get();
  242.  
  243. return view('boards/edit', compact('item', 'boards'));
  244. }
  245.  
  246. /**
  247. * Снятие / Публикация объявления
  248. *
  249. * @param int $id
  250. * @param Request $request
  251. * @param Validator $validator
  252. */
  253. public function close(int $id, Request $request, Validator $validator): void
  254. {
  255. if (! $user = getUser()) {
  256. abort(403, __('main.not_authorized'));
  257. }
  258.  
  259. /** @var Item $item */
  260. $item = Item::query()->find($id);
  261.  
  262. if (! $item) {
  263. abort(404, __('boards.item_not_exist'));
  264. }
  265.  
  266. $validator->equal($request->input('token'), $_SESSION['token'], __('validator.token'))
  267. ->equal($item->user_id, $user->id, __('boards.item_not_author'));
  268.  
  269. if ($validator->isValid()) {
  270. if ($item->expires_at > SITETIME) {
  271. $status = __('boards.item_success_unpublished');
  272. $item->update([
  273. 'expires_at' => SITETIME,
  274. ]);
  275.  
  276. $item->category->decrement('count_items');
  277. } else {
  278. $status = __('boards.item_success_published');
  279. $expired = strtotime('+1 month', $item->updated_at) <= SITETIME;
  280.  
  281. $item->update([
  282. 'expires_at' => strtotime('+1 month', SITETIME),
  283. 'updated_at' => $expired ? SITETIME : $item->updated_at,
  284. ]);
  285.  
  286. $item->category->increment('count_items');
  287. }
  288.  
  289. setFlash('success', $status);
  290. } else {
  291. setFlash('danger', $validator->getErrors());
  292. }
  293.  
  294. redirect('/items/edit/' . $item->id);
  295. }
  296.  
  297. /**
  298. * Удаление объявления
  299. *
  300. * @param int $id
  301. * @param Request $request
  302. * @param Validator $validator
  303. *
  304. * @throws Exception
  305. */
  306. public function delete(int $id, Request $request, Validator $validator): void
  307. {
  308. if (! $user = getUser()) {
  309. abort(403, __('main.not_authorized'));
  310. }
  311.  
  312. /** @var Item $item */
  313. $item = Item::query()->find($id);
  314.  
  315. if (! $item) {
  316. abort(404, __('boards.item_not_exist'));
  317. }
  318.  
  319. $validator->equal($request->input('token'), $_SESSION['token'], __('validator.token'))
  320. ->equal($item->user_id, $user->id, __('boards.item_not_author'));
  321.  
  322. if ($validator->isValid()) {
  323. $item->delete();
  324.  
  325. $item->category->decrement('count_items');
  326.  
  327. clearCache(['statBoards', 'recentBoards']);
  328. setFlash('success', __('boards.item_success_deleted'));
  329. } else {
  330. setFlash('danger', $validator->getErrors());
  331. }
  332.  
  333. redirect('/boards/' . $item->board_id);
  334. }
  335.  
  336. /**
  337. * Мои объявления
  338. *
  339. * @return string
  340. */
  341. public function active(): string
  342. {
  343. if (! $user = getUser()) {
  344. abort(403, __('main.not_authorized'));
  345. }
  346.  
  347. $items = Item::query()
  348. ->where('user_id', $user->id)
  349. ->orderByDesc('updated_at')
  350. ->with('category', 'user', 'files')
  351. ->paginate(Item::BOARD_PAGINATE);
  352.  
  353. return view('boards/active', compact('items'));
  354. }
  355. }