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

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