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

Размер файла: 15.54Kb
  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\File;
  10. use App\Models\Flood;
  11. use App\Models\Photo;
  12. use Exception;
  13. use Illuminate\Database\Query\JoinClause;
  14. use Illuminate\Http\RedirectResponse;
  15. use Illuminate\Http\Request;
  16. use Illuminate\View\View;
  17.  
  18. class PhotoController extends Controller
  19. {
  20. /**
  21. * Главная страница
  22. *
  23. * @return View
  24. */
  25. public function index(): View
  26. {
  27. $photos = Photo::query()
  28. ->select('photos.*', 'pollings.vote')
  29. ->leftJoin('pollings', static function (JoinClause $join) {
  30. $join->on('photos.id', 'pollings.relate_id')
  31. ->where('pollings.relate_type', Photo::$morphName)
  32. ->where('pollings.user_id', getUser('id'));
  33. })
  34. ->orderByDesc('created_at')
  35. ->with('user', 'files')
  36. ->paginate(setting('fotolist'));
  37.  
  38. return view('photos/index', compact('photos'));
  39. }
  40.  
  41. /**
  42. * Просмотр полной фотографии
  43. *
  44. * @param int $id
  45. *
  46. * @return View
  47. */
  48. public function view(int $id): View
  49. {
  50. $photo = Photo::query()
  51. ->select('photos.*', 'pollings.vote')
  52. ->where('photos.id', $id)
  53. ->leftJoin('pollings', static function (JoinClause $join) {
  54. $join->on('photos.id', 'pollings.relate_id')
  55. ->where('pollings.relate_type', Photo::$morphName)
  56. ->where('pollings.user_id', getUser('id'));
  57. })
  58. ->with('user')
  59. ->first();
  60.  
  61. if (! $photo) {
  62. abort(404, __('photos.photo_not_exist'));
  63. }
  64.  
  65. return view('photos/view', compact('photo'));
  66. }
  67.  
  68. /**
  69. * Форма загрузки фото
  70. *
  71. * @param Request $request
  72. * @param Validator $validator
  73. * @param Flood $flood
  74. *
  75. * @return View|RedirectResponse
  76. */
  77. public function create(Request $request, Validator $validator, Flood $flood)
  78. {
  79. if (! $user = getUser()) {
  80. abort(403, __('main.not_authorized'));
  81. }
  82.  
  83. if ($request->isMethod('post')) {
  84. $title = $request->input('title');
  85. $text = $request->input('text');
  86. $closed = empty($request->input('closed')) ? 0 : 1;
  87.  
  88. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  89. ->length($title, 3, 50, ['title' => __('validator.text')])
  90. ->length($text, 0, 1000, ['text' => __('validator.text_long')])
  91. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])]);
  92.  
  93. $existFiles = File::query()
  94. ->where('relate_type', Photo::$morphName)
  95. ->where('relate_id', 0)
  96. ->where('user_id', $user->id)
  97. ->exists();
  98. $validator->true($existFiles, ['files' => __('validator.image_upload_failed')]);
  99.  
  100. if ($validator->isValid()) {
  101. /** @var Photo $photo */
  102. $photo = Photo::query()->create([
  103. 'user_id' => $user->id,
  104. 'title' => $title,
  105. 'text' => antimat($text),
  106. 'created_at' => SITETIME,
  107. 'closed' => $closed,
  108. ]);
  109.  
  110. File::query()
  111. ->where('relate_type', Photo::$morphName)
  112. ->where('relate_id', 0)
  113. ->where('user_id', $user->id)
  114. ->update(['relate_id' => $photo->id]);
  115.  
  116. clearCache(['statPhotos', 'recentPhotos']);
  117. $flood->saveState();
  118.  
  119. setFlash('success', __('photos.photo_success_uploaded'));
  120.  
  121. return redirect('photos/' . $photo->id);
  122. }
  123.  
  124. setInput($request->all());
  125. setFlash('danger', $validator->getErrors());
  126. }
  127.  
  128. $files = File::query()
  129. ->where('relate_type', Photo::$morphName)
  130. ->where('relate_id', 0)
  131. ->where('user_id', $user->id)
  132. ->get();
  133.  
  134. return view('photos/create', compact('files'));
  135. }
  136.  
  137. /**
  138. * Редактирование фото
  139. *
  140. * @param int $id
  141. * @param Request $request
  142. * @param Validator $validator
  143. *
  144. * @return View|RedirectResponse
  145. */
  146. public function edit(int $id, Request $request, Validator $validator)
  147. {
  148. $page = int($request->input('page', 1));
  149.  
  150. if (! $user = getUser()) {
  151. abort(403, __('main.not_authorized'));
  152. }
  153.  
  154. /** @var Photo $photo */
  155. $photo = Photo::query()->where('user_id', $user->id)->find($id);
  156.  
  157. if (! $photo) {
  158. abort(404, __('photos.photo_not_author'));
  159. }
  160.  
  161. if ($request->isMethod('post')) {
  162. $title = $request->input('title');
  163. $text = $request->input('text');
  164. $closed = empty($request->input('closed')) ? 0 : 1;
  165.  
  166. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  167. ->length($title, 3, 50, ['title' => __('validator.text')])
  168. ->length($text, 0, 1000, ['text' => __('validator.text_long')]);
  169.  
  170. if ($validator->isValid()) {
  171. $text = antimat($text);
  172.  
  173. $photo->update([
  174. 'title' => $title,
  175. 'text' => $text,
  176. 'closed' => $closed,
  177. ]);
  178.  
  179. setFlash('success', __('photos.photo_success_edited'));
  180. return redirect('photos/albums/' . $user->login . '?page=' . $page);
  181. }
  182.  
  183. setInput($request->all());
  184. setFlash('danger', $validator->getErrors());
  185. }
  186.  
  187. $checked = $photo->closed ? ' checked' : '';
  188.  
  189. return view('photos/edit', compact('photo', 'checked', 'page'));
  190. }
  191.  
  192. /**
  193. * Список комментариев
  194. *
  195. * @param int $id
  196. * @param Request $request
  197. * @param Validator $validator
  198. * @param Flood $flood
  199. *
  200. * @return View|RedirectResponse
  201. */
  202. public function comments(int $id, Request $request, Validator $validator, Flood $flood)
  203. {
  204. /** @var Photo $photo */
  205. $photo = Photo::query()->find($id);
  206.  
  207. if (! $photo) {
  208. abort(404, __('photos.photo_not_exist'));
  209. }
  210.  
  211. if ($request->isMethod('post')) {
  212. $user = getUser();
  213. $msg = $request->input('msg');
  214.  
  215. $validator
  216. ->true($user, __('main.not_authorized'))
  217. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  218. ->length($msg, 5, setting('comment_length'), ['msg' => __('validator.text')])
  219. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
  220. ->empty($photo->closed, ['msg' => __('main.closed_comments')]);
  221.  
  222. if ($validator->isValid()) {
  223. $msg = antimat($msg);
  224.  
  225. /** @var Comment $comment */
  226. $comment = $photo->comments()->create([
  227. 'text' => $msg,
  228. 'user_id' => $user->id,
  229. 'created_at' => SITETIME,
  230. 'ip' => getIp(),
  231. 'brow' => getBrowser(),
  232. ]);
  233.  
  234. $user->increment('allcomments');
  235. $user->increment('point');
  236. $user->increment('money', 5);
  237.  
  238. $photo->increment('count_comments');
  239.  
  240. $flood->saveState();
  241. sendNotify($msg, '/photos/comment/' . $photo->id . '/' . $comment->id, $photo->title);
  242.  
  243. setFlash('success', __('main.comment_added_success'));
  244.  
  245. return redirect('photos/end/' . $photo->id);
  246. }
  247.  
  248. setInput($request->all());
  249. setFlash('danger', $validator->getErrors());
  250. }
  251.  
  252. $comments = $photo->comments()
  253. ->orderBy('created_at')
  254. ->with('user')
  255. ->paginate(setting('comments_per_page'));
  256.  
  257. return view('photos/comments', compact('photo', 'comments'));
  258. }
  259.  
  260. /**
  261. * Редактирование комментария
  262. *
  263. * @param int $id
  264. * @param int $cid
  265. * @param Request $request
  266. * @param Validator $validator
  267. *
  268. * @return View|RedirectResponse
  269. */
  270. public function editComment(int $id, int $cid, Request $request, Validator $validator)
  271. {
  272. $page = int($request->input('page', 1));
  273.  
  274. if (! $user = getUser()) {
  275. abort(403, __('main.not_authorized'));
  276. }
  277.  
  278. /** @var Photo $photo */
  279. $photo = Photo::query()->find($id);
  280.  
  281. if (! $photo) {
  282. abort(404, __('photos.photo_not_exist'));
  283. }
  284.  
  285. $comment = $photo->comments()
  286. ->where('id', $cid)
  287. ->where('user_id', $user->id)
  288. ->first();
  289.  
  290. if (! $comment) {
  291. abort(200, __('main.comment_deleted'));
  292. }
  293.  
  294. if ($comment->created_at + 600 < SITETIME) {
  295. abort(200, __('main.editing_impossible'));
  296. }
  297.  
  298. if ($request->isMethod('post')) {
  299. $msg = $request->input('msg');
  300.  
  301. $validator
  302. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  303. ->length($msg, 5, setting('comment_length'), ['msg' => __('validator.text')])
  304. ->empty($photo->closed, __('main.closed_comments'));
  305.  
  306. if ($validator->isValid()) {
  307. $msg = antimat($msg);
  308.  
  309. $comment->update([
  310. 'text' => $msg,
  311. ]);
  312.  
  313. setFlash('success', __('main.comment_edited_success'));
  314.  
  315. return redirect('photos/comments/' . $photo->id . '?page=' . $page);
  316. }
  317.  
  318. setInput($request->all());
  319. setFlash('danger', $validator->getErrors());
  320. }
  321. return view('photos/editcomment', compact('photo', 'comment', 'page'));
  322. }
  323.  
  324. /**
  325. * Удаление фотографий
  326. *
  327. * @param int $id
  328. * @param Request $request
  329. * @param Validator $validator
  330. *
  331. * @return RedirectResponse
  332. * @throws Exception
  333. */
  334. public function delete(int $id, Request $request, Validator $validator): RedirectResponse
  335. {
  336. $page = int($request->input('page', 1));
  337.  
  338. if (! $user = getUser()) {
  339. abort(403, __('main.not_authorized'));
  340. }
  341.  
  342. /** @var Photo $photo */
  343. $photo = Photo::query()->where('user_id', $user->id)->find($id);
  344.  
  345. if (! $photo) {
  346. abort(404, __('photos.photo_not_author'));
  347. }
  348.  
  349. $validator
  350. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  351. ->empty($photo->count_comments, __('photos.photo_has_comments'));
  352.  
  353. if ($validator->isValid()) {
  354. $photo->comments()->delete();
  355. $photo->delete();
  356.  
  357. setFlash('success', __('photos.photo_success_deleted'));
  358. } else {
  359. setFlash('danger', $validator->getErrors());
  360. }
  361.  
  362. return redirect('photos/albums/' . $user->login . '?page=' . $page);
  363. }
  364.  
  365. /**
  366. * Переадресация на последнюю страницу
  367. *
  368. * @param int $id
  369. *
  370. * @return RedirectResponse
  371. */
  372. public function end(int $id): RedirectResponse
  373. {
  374. /** @var Photo $photo */
  375. $photo = Photo::query()->find($id);
  376.  
  377. if (! $photo) {
  378. abort(404, __('photos.photo_not_exist'));
  379. }
  380.  
  381. $total = $photo->comments()->count();
  382.  
  383. $end = ceil($total / setting('comments_per_page'));
  384. return redirect('photos/comments/' . $photo->id . '?page=' . $end);
  385. }
  386.  
  387. /**
  388. * Альбомы пользователей
  389. *
  390. * @return View
  391. */
  392. public function albums(): View
  393. {
  394. $albums = Photo::query()
  395. ->select('user_id', 'login')
  396. ->selectRaw('count(*) as cnt, sum(count_comments) as count_comments')
  397. ->join('users', 'photos.user_id', 'users.id')
  398. ->groupBy('user_id')
  399. ->orderByDesc('cnt')
  400. ->paginate(setting('photogroup'));
  401.  
  402. return view('photos/albums', compact('albums'));
  403. }
  404.  
  405. /**
  406. * Альбом пользователя
  407. *
  408. * @param string $login
  409. *
  410. * @return View
  411. */
  412. public function album(string $login): View
  413. {
  414. $user = getUserByLogin($login);
  415.  
  416. if (! $user) {
  417. abort(404, __('validator.user'));
  418. }
  419.  
  420. $photos = Photo::query()
  421. ->where('user_id', $user->id)
  422. ->orderByDesc('created_at')
  423. ->with('user')
  424. ->paginate(setting('fotolist'));
  425.  
  426. $moder = getUser() && getUser('id') === $user->id ? 1 : 0;
  427.  
  428. return view('photos/user_albums', compact('photos', 'moder', 'user'));
  429. }
  430.  
  431. /**
  432. * Альбом пользователя
  433. *
  434. * @param Request $request
  435. *
  436. * @return View
  437. */
  438. public function top(Request $request): View
  439. {
  440. $sort = check($request->input('sort', 'rating'));
  441.  
  442. if ($sort === 'comments') {
  443. $order = 'count_comments';
  444. } else {
  445. $order = 'rating';
  446. }
  447.  
  448. $photos = Photo::query()
  449. ->orderByDesc($order)
  450. ->with('user')
  451. ->paginate(setting('fotolist'))
  452. ->appends(['sort' => $sort]);
  453.  
  454. return view('photos/top', compact('photos', 'order'));
  455. }
  456.  
  457. /**
  458. * Выводит все комментарии
  459. *
  460. * @return View
  461. */
  462. public function allComments(): View
  463. {
  464. $comments = Comment::query()
  465. ->select('comments.*', 'title')
  466. ->where('relate_type', Photo::$morphName)
  467. ->leftJoin('photos', 'comments.relate_id', 'photos.id')
  468. ->orderByDesc('comments.created_at')
  469. ->with('user')
  470. ->paginate(setting('comments_per_page'));
  471.  
  472. return view('photos/all_comments', compact('comments'));
  473. }
  474.  
  475. /**
  476. * Выводит комментарии пользователя
  477. *
  478. * @param string $login
  479. *
  480. * @return View
  481. */
  482. public function UserComments(string $login): View
  483. {
  484. $user = getUserByLogin($login);
  485.  
  486. if (! $user) {
  487. abort(404, __('validator.user'));
  488. }
  489.  
  490. $comments = Comment::query()
  491. ->select('comments.*', 'title')
  492. ->where('relate_type', Photo::$morphName)
  493. ->where('comments.user_id', $user->id)
  494. ->leftJoin('photos', 'comments.relate_id', 'photos.id')
  495. ->orderByDesc('comments.created_at')
  496. ->with('user')
  497. ->paginate(setting('comments_per_page'));
  498.  
  499. return view('photos/user_comments', compact('comments', 'user'));
  500. }
  501.  
  502. /**
  503. * Переход к сообщению
  504. *
  505. * @param int $id
  506. * @param int $cid
  507. *
  508. * @return RedirectResponse
  509. */
  510. public function viewComment(int $id, int $cid): RedirectResponse
  511. {
  512. /** @var Photo $photo */
  513. $photo = Photo::query()->find($id);
  514.  
  515. if (! $photo) {
  516. abort(404, __('photos.photo_not_exist'));
  517. }
  518.  
  519. $total = $photo->comments()
  520. ->where('id', '<=', $cid)
  521. ->orderBy('created_at')
  522. ->count();
  523.  
  524. $end = ceil($total / setting('comments_per_page'));
  525.  
  526. return redirect('photos/comments/' . $photo->id . '?page=' . $end . '#comment_' . $cid);
  527. }
  528. }