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

Размер файла: 11.38Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Http\Controllers;
  6.  
  7. use App\Classes\Validator;
  8. use App\Models\Comment;
  9. use App\Models\Flood;
  10. use App\Models\Offer;
  11. use Illuminate\Database\Query\JoinClause;
  12. use Illuminate\Http\RedirectResponse;
  13. use Illuminate\Http\Request;
  14. use Illuminate\View\View;
  15.  
  16. class OfferController extends Controller
  17. {
  18. /**
  19. * Главная страница
  20. *
  21. * @param Request $request
  22. * @param string $type
  23. *
  24. * @return View
  25. */
  26. public function index(Request $request, string $type = 'offer'): View
  27. {
  28. $offerCount = Offer::query()->where('type', Offer::OFFER)->count();
  29. $issueCount = Offer::query()->where('type', Offer::ISSUE)->count();
  30.  
  31. $sort = check($request->input('sort', 'rating'));
  32.  
  33. switch ($sort) {
  34. case 'time':
  35. $order = 'created_at';
  36. break;
  37. case 'status':
  38. $order = 'status';
  39. break;
  40. case 'comments':
  41. $order = 'count_comments';
  42. break;
  43. default:
  44. $order = 'rating';
  45. }
  46.  
  47. $offers = Offer::query()
  48. ->where('type', $type)
  49. ->orderByDesc($order)
  50. ->with('user')
  51. ->paginate(setting('postoffers'))
  52. ->appends(compact('type', 'sort'));
  53.  
  54. return view('offers/index', compact('offers', 'order', 'type', 'sort', 'offerCount', 'issueCount'));
  55. }
  56.  
  57. /**
  58. * Просмотр записи
  59. *
  60. * @param int $id
  61. *
  62. * @return View
  63. */
  64. public function view(int $id): View
  65. {
  66. $offer = Offer::query()
  67. ->select('offers.*', 'pollings.vote')
  68. ->where('offers.id', $id)
  69. ->leftJoin('pollings', static function (JoinClause $join) {
  70. $join->on('offers.id', 'pollings.relate_id')
  71. ->where('pollings.relate_type', Offer::$morphName)
  72. ->where('pollings.user_id', getUser('id'));
  73. })
  74. ->first();
  75.  
  76. if (! $offer) {
  77. abort(404, __('main.record_not_found'));
  78. }
  79.  
  80. return view('offers/view', compact('offer'));
  81. }
  82.  
  83. /**
  84. * Создание записи
  85. *
  86. * @param Request $request
  87. * @param Validator $validator
  88. * @param Flood $flood
  89. *
  90. * @return View|RedirectResponse
  91. */
  92. public function create(Request $request, Validator $validator, Flood $flood)
  93. {
  94. if (! $user = getUser()) {
  95. abort(403, __('main.not_authorized'));
  96. }
  97.  
  98. $type = $request->input('type');
  99.  
  100. if ($request->isMethod('post')) {
  101. $title = $request->input('title');
  102. $text = $request->input('text');
  103.  
  104. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  105. ->length($title, 3, 50, ['title' => __('validator.text')])
  106. ->length($text, 5, 1000, ['text' => __('validator.text')])
  107. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
  108. ->in($type, Offer::TYPES, ['type' => __('offers.type_invalid')])
  109. ->gte(getUser('point'), setting('addofferspoint'), __('offers.condition_add', ['point' => plural(setting('addofferspoint'), setting('scorename'))]));
  110.  
  111. if ($validator->isValid()) {
  112. $title = antimat($title);
  113. $text = antimat($text);
  114.  
  115. /** @var Offer $offer */
  116. $offer = Offer::query()->create([
  117. 'type' => $type,
  118. 'title' => $title,
  119. 'text' => $text,
  120. 'user_id' => $user->id,
  121. 'rating' => 1,
  122. 'status' => 'wait',
  123. 'created_at' => SITETIME,
  124. ]);
  125.  
  126. $flood->saveState();
  127.  
  128. setFlash('success', __('main.record_added_success'));
  129.  
  130. return redirect('offers/' . $offer->id);
  131. }
  132.  
  133. setInput($request->all());
  134. setFlash('danger', $validator->getErrors());
  135. }
  136.  
  137. return view('offers/create', compact('type'));
  138. }
  139.  
  140. /**
  141. * Редактирование записи
  142. *
  143. * @param int $id
  144. * @param Request $request
  145. * @param Validator $validator
  146. *
  147. * @return View|RedirectResponse
  148. */
  149. public function edit(int $id, Request $request, Validator $validator)
  150. {
  151. if (! $user = getUser()) {
  152. abort(403, __('main.not_authorized'));
  153. }
  154.  
  155. $offer = Offer::query()
  156. ->where('id', $id)
  157. ->where('user_id', $user->id)
  158. ->first();
  159.  
  160. if (! $offer) {
  161. abort(404, __('main.record_not_found'));
  162. }
  163.  
  164. if (! in_array($offer->status, ['wait', 'process'])) {
  165. abort(200, __('offers.already_resolved'));
  166. }
  167.  
  168. if ($request->isMethod('post')) {
  169. $title = $request->input('title');
  170. $text = $request->input('text');
  171. $type = $request->input('type');
  172.  
  173. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  174. ->length($title, 3, 50, ['title' => __('validator.text')])
  175. ->length($text, 5, 1000, ['text' => __('validator.text')])
  176. ->in($type, Offer::TYPES, ['type' => __('offers.type_invalid')]);
  177.  
  178. if ($validator->isValid()) {
  179. $title = antimat($title);
  180. $text = antimat($text);
  181.  
  182. $offer->update([
  183. 'type' => $type,
  184. 'title' => $title,
  185. 'text' => $text,
  186. 'updated_at' => SITETIME,
  187. ]);
  188.  
  189. setFlash('success', __('main.record_changed_success'));
  190.  
  191. return redirect('offers/' . $offer->id);
  192. }
  193.  
  194. setInput($request->all());
  195. setFlash('danger', $validator->getErrors());
  196. }
  197.  
  198. return view('offers/edit', compact('offer'));
  199. }
  200.  
  201. /**
  202. * Комментарии
  203. *
  204. * @param int $id
  205. * @param Request $request
  206. * @param Validator $validator
  207. * @param Flood $flood
  208. *
  209. * @return View|RedirectResponse
  210. */
  211. public function comments(int $id, Request $request, Validator $validator, Flood $flood)
  212. {
  213. /** @var Offer $offer */
  214. $offer = Offer::query()->find($id);
  215.  
  216. if (! $offer) {
  217. abort(404, __('main.record_not_found'));
  218. }
  219.  
  220. if ($request->isMethod('post')) {
  221. $msg = $request->input('msg');
  222.  
  223. $validator
  224. ->true(getUser(), __('main.not_authorized'))
  225. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  226. ->length($msg, 5, setting('comment_length'), ['msg' => __('validator.text')])
  227. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
  228. ->empty($offer->closed, ['msg' => __('offers.offer_closed')]);
  229.  
  230. if ($validator->isValid()) {
  231. $msg = antimat($msg);
  232.  
  233. /** @var Comment $comment */
  234. $comment = $offer->comments()->create([
  235. 'text' => $msg,
  236. 'user_id' => getUser('id'),
  237. 'created_at' => SITETIME,
  238. 'ip' => getIp(),
  239. 'brow' => getBrowser(),
  240. ]);
  241.  
  242. $user = getUser();
  243. $user->increment('allcomments');
  244. $user->increment('point');
  245. $user->increment('money', 5);
  246.  
  247. $offer->increment('count_comments');
  248.  
  249. $flood->saveState();
  250. sendNotify($msg, '/offers/comment/' . $offer->id . '/' . $comment->id, $offer->title);
  251.  
  252. setFlash('success', __('main.comment_added_success'));
  253.  
  254. return redirect('offers/end/' . $offer->id);
  255. }
  256.  
  257. setInput($request->all());
  258. setFlash('danger', $validator->getErrors());
  259. }
  260.  
  261. $comments = $offer->comments()
  262. ->orderBy('created_at')
  263. ->paginate(setting('comments_per_page'));
  264.  
  265. return view('offers/comments', compact('offer', 'comments'));
  266. }
  267.  
  268. /**
  269. * Подготовка к редактированию комментария
  270. *
  271. * @param int $id
  272. * @param int $cid
  273. * @param Request $request
  274. * @param Validator $validator
  275. *
  276. * @return View|RedirectResponse
  277. */
  278. public function editComment(int $id, int $cid, Request $request, Validator $validator)
  279. {
  280. $page = int($request->input('page', 1));
  281.  
  282. /** @var Offer $offer */
  283. $offer = Offer::query()->find($id);
  284.  
  285. if (! $offer) {
  286. abort(404, __('main.record_not_found'));
  287. }
  288.  
  289. if (! getUser()) {
  290. abort(403, __('main.not_authorized'));
  291. }
  292.  
  293. $comment = $offer->comments()
  294. ->where('id', $cid)
  295. ->where('user_id', getUser('id'))
  296. ->first();
  297.  
  298. if (! $comment) {
  299. abort(200, __('main.comment_deleted'));
  300. }
  301.  
  302. if ($comment->created_at + 600 < SITETIME) {
  303. abort(200, __('main.editing_impossible'));
  304. }
  305.  
  306. if ($request->isMethod('post')) {
  307. $msg = $request->input('msg');
  308. $page = int($request->input('page', 1));
  309.  
  310. $validator
  311. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  312. ->length($msg, 5, setting('comment_length'), ['msg' => __('validator.text')]);
  313.  
  314. if ($validator->isValid()) {
  315. $msg = antimat($msg);
  316.  
  317. $comment->update([
  318. 'text' => $msg,
  319. ]);
  320.  
  321. setFlash('success', __('main.comment_edited_success'));
  322.  
  323. return redirect('offers/comments/' . $offer->id . '?page=' . $page);
  324. }
  325.  
  326. setInput($request->all());
  327. setFlash('danger', $validator->getErrors());
  328. }
  329.  
  330. return view('offers/editcomment', compact('offer', 'comment', 'page'));
  331. }
  332.  
  333. /**
  334. * Переадресация на последнюю страницу
  335. *
  336. * @param int $id
  337. *
  338. * @return RedirectResponse
  339. */
  340. public function end(int $id): RedirectResponse
  341. {
  342. /** @var Offer $offer */
  343. $offer = Offer::query()->find($id);
  344.  
  345. if (! $offer) {
  346. abort(404, __('main.record_not_found'));
  347. }
  348.  
  349. $total = $offer->comments()->count();
  350.  
  351. $end = ceil($total / setting('comments_per_page'));
  352.  
  353. return redirect('offers/comments/' . $offer->id . '?page=' . $end);
  354. }
  355.  
  356. /**
  357. * Переход к сообщению
  358. *
  359. * @param int $id
  360. * @param int $cid
  361. *
  362. * @return RedirectResponse
  363. */
  364. public function viewComment(int $id, int $cid): RedirectResponse
  365. {
  366. /** @var Offer $offer */
  367. $offer = Offer::query()->find($id);
  368.  
  369. if (! $offer) {
  370. abort(404, __('main.record_not_found'));
  371. }
  372.  
  373. $total = $offer->comments()
  374. ->where('id', '<=', $cid)
  375. ->orderBy('created_at')
  376. ->count();
  377.  
  378. $end = ceil($total / setting('comments_per_page'));
  379.  
  380. return redirect('offers/comments/' . $offer->id . '?page=' . $end . '#comment_' . $cid);
  381. }
  382. }