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

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