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

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