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

Размер файла: 5.25Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Controllers;
  6.  
  7. use App\Models\File;
  8. use App\Models\Story;
  9. use App\Services\Session;
  10. use App\Services\Validator;
  11. use Intervention\Image\Constraint;
  12. use Intervention\Image\ImageManager;
  13. use Psr\Http\Message\ResponseInterface as Response;
  14. use Psr\Http\Message\ServerRequestInterface as Request;
  15.  
  16. /**
  17. * UploadController
  18. */
  19. class UploadController extends Controller
  20. {
  21. public function __construct(
  22. protected Session $session,
  23. protected Validator $validator,
  24. protected ImageManager $imageManager,
  25. ) {}
  26.  
  27. /**
  28. * Upload file
  29. *
  30. * @param Request $request
  31. * @param Response $response
  32. *
  33. * @return Response
  34. */
  35. public function upload(Request $request, Response $response): Response
  36. {
  37. $user = getUser();
  38. $input = (array) $request->getParsedBody();
  39. $files = $request->getUploadedFiles();
  40. $input = array_merge($input, $files);
  41.  
  42. $id = $input['id'] ?? 0;
  43.  
  44. if ($id) {
  45. $model = Story::query()->find($id);
  46.  
  47. if (! $model) {
  48. return $this->json($response, [
  49. 'success' => false,
  50. 'message' => 'Запись не найдена!',
  51. ]);
  52. }
  53.  
  54. $this->validator->custom(
  55. $model->user_id === $user->id || isAdmin(),
  56. 'Вы не являетесь автором данной записи!'
  57. );
  58. } else {
  59. $model = new Story();
  60. }
  61.  
  62. $this->validator
  63. ->required(['csrf', 'file'])
  64. ->same('csrf', $this->session->get('csrf'), 'Неверный идентификатор сессии, повторите действие!')
  65. ->file('file', [
  66. 'size_max' => setting('file.size_max'),
  67. 'extensions' => setting('file.extensions'),
  68. 'weight_max' => setting('image.weight_max'),
  69. 'weight_min' => setting('image.weight_min'),
  70. ]);
  71.  
  72. $countFiles = File::query()
  73. ->where('user_id', getUser('id'))
  74. ->where('story_id', $id)
  75. ->count();
  76.  
  77. $this->validator->custom(
  78. $countFiles < setting('file.total_max'),
  79. sprintf('Разрешено загружать не более %d файлов!', setting('file.total_max'))
  80. );
  81.  
  82. if ($this->validator->isValid($input)) {
  83. $file = $input['file'];
  84. $filename = sanitize($file->getClientFilename());
  85. $extension = getExtension($filename);
  86. $path = $model->uploadPath . '/' . uniqueName($extension);
  87.  
  88. if (in_array($extension, File::IMAGES, true)) {
  89. $img = $this->imageManager->make($file->getFilePath());
  90. $img->resize(setting('image.resize'), setting('image.resize'), static function (Constraint $constraint) {
  91. $constraint->aspectRatio();
  92. $constraint->upsize();
  93. });
  94.  
  95. $img->save(publicPath($path));
  96. } else {
  97. $file->moveTo(publicPath($path));
  98. }
  99.  
  100. $file = File::query()->create([
  101. 'user_id' => $user->id,
  102. 'story_id' => $id,
  103. 'path' => $path,
  104. 'name' => $filename,
  105. 'ext' => $extension,
  106. 'size' => $file->getSize(),
  107. 'created_at' => time(),
  108. ]);
  109.  
  110. return $this->json($response, [
  111. 'success' => true,
  112. 'id' => $file->id,
  113. 'path' => $file->path,
  114. 'name' => $file->name,
  115. 'size' => formatSize($file->size),
  116. 'type' => $file->isImage() ? 'image' : 'file',
  117. ]);
  118. }
  119.  
  120. return $this->json($response, [
  121. 'success' => false,
  122. 'message' => current($this->validator->getErrors()),
  123. ]);
  124. }
  125.  
  126. /**
  127. * Delete file
  128. *
  129. * @param int $id
  130. * @param Request $request
  131. * @param Response $response
  132. *
  133. * @return Response
  134. */
  135. public function destroy(int $id, Request $request, Response $response): Response
  136. {
  137. $user = getUser();
  138. $input = (array) $request->getParsedBody();
  139.  
  140. $file = File::query()->find($id);
  141.  
  142. if (! $file) {
  143. return $this->json($response, [
  144. 'success' => false,
  145. 'message' => 'Файл не найден!'
  146. ]);
  147. }
  148.  
  149. $this->validator
  150. ->required(['csrf'])
  151. ->same('csrf', $this->session->get('csrf'), 'Неверный идентификатор сессии, повторите действие!')
  152. ->custom($file->user_id === $user->id || isAdmin(), 'Вы не являетесь автором данного файла!');
  153.  
  154. if ($this->validator->isValid($input)) {
  155. $file->delete();
  156.  
  157. return $this->json($response, [
  158. 'success' => true,
  159. 'path' => $file->path,
  160. ]);
  161. }
  162.  
  163. return $this->json($response, [
  164. 'success' => false,
  165. 'message' => current($this->validator->getErrors()),
  166. ]);
  167. }
  168. }