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

Размер файла: 13.75Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Http\Controllers\Admin;
  6.  
  7. use App\Classes\Validator;
  8. use App\Models\Down;
  9. use App\Models\File;
  10. use App\Models\Load;
  11. use App\Models\User;
  12. use Illuminate\Http\RedirectResponse;
  13. use Illuminate\Http\Request;
  14. use Illuminate\View\View;
  15.  
  16. class LoadController extends AdminController
  17. {
  18. /**
  19. * Главная страница
  20. *
  21. * @return View
  22. */
  23. public function index(): View
  24. {
  25. $categories = Load::query()
  26. ->where('parent_id', 0)
  27. ->with('children', 'new', 'children.new')
  28. ->orderBy('sort')
  29. ->get();
  30.  
  31. return view('admin/loads/index', compact('categories'));
  32. }
  33.  
  34. /**
  35. * Создание раздела
  36. *
  37. * @param Request $request
  38. * @param Validator $validator
  39. *
  40. * @return RedirectResponse
  41. */
  42. public function create(Request $request, Validator $validator): RedirectResponse
  43. {
  44. if (! isAdmin(User::BOSS)) {
  45. abort(403, __('errors.forbidden'));
  46. }
  47.  
  48. $name = $request->input('name');
  49.  
  50. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  51. ->length($name, 3, 50, ['title' => __('validator.text')]);
  52.  
  53. if ($validator->isValid()) {
  54. $max = Load::query()->max('sort') + 1;
  55.  
  56. /** @var Load $load */
  57. $load = Load::query()->create([
  58. 'name' => $name,
  59. 'sort' => $max,
  60. ]);
  61.  
  62. setFlash('success', __('loads.load_success_created'));
  63.  
  64. return redirect('admin/loads/edit/' . $load->id);
  65. }
  66.  
  67. setInput($request->all());
  68. setFlash('danger', $validator->getErrors());
  69.  
  70. return redirect('admin/loads');
  71. }
  72.  
  73. /**
  74. * Редактирование раздела
  75. *
  76. * @param int $id
  77. * @param Request $request
  78. * @param Validator $validator
  79. *
  80. * @return View|RedirectResponse
  81. */
  82. public function edit(int $id, Request $request, Validator $validator)
  83. {
  84. if (! isAdmin(User::BOSS)) {
  85. abort(403, __('errors.forbidden'));
  86. }
  87.  
  88. /** @var Load $load */
  89. $load = Load::query()->with('children')->find($id);
  90.  
  91. if (! $load) {
  92. abort(404, __('loads.load_not_exist'));
  93. }
  94.  
  95. if ($request->isMethod('post')) {
  96. $parent = int($request->input('parent'));
  97. $name = $request->input('name');
  98. $sort = int($request->input('sort'));
  99. $closed = empty($request->input('closed')) ? 0 : 1;
  100.  
  101. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  102. ->length($name, 3, 50, ['title' => __('validator.text')])
  103. ->notEqual($parent, $load->id, ['parent' => __('loads.load_parent_invalid')]);
  104.  
  105. if ($validator->isValid()) {
  106. $load->update([
  107. 'parent_id' => $parent,
  108. 'name' => $name,
  109. 'sort' => $sort,
  110. 'closed' => $closed,
  111. ]);
  112.  
  113. setFlash('success', __('loads.load_success_edited'));
  114.  
  115. return redirect('admin/loads');
  116. }
  117.  
  118. setInput($request->all());
  119. setFlash('danger', $validator->getErrors());
  120. }
  121.  
  122. $loads = $load->getChildren();
  123.  
  124. return view('admin/loads/edit', compact('loads', 'load'));
  125. }
  126.  
  127. /**
  128. * Удаление раздела
  129. *
  130. * @param int $id
  131. * @param Request $request
  132. * @param Validator $validator
  133. *
  134. * @return RedirectResponse
  135. */
  136. public function delete(int $id, Request $request, Validator $validator): RedirectResponse
  137. {
  138. if (! isAdmin(User::BOSS)) {
  139. abort(403, __('errors.forbidden'));
  140. }
  141.  
  142. /** @var Load $load */
  143. $load = Load::query()->with('children')->find($id);
  144.  
  145. if (! $load) {
  146. abort(404, __('loads.load_not_exist'));
  147. }
  148.  
  149. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  150. ->true($load->children->isEmpty(), __('loads.load_has_subcategories'));
  151.  
  152. $down = Down::query()->where('category_id', $load->id)->first();
  153. if ($down) {
  154. $validator->addError(__('loads.load_has_downs'));
  155. }
  156.  
  157. if ($validator->isValid()) {
  158. $load->delete();
  159.  
  160. setFlash('success', __('loads.load_success_deleted'));
  161. } else {
  162. setFlash('danger', $validator->getErrors());
  163. }
  164.  
  165. return redirect('admin/loads');
  166. }
  167.  
  168. /**
  169. * Пересчет данных
  170. *
  171. * @param Request $request
  172. *
  173. * @return RedirectResponse
  174. */
  175. public function restatement(Request $request): RedirectResponse
  176. {
  177. if (! isAdmin(User::BOSS)) {
  178. abort(403, __('errors.forbidden'));
  179. }
  180.  
  181. if ($request->input('_token') === csrf_token()) {
  182. restatement('loads');
  183.  
  184. setFlash('success', __('main.success_recounted'));
  185. } else {
  186. setFlash('danger', __('validator.token'));
  187. }
  188.  
  189. return redirect('admin/loads');
  190. }
  191.  
  192. /**
  193. * Просмотр загрузок раздела
  194. *
  195. * @param int $id
  196. * @param Request $request
  197. *
  198. * @return View
  199. */
  200. public function load(int $id, Request $request): View
  201. {
  202. /** @var Load $category */
  203. $category = Load::query()->with('parent')->find($id);
  204.  
  205. if (! $category) {
  206. abort(404, __('loads.load_not_exist'));
  207. }
  208.  
  209. $sort = check($request->input('sort', 'time'));
  210. $order = match ($sort) {
  211. 'rating' => 'rating',
  212. 'comments' => 'count_comments',
  213. 'loads' => 'loads',
  214. default => 'created_at',
  215. };
  216.  
  217. $downs = Down::query()
  218. ->where('category_id', $category->id)
  219. ->where('active', 1)
  220. ->orderByDesc($order)
  221. ->paginate(setting('downlist'))
  222. ->appends(['sort' => $sort]);
  223.  
  224. return view('admin/loads/load', compact('category', 'downs', 'order'));
  225. }
  226.  
  227. /**
  228. * Редактирование загрузки
  229. *
  230. * @param int $id
  231. * @param Request $request
  232. * @param Validator $validator
  233. *
  234. * @return View|RedirectResponse
  235. */
  236. public function editDown(int $id, Request $request, Validator $validator)
  237. {
  238. $cid = int($request->input('category'));
  239.  
  240. /** @var Down $down */
  241. $down = Down::query()->find($id);
  242.  
  243. if (! $down) {
  244. abort(404, __('loads.down_not_exist'));
  245. }
  246.  
  247. if ($request->isMethod('post')) {
  248. $title = $request->input('title');
  249. $text = $request->input('text');
  250. $files = (array) $request->file('files');
  251. $links = (array) $request->input('links');
  252.  
  253. $links = array_unique(array_diff($links, ['']));
  254.  
  255. /** @var Load $category */
  256. $category = Load::query()->find($cid);
  257.  
  258. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  259. ->length($title, 3, 50, ['title' => __('validator.text')])
  260. ->length($text, 50, 5000, ['text' => __('validator.text')])
  261. ->notEmpty($category, ['category' => __('loads.load_not_exist')]);
  262.  
  263. $duplicate = Down::query()->where('title', $title)->where('id', '<>', $down->id)->count();
  264. $validator->empty($duplicate, ['title' => __('loads.down_name_exists')]);
  265.  
  266. $existFiles = $down->files ? $down->files->count() : 0;
  267. $validator->notEmpty(count($files) + count($links) + $existFiles , ['files' => __('validator.file_upload_one')]);
  268. $validator->lte(count($files) + count($links) + $existFiles, setting('maxfiles'), ['files' => __('validator.files_max', ['max' => setting('maxfiles')])]);
  269.  
  270. if ($validator->isValid()) {
  271. $allowExtension = explode(',', setting('allowextload'));
  272.  
  273. $rules = [
  274. 'maxsize' => setting('fileupload'),
  275. 'extensions' => $allowExtension,
  276. 'minweight' => 100,
  277. ];
  278.  
  279. foreach ($files as $file) {
  280. $validator->file($file, $rules, ['files' => __('validator.file_upload_failed')]);
  281. }
  282.  
  283. foreach ($links as $link) {
  284. $validator->length($link, 5, 100, ['links' => __('validator.text')])
  285. ->url($link, ['links' => __('validator.url')]);
  286.  
  287. if (! in_array(getExtension($link), $allowExtension, true)) {
  288. $validator->addError(['links' => __('validator.extension')]);
  289. }
  290. }
  291. }
  292.  
  293. if ($validator->isValid()) {
  294. $oldDown = $down->replicate();
  295. $links = setting('down_allow_links') ? array_values($links) : null;
  296.  
  297. $down->update([
  298. 'category_id' => $category->id,
  299. 'title' => $title,
  300. 'text' => $text,
  301. 'links' => $links,
  302. ]);
  303.  
  304. if ($down->category->id !== $oldDown->category->id && $down->active) {
  305. $down->category->increment('count_downs');
  306. $oldDown->category->decrement('count_downs');
  307. }
  308.  
  309. foreach ($files as $file) {
  310. $down->uploadAndConvertFile($file);
  311. }
  312.  
  313. if (! $down->active) {
  314. $text = textNotice('down_change', ['url' => '/downs/' . $down->id, 'title' => $down->title]);
  315. $down->user->sendMessage(null, $text);
  316. }
  317.  
  318. clearCache(['statLoads', 'recentDowns', 'DownFeed']);
  319. setFlash('success', __('loads.down_edited_success'));
  320.  
  321. return redirect('admin/downs/edit/' . $down->id);
  322. }
  323.  
  324. setInput($request->all());
  325. setFlash('danger', $validator->getErrors());
  326. }
  327.  
  328. $categories = $down->category->getChildren();
  329.  
  330. return view('admin/loads/edit_down', compact('categories', 'down', 'cid'));
  331. }
  332.  
  333. /**
  334. * Удаление загрузки
  335. *
  336. * @param int $id
  337. * @param Request $request
  338. *
  339. * @return RedirectResponse
  340. */
  341. public function deleteDown(int $id, Request $request): RedirectResponse
  342. {
  343. /** @var Down $down */
  344. $down = Down::query()->find($id);
  345.  
  346. if (! $down) {
  347. abort(404, __('loads.down_not_exist'));
  348. }
  349.  
  350. if (! isAdmin(User::BOSS)) {
  351. abort(403, __('errors.forbidden'));
  352. }
  353.  
  354. if ($request->input('_token') === csrf_token()) {
  355. if ($down->active) {
  356. $down->category->decrement('count_downs');
  357. }
  358.  
  359. $down->comments()->delete();
  360. $down->delete();
  361.  
  362. clearCache(['statLoads', 'recentDowns', 'DownFeed']);
  363. setFlash('success', __('loads.down_success_deleted'));
  364. } else {
  365. setFlash('danger', __('validator.token'));
  366. }
  367.  
  368. return redirect('admin/loads/' . $down->category_id);
  369. }
  370.  
  371. /**
  372. * Удаление файла
  373. *
  374. * @param int $id
  375. * @param int $fid
  376. *
  377. * @return RedirectResponse
  378. */
  379. public function deleteFile(int $id, int $fid): RedirectResponse
  380. {
  381. /** @var Down $down */
  382. $down = Down::query()->find($id);
  383.  
  384. if (! $down) {
  385. abort(404, __('loads.down_not_exist'));
  386. }
  387.  
  388. /** @var File $file */
  389. $file = $down->files()->find($fid);
  390.  
  391. if (! $file) {
  392. abort(404, __('loads.down_not_exist'));
  393. }
  394.  
  395. deleteFile(public_path($file->hash));
  396.  
  397. setFlash('success', __('loads.file_deleted_success'));
  398. $file->delete();
  399.  
  400. return redirect('admin/downs/edit/' . $down->id);
  401. }
  402.  
  403. /**
  404. * Новые публикации
  405. *
  406. * @return View
  407. */
  408. public function new(): View
  409. {
  410. $downs = Down::query()
  411. ->where('active', 0)
  412. ->orderByDesc('created_at')
  413. ->with('user', 'category', 'files')
  414. ->paginate(setting('downlist'));
  415.  
  416. return view('admin/loads/new', compact('downs'));
  417. }
  418.  
  419. /**
  420. * Публикация загрузки
  421. *
  422. * @param int $id
  423. * @param Request $request
  424. *
  425. * @return RedirectResponse
  426. */
  427. public function publish(int $id, Request $request): RedirectResponse
  428. {
  429. /** @var Down $down */
  430. $down = Down::query()->find($id);
  431.  
  432. if (! $down) {
  433. abort(404, __('loads.down_not_exist'));
  434. }
  435.  
  436. if ($request->input('_token') === csrf_token()) {
  437. $active = $down->active ^ 1;
  438.  
  439. $down->update([
  440. 'active' => $active,
  441. 'updated_at' => SITETIME,
  442. 'created_at' => SITETIME,
  443. ]);
  444.  
  445. if ($active) {
  446. $status = __('loads.down_success_published');
  447. $down->category->increment('count_downs');
  448. $text = textNotice('down_publish', ['url' => '/downs/' . $down->id, 'title' => $down->title]);
  449. } else {
  450. $status = __('loads.down_success_unpublished');
  451. $down->category->decrement('count_downs');
  452. $text = textNotice('down_unpublish', ['url' => '/downs/' . $down->id, 'title' => $down->title]);
  453. }
  454.  
  455. $down->user->sendMessage(null, $text);
  456.  
  457. clearCache(['statLoads', 'recentDowns', 'DownFeed']);
  458. setFlash('success', $status);
  459. } else {
  460. setFlash('danger', __('validator.token'));
  461. }
  462.  
  463. return redirect('admin/downs/edit/' . $down->id);
  464. }
  465. }