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

Размер файла: 7.91Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Http\Controllers;
  6.  
  7. use App\Classes\Validator;
  8. use App\Models\Dialogue;
  9. use App\Models\File;
  10. use App\Models\Flood;
  11. use App\Models\Ignore;
  12. use App\Models\Message;
  13. use App\Models\User;
  14. use Illuminate\Http\RedirectResponse;
  15. use Illuminate\Support\Facades\DB;
  16. use Illuminate\Database\Query\JoinClause;
  17. use Illuminate\Http\Request;
  18. use Illuminate\View\View;
  19. use Symfony\Component\HttpFoundation\Response;
  20.  
  21. class MessageController extends Controller
  22. {
  23. public ?User $user;
  24.  
  25. /**
  26. * Конструктор
  27. */
  28. public function __construct()
  29. {
  30. $this->middleware(function ($request, $next) {
  31. $this->user = getUser();
  32.  
  33. return $next($request);
  34. });
  35. }
  36.  
  37. /**
  38. * Главная страница
  39. *
  40. * @return View
  41. */
  42. public function index(): View
  43. {
  44. $lastMessage = Dialogue::query()
  45. ->select(
  46. 'author_id',
  47. DB::raw('max(message_id) as message_id'),
  48. DB::raw('min(case when reading then 1 else 0 end) as all_reading')
  49. )
  50. ->where('user_id', $this->user->id)
  51. ->groupBy('author_id');
  52.  
  53. $messages = Message::query()
  54. ->select('d.*', 'm.text', 'd2.all_reading', 'd3.reading as recipient_read')
  55. ->from('messages as m')
  56. ->join('dialogues as d', 'd.message_id', 'm.id')
  57. ->joinSub($lastMessage, 'd2', static function (JoinClause $join) {
  58. $join->on('d.message_id', 'd2.message_id');
  59. })
  60. ->leftJoin('dialogues as d3', function ($join) {
  61. $join->on('d.user_id', 'd3.author_id')
  62. ->whereRaw('d.message_id = d3.message_id');
  63. })
  64. ->where('d.user_id', $this->user->id)
  65. ->orderByDesc('d.created_at')
  66. ->with('author')
  67. ->paginate(setting('privatpost'));
  68.  
  69. return view('messages/index', compact('messages'));
  70. }
  71.  
  72. /**
  73. * Диалог
  74. *
  75. * @param string $login
  76. *
  77. * @return View
  78. */
  79. public function talk(string $login): View
  80. {
  81. if (is_numeric($login)) {
  82. $user = new User();
  83. $user->id = $login;
  84. } else {
  85. $user = getUserByLogin($login);
  86.  
  87. if (! $user) {
  88. abort(404, __('validator.user'));
  89. }
  90. }
  91.  
  92. if ($user->id === $this->user->id) {
  93. abort(200, __('messages.empty_dialogue'));
  94. }
  95.  
  96. $messages = Message::query()
  97. ->select('d.*', 'm.id', 'm.text', 'd2.reading as recipient_read')
  98. ->from('messages as m')
  99. ->join('dialogues as d', 'd.message_id', 'm.id')
  100. ->leftJoin('dialogues as d2', function ($join) {
  101. $join->on('d.user_id', 'd2.author_id')
  102. ->whereRaw('d.message_id = d2.message_id');
  103. })
  104. ->where('d.user_id', $this->user->id)
  105. ->where('d.author_id', $user->id)
  106. ->orderByDesc('d.created_at')
  107. ->with('user', 'author', 'files')
  108. ->paginate(setting('privatpost'));
  109.  
  110. Dialogue::query()
  111. ->where('user_id', $this->user->id)
  112. ->where('author_id', $user->id)
  113. ->where('reading', 0)
  114. ->update(['reading' => 1]);
  115.  
  116. $files = File::query()
  117. ->where('relate_type', Message::$morphName)
  118. ->where('relate_id', 0)
  119. ->where('user_id', $this->user->id)
  120. ->orderBy('created_at')
  121. ->get();
  122.  
  123. $view = $user->id ? 'messages/talk' : 'messages/talk_system';
  124.  
  125. return view($view, compact('messages', 'user', 'files'));
  126. }
  127.  
  128. /**
  129. * Отправка сообщений
  130. *
  131. * @param Request $request
  132. * @param Validator $validator
  133. * @param Flood $flood
  134. *
  135. * @return RedirectResponse
  136. */
  137. public function send(Request $request, Validator $validator, Flood $flood): RedirectResponse
  138. {
  139. $login = $request->input('user');
  140. $msg = $request->input('msg');
  141.  
  142. $user = getUserByLogin($login);
  143.  
  144. if (! $user) {
  145. abort(404, __('validator.user'));
  146. }
  147.  
  148. $validator->equal($request->input('_token'), csrf_token(), ['msg' => __('validator.token')])
  149. ->length($msg, 5, setting('comment_length'), ['msg' => __('validator.text')])
  150. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
  151. ->notEqual($user->id, $this->user->id, __('messages.send_yourself'));
  152.  
  153. if (! captchaVerify() && $this->user->point < setting('privatprotect')) {
  154. $validator->addError(['protect' => __('validator.captcha')]);
  155. }
  156.  
  157. // Проверка на игнор
  158. $ignoring = Ignore::query()
  159. ->where('user_id', $user->id)
  160. ->where('ignore_id', $this->user->id)
  161. ->first();
  162.  
  163. $validator->empty($ignoring, ['user' => __('ignores.you_are_ignoring')]);
  164.  
  165. if ($validator->isValid()) {
  166. $msg = antimat($msg);
  167. $message = $user->sendMessage($this->user, $msg);
  168.  
  169. File::query()
  170. ->where('relate_type', Message::$morphName)
  171. ->where('relate_id', 0)
  172. ->where('user_id', $this->user->id)
  173. ->update(['relate_id' => $message->id]);
  174.  
  175. $flood->saveState();
  176.  
  177. setFlash('success', __('messages.success_sent'));
  178. } else {
  179. setInput($request->all());
  180. setFlash('danger', $validator->getErrors());
  181. }
  182.  
  183. return redirect('messages/talk/' . $user->login);
  184. }
  185.  
  186. /**
  187. * Удаление переписки
  188. *
  189. * @param int $uid
  190. * @param Request $request
  191. * @param Validator $validator
  192. *
  193. * @return RedirectResponse
  194. */
  195. public function delete(int $uid, Request $request, Validator $validator): RedirectResponse
  196. {
  197. $page = int($request->input('page', 1));
  198.  
  199. $dialogues = Dialogue::query()
  200. ->where('user_id', $this->user->id)
  201. ->where('author_id', $uid)
  202. ->get();
  203.  
  204. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  205. ->notEmpty($dialogues->count(), ['user' => __('messages.empty_dialogue')])
  206. ->empty(getUser('newprivat'), __('messages.unread_messages'));
  207.  
  208. if ($validator->isValid()) {
  209. foreach ($dialogues as $dialogue) {
  210. $dialogue->delete();
  211. }
  212.  
  213. setFlash('success', __('messages.success_deleted'));
  214. } else {
  215. setFlash('danger', $validator->getErrors());
  216. }
  217.  
  218. return redirect('messages?page=' . $page);
  219. }
  220.  
  221. /**
  222. * New messages
  223. *
  224. * @param Request $request
  225. *
  226. * @return Response
  227. */
  228. public function newMessages(Request $request): Response
  229. {
  230. if (! $request->ajax()) {
  231. return redirect('/');
  232. }
  233.  
  234. $countMessages = Dialogue::query()
  235. ->where('user_id', $this->user->id)
  236. ->where('reading', 0)
  237. ->count();
  238.  
  239. if ($countMessages) {
  240. $dialogues = Dialogue::query()
  241. ->select(
  242. 'author_id',
  243. DB::raw('max(created_at) as last_created_at')
  244. )
  245. ->selectRaw('count(*) as cnt')
  246. ->where('user_id', $this->user->id)
  247. ->where('reading', 0)
  248. ->groupBy('author_id')
  249. ->limit(3)
  250. ->get();
  251.  
  252. if ($dialogues->isNotEmpty()) {
  253. $view = view('messages/_new', compact('dialogues'))->render();
  254.  
  255. return response()->json([
  256. 'success' => true,
  257. 'dialogues' => $view,
  258. 'countMessages' => $countMessages,
  259. ]);
  260. }
  261. }
  262.  
  263. return response()->json(['success' => false]);
  264. }
  265. }