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

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