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

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