UploadController.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. namespace App\Controllers;
  3. use League\Flysystem\FileExistsException;
  4. use Psr\Http\Message\ResponseInterface as Response;
  5. use Psr\Http\Message\ServerRequestInterface as Request;
  6. class UploadController extends Controller
  7. {
  8. /**
  9. * @param Request $request
  10. * @param Response $response
  11. *
  12. * @throws \Twig\Error\RuntimeError
  13. * @throws \Twig\Error\SyntaxError
  14. * @throws \Twig\Error\LoaderError
  15. *
  16. * @return Response
  17. */
  18. public function webUpload(Request $request, Response $response): Response
  19. {
  20. $user = $this->database->query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $this->session->get('user_id'))->fetch();
  21. if ($user->token === null || $user->token === '') {
  22. $this->session->alert(lang('no_upload_token'), 'danger');
  23. return redirect($response, $request->getHeaderLine('Referer'));
  24. }
  25. return view()->render($response, 'upload/web.twig', [
  26. 'user' => $user,
  27. ]);
  28. }
  29. /**
  30. * @param Request $request
  31. * @param Response $response
  32. *
  33. * @throws FileExistsException
  34. *
  35. * @return Response
  36. */
  37. public function upload(Request $request, Response $response): Response
  38. {
  39. $json = [
  40. 'message' => null,
  41. 'version' => PLATFORM_VERSION,
  42. ];
  43. if ($this->config['maintenance']) {
  44. $json['message'] = 'Endpoint under maintenance.';
  45. return json($response, $json, 503);
  46. }
  47. if ($request->getServerParams()['CONTENT_LENGTH'] > stringToBytes(ini_get('post_max_size'))) {
  48. $json['message'] = 'File too large (post_max_size too low?).';
  49. return json($response, $json, 400);
  50. }
  51. $file = array_values($request->getUploadedFiles());
  52. /** @var \Psr\Http\Message\UploadedFileInterface|null $file */
  53. $file = isset($file[0]) ? $file[0] : null;
  54. if ($file === null) {
  55. $json['message'] = 'Request without file attached.';
  56. return json($response, $json, 400);
  57. }
  58. if ($file->getError() === UPLOAD_ERR_INI_SIZE) {
  59. $json['message'] = 'File too large (upload_max_filesize too low?).';
  60. return json($response, $json, 400);
  61. }
  62. if (param($request, 'token') === null) {
  63. $json['message'] = 'Token not specified.';
  64. return json($response, $json, 400);
  65. }
  66. $user = $this->database->query('SELECT * FROM `users` WHERE `token` = ? LIMIT 1', param($request, 'token'))->fetch();
  67. if (!$user) {
  68. $json['message'] = 'Token specified not found.';
  69. return json($response, $json, 404);
  70. }
  71. if (!$user->active) {
  72. $json['message'] = 'Account disabled.';
  73. return json($response, $json, 401);
  74. }
  75. do {
  76. $code = humanRandomString();
  77. } while ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count > 0);
  78. $fileInfo = pathinfo($file->getClientFilename());
  79. $storagePath = "$user->user_code/$code.$fileInfo[extension]";
  80. $this->storage->writeStream($storagePath, $file->getStream()->detach());
  81. $this->database->query('INSERT INTO `uploads`(`user_id`, `code`, `filename`, `storage_path`) VALUES (?, ?, ?, ?)', [
  82. $user->id,
  83. $code,
  84. $file->getClientFilename(),
  85. $storagePath,
  86. ]);
  87. $json['message'] = 'OK.';
  88. $json['url'] = urlFor("/{$user->user_code}/{$code}.{$fileInfo['extension']}");
  89. $this->logger->info("User $user->username uploaded new media.", [$this->database->getPdo()->lastInsertId()]);
  90. return json($response, $json, 201);
  91. }
  92. }