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

Размер файла: 13.17Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Http\Controllers;
  6.  
  7. use App\Classes\Validator;
  8. use App\Models\Article;
  9. use App\Models\BaseModel;
  10. use App\Models\Comment;
  11. use App\Models\Down;
  12. use App\Models\File;
  13. use App\Models\Guestbook;
  14. use App\Models\Item;
  15. use App\Models\Message;
  16. use App\Models\News;
  17. use App\Models\Offer;
  18. use App\Models\Photo;
  19. use App\Models\Post;
  20. use App\Models\Spam;
  21. use App\Models\Sticker;
  22. use App\Models\Wall;
  23. use Exception;
  24. use Illuminate\Http\JsonResponse;
  25. use Illuminate\Support\Facades\DB;
  26. use Illuminate\Database\Eloquent\Relations\Relation;
  27. use Illuminate\Http\Request;
  28. use Illuminate\View\View;
  29.  
  30. class AjaxController extends Controller
  31. {
  32. /**
  33. * Конструктор
  34. *
  35. * @param Request $request
  36. */
  37. public function __construct(Request $request)
  38. {
  39. $this->checkAjax($request);
  40. $this->checkAuthorize();
  41. }
  42.  
  43. /**
  44. * Возвращает bbCode для предпросмотра
  45. *
  46. * @param Request $request
  47. *
  48. * @return View
  49. */
  50. public function bbCode(Request $request): View
  51. {
  52. $message = $request->input('data');
  53.  
  54. return view('app/_bbcode', compact('message'));
  55. }
  56.  
  57. /**
  58. * Отправляет жалобу на сообщение
  59. *
  60. * @param Request $request
  61. * @param Validator $validator
  62. *
  63. * @return JsonResponse
  64. */
  65. public function complaint(Request $request, Validator $validator): JsonResponse
  66. {
  67. $path = null;
  68. $model = false;
  69. $id = int($request->input('id'));
  70. $type = $request->input('type');
  71. $page = $request->input('page');
  72.  
  73. switch ($type) :
  74. case Guestbook::$morphName:
  75. $model = Guestbook::query()->find($id);
  76. $path = '/guestbook?page='.$page;
  77. break;
  78.  
  79. case Post::$morphName:
  80. $model = Post::query()->find($id);
  81. $path = '/topics/' . $model->topic_id . '?page='.$page;
  82. break;
  83.  
  84. case Message::$morphName:
  85. $model = Message::query()->find($id);
  86. break;
  87.  
  88. case Wall::$morphName:
  89. $model = Wall::query()->find($id);
  90. $path = '/walls/' . $model->user->login . '?page='.$page;
  91. break;
  92.  
  93. case News::$morphName:
  94. case Article::$morphName:
  95. case Photo::$morphName:
  96. case Offer::$morphName:
  97. case Down::$morphName:
  98. $model = Comment::query()->find($id);
  99. $path = '/' . $model->relate_type . '/comments/' . $model->relate_id . '?page='.$page;
  100. $type = 'comments';
  101. break;
  102. endswitch;
  103.  
  104. $spam = Spam::query()->where(['relate_type' => $type, 'relate_id' => $id])->first();
  105.  
  106. $validator
  107. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  108. ->true($model, __('main.message_not_found'))
  109. ->false($spam, __('ajax.complaint_already_sent'));
  110.  
  111. if ($validator->isValid()) {
  112. Spam::query()->create([
  113. 'relate_type' => $type,
  114. 'relate_id' => $model->id,
  115. 'user_id' => getUser('id'),
  116. 'path' => $path,
  117. 'created_at' => SITETIME,
  118. ]);
  119.  
  120. return response()->json(['success' => true]);
  121. }
  122.  
  123. return response()->json([
  124. 'success' => false,
  125. 'message' => current($validator->getErrors()),
  126. ]);
  127. }
  128.  
  129. /**
  130. * Удаляет комментарии
  131. *
  132. * @param Request $request
  133. * @param Validator $validator
  134. *
  135. * @return JsonResponse
  136. */
  137. public function delComment(Request $request, Validator $validator): JsonResponse
  138. {
  139. if (! isAdmin()) {
  140. return response()->json([
  141. 'success' => false,
  142. 'message' => __('main.not_authorized'),
  143. ]);
  144. }
  145.  
  146. $type = $request->input('type');
  147. $rid = int($request->input('rid'));
  148. $id = int($request->input('id'));
  149.  
  150. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'));
  151.  
  152. if ($validator->isValid()) {
  153. $delComments = Comment::query()
  154. ->where('relate_type', $type)
  155. ->where('relate_id', $rid)
  156. ->where('id', $id)
  157. ->delete();
  158.  
  159. if ($delComments) {
  160. /** @var BaseModel $class */
  161. $class = Relation::getMorphedModel($type);
  162. $model = $class::query()->find($rid);
  163.  
  164. if ($model) {
  165. $model->decrement('count_comments');
  166. }
  167. }
  168.  
  169. return response()->json(['success' => true]);
  170. }
  171.  
  172. return response()->json([
  173. 'success' => 'false',
  174. 'message' => current($validator->getErrors()),
  175. ]);
  176. }
  177.  
  178. /**
  179. * Изменяет рейтинг
  180. *
  181. * @param Request $request
  182. *
  183. * @return JsonResponse
  184. * @throws Exception
  185. */
  186. public function rating(Request $request): JsonResponse
  187. {
  188. $types = [
  189. Post::$morphName,
  190. Article::$morphName,
  191. Photo::$morphName,
  192. Offer::$morphName,
  193. News::$morphName,
  194. ];
  195.  
  196. $id = int($request->input('id'));
  197. $type = $request->input('type');
  198. $vote = $request->input('vote');
  199.  
  200. if ($request->input('_token') !== csrf_token()) {
  201. return response()->json([
  202. 'success' => false,
  203. 'message' => 'Invalid token',
  204. ]);
  205. }
  206.  
  207. if (! in_array($vote, ['+', '-'], true)) {
  208. return response()->json([
  209. 'success' => false,
  210. 'message' => 'Invalid rating',
  211. ]);
  212. }
  213.  
  214. if (! in_array($type, $types, true)) {
  215. return response()->json([
  216. 'success' => false,
  217. 'message' => 'Type invalid',
  218. ]);
  219. }
  220.  
  221. /** @var BaseModel $model */
  222. $model = Relation::getMorphedModel($type);
  223.  
  224. $post = $model::query()
  225. ->where('id', $id)
  226. ->where('user_id', '<>', getUser('id'))
  227. ->first();
  228.  
  229. if (! $post) {
  230. return response()->json([
  231. 'success' => false,
  232. 'message' => 'Record not found',
  233. ]);
  234. }
  235.  
  236. $polling = $post->polling()->first();
  237. $cancel = false;
  238.  
  239. if ($polling) {
  240. if ($polling->vote === $vote) {
  241. return response()->json(['success' => false]);
  242. }
  243.  
  244. $polling->delete();
  245. $cancel = true;
  246. } else {
  247. $post->polling()->create([
  248. 'user_id' => getUser('id'),
  249. 'vote' => $vote,
  250. 'created_at' => SITETIME,
  251. ]);
  252. }
  253.  
  254. if ($vote === '+') {
  255. $post->increment('rating');
  256. } else {
  257. $post->decrement('rating');
  258. }
  259.  
  260. return response()->json([
  261. 'success' => true,
  262. 'cancel' => $cancel,
  263. 'rating' => formatNum($post['rating'])->toHtml(),
  264. ]);
  265. }
  266.  
  267. /**
  268. * Загружает изображение
  269. *
  270. * @param Request $request
  271. * @param Validator $validator
  272. *
  273. * @return JsonResponse
  274. */
  275. public function uploadFile(Request $request, Validator $validator): JsonResponse
  276. {
  277. $imageTypes = [
  278. Article::$morphName,
  279. Item::$morphName,
  280. Photo::$morphName,
  281. ];
  282.  
  283. $fileTypes = [
  284. Message::$morphName,
  285. ];
  286.  
  287. $id = int($request->input('id'));
  288. $file = $request->file('file');
  289. $type = $request->input('type');
  290.  
  291. if (! in_array($type, array_merge($imageTypes, $fileTypes), true)) {
  292. return response()->json([
  293. 'success' => false,
  294. 'message' => 'Type invalid',
  295. ]);
  296. }
  297.  
  298. /** @var BaseModel $class */
  299. $class = Relation::getMorphedModel($type);
  300. $isImageType = in_array($type, $imageTypes, true);
  301.  
  302. if ($id) {
  303. $model = $class::query()->where('user_id', getUser('id'))->find($id);
  304.  
  305. if (! $model) {
  306. return response()->json([
  307. 'success' => false,
  308. 'message' => 'Service not found',
  309. ]);
  310. }
  311. } else {
  312. $model = new $class();
  313. }
  314.  
  315. $countFiles = File::query()
  316. ->where('relate_type', $type)
  317. ->where('relate_id', $id)
  318. ->where('user_id', getUser('id'))
  319. ->count();
  320.  
  321. $validator
  322. ->equal($request->input('_token'), csrf_token(), __('validator.token'))
  323. ->lt($countFiles, setting('maxfiles'), __('validator.files_max', ['max' => setting('maxfiles')]));
  324.  
  325. if ($validator->isValid()) {
  326. $rules = [
  327. 'minweight' => 100,
  328. 'maxsize' => setting('filesize'),
  329. 'extensions' => explode(',', setting('file_extensions')),
  330. ];
  331.  
  332. $validator->file($file, $rules, ['files' => __('validator.file_upload_failed')]);
  333. }
  334.  
  335. if ($validator->isValid()) {
  336. $fileData = $model->uploadFile($file);
  337. $fileType = $fileData['is_image'] ? 'image' : 'file';
  338.  
  339. if ($isImageType) {
  340. $imageData = resizeProcess($fileData['path'], ['size' => 100]);
  341. $data = [
  342. 'success' => true,
  343. 'id' => $fileData['id'],
  344. 'path' => $imageData['path'],
  345. 'source' => $imageData['source'],
  346. 'type' => $fileType,
  347. ];
  348. } else {
  349. $data = [
  350. 'success' => true,
  351. 'id' => $fileData['id'],
  352. 'path' => $fileData['path'],
  353. 'name' => $fileData['name'],
  354. 'size' => $fileData['size'],
  355. 'type' => $fileType,
  356. ];
  357. }
  358.  
  359. return response()->json($data);
  360. }
  361.  
  362. return response()->json([
  363. 'success' => false,
  364. 'message' => current($validator->getErrors()),
  365. ]);
  366. }
  367.  
  368. /**
  369. * Удаляет изображение
  370. *
  371. * @param Request $request
  372. * @param Validator $validator
  373. *
  374. * @return JsonResponse
  375. * @throws Exception
  376. */
  377. public function deleteFile(Request $request, Validator $validator): JsonResponse
  378. {
  379. $types = [
  380. Article::$morphName,
  381. Item::$morphName,
  382. Photo::$morphName,
  383. Message::$morphName,
  384. ];
  385.  
  386. $id = int($request->input('id'));
  387. $type = $request->input('type');
  388.  
  389. if (! in_array($type, $types, true)) {
  390. return response()->json([
  391. 'success' => false,
  392. 'message' => 'Type invalid',
  393. ]);
  394. }
  395.  
  396. /** @var File $file */
  397. $file = File::query()
  398. ->where('relate_type', $type)
  399. ->find($id);
  400.  
  401. if (! $file) {
  402. return response()->json([
  403. 'success' => false,
  404. 'message' => 'File not found'
  405. ]);
  406. }
  407.  
  408. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  409. ->true(getUser('id') === $file->user_id || isAdmin(), __('ajax.file_not_author'));
  410.  
  411. if ($validator->isValid()) {
  412. $file->delete();
  413.  
  414. return response()->json([
  415. 'success' => true,
  416. 'path' => $file->hash,
  417. ]);
  418. }
  419.  
  420. return response()->json([
  421. 'success' => false,
  422. 'message' => current($validator->getErrors()),
  423. ]);
  424. }
  425.  
  426. /**
  427. * Вставляет стикер
  428. *
  429. * @return JsonResponse
  430. * @throws Exception
  431. */
  432. public function getStickers(): JsonResponse
  433. {
  434. $stickers = Sticker::query()
  435. //->where('category_id', $id)
  436. ->orderBy(DB::raw('CHAR_LENGTH(code)'))
  437. ->orderBy('name')
  438. ->get();
  439.  
  440. $view = view('pages/_stickers_modal', compact('stickers'))->render();
  441.  
  442. return response()->json([
  443. 'success' => true,
  444. 'stickers' => $view,
  445. ]);
  446. }
  447.  
  448. /**
  449. * Возвращает является ли запрос ajax
  450. *
  451. * @param Request $request
  452. *
  453. * @return JsonResponse|bool
  454. */
  455. private function checkAjax(Request $request)
  456. {
  457. if (! $request->ajax()) {
  458. return response()->json([
  459. 'success' => false,
  460. 'message' => __('validator.not_ajax'),
  461. ]);
  462. }
  463.  
  464. return true;
  465. }
  466.  
  467. /**
  468. * Возвращает авторизован ли пользователь
  469. *
  470. * @return JsonResponse|bool
  471. */
  472. private function checkAuthorize()
  473. {
  474. if (! getUser()) {
  475. return response()->json([
  476. 'success' => false,
  477. 'message' => __('main.not_authorized'),
  478. ]);
  479. }
  480.  
  481. return true;
  482. }
  483. }