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

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