- <?php
-
- declare(strict_types=1);
-
- namespace App\Controllers;
-
- use App\Models\File;
- use App\Models\Story;
- use App\Services\Session;
- use App\Services\Validator;
- use Intervention\Image\Constraint;
- use Intervention\Image\ImageManager;
- use Psr\Http\Message\ResponseInterface as Response;
- use Psr\Http\Message\ServerRequestInterface as Request;
-
- /**
- * UploadController
- */
- class UploadController extends Controller
- {
- public function __construct(
- protected Session $session,
- protected Validator $validator,
- protected ImageManager $imageManager,
- ) {}
-
- /**
- * Upload file
- *
- * @param Request $request
- * @param Response $response
- *
- * @return Response
- */
- public function upload(Request $request, Response $response): Response
- {
- $user = getUser();
- $input = (array) $request->getParsedBody();
- $files = $request->getUploadedFiles();
- $input = array_merge($input, $files);
-
- $id = $input['id'] ?? 0;
-
- if ($id) {
- $model = Story::query()->find($id);
-
- if (! $model) {
- return $this->json($response, [
- 'success' => false,
- 'message' => 'Запись не найдена!',
- ]);
- }
-
- $this->validator->custom(
- $model->user_id === $user->id || isAdmin(),
- 'Вы не являетесь автором данной записи!'
- );
- } else {
- $model = new Story();
- }
-
- $this->validator
- ->required(['csrf', 'file'])
- ->same('csrf', $this->session->get('csrf'), 'Неверный идентификатор сессии, повторите действие!')
- ->file('file', [
- 'size_max' => setting('file.size_max'),
- 'extensions' => setting('file.extensions'),
- 'weight_max' => setting('image.weight_max'),
- 'weight_min' => setting('image.weight_min'),
- ]);
-
- $countFiles = File::query()
- ->where('user_id', getUser('id'))
- ->where('story_id', $id)
- ->count();
-
- $this->validator->custom(
- $countFiles < setting('file.total_max'),
- sprintf('Разрешено загружать не более %d файлов!', setting('file.total_max'))
- );
-
- if ($this->validator->isValid($input)) {
- $file = $input['file'];
- $filename = sanitize($file->getClientFilename());
- $extension = getExtension($filename);
- $path = $model->uploadPath . '/' . uniqueName($extension);
-
- if (in_array($extension, File::IMAGES, true)) {
- $img = $this->imageManager->make($file->getFilePath());
- $img->resize(setting('image.resize'), setting('image.resize'), static function (Constraint $constraint) {
- $constraint->aspectRatio();
- $constraint->upsize();
- });
-
- $img->save(publicPath($path));
- } else {
- $file->moveTo(publicPath($path));
- }
-
- $file = File::query()->create([
- 'user_id' => $user->id,
- 'story_id' => $id,
- 'path' => $path,
- 'name' => $filename,
- 'ext' => $extension,
- 'size' => $file->getSize(),
- 'created_at' => time(),
- ]);
-
- return $this->json($response, [
- 'success' => true,
- 'id' => $file->id,
- 'path' => $file->path,
- 'name' => $file->name,
- 'size' => formatSize($file->size),
- 'type' => $file->isImage() ? 'image' : 'file',
- ]);
- }
-
- return $this->json($response, [
- 'success' => false,
- 'message' => current($this->validator->getErrors()),
- ]);
- }
-
- /**
- * Delete file
- *
- * @param int $id
- * @param Request $request
- * @param Response $response
- *
- * @return Response
- */
- public function destroy(int $id, Request $request, Response $response): Response
- {
- $user = getUser();
- $input = (array) $request->getParsedBody();
-
- $file = File::query()->find($id);
-
- if (! $file) {
- return $this->json($response, [
- 'success' => false,
- 'message' => 'Файл не найден!'
- ]);
- }
-
- $this->validator
- ->required(['csrf'])
- ->same('csrf', $this->session->get('csrf'), 'Неверный идентификатор сессии, повторите действие!')
- ->custom($file->user_id === $user->id || isAdmin(), 'Вы не являетесь автором данного файла!');
-
- if ($this->validator->isValid($input)) {
- $file->delete();
-
- return $this->json($response, [
- 'success' => true,
- 'path' => $file->path,
- ]);
- }
-
- return $this->json($response, [
- 'success' => false,
- 'message' => current($this->validator->getErrors()),
- ]);
- }
- }