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

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