Controller.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. namespace App\Controllers;
  3. use App\Database\DB;
  4. use App\Web\Lang;
  5. use App\Web\Session;
  6. use App\Web\View;
  7. use DI\Container;
  8. use DI\DependencyException;
  9. use DI\NotFoundException;
  10. use League\Flysystem\FileNotFoundException;
  11. use League\Flysystem\Filesystem;
  12. use Monolog\Logger;
  13. use Psr\Http\Message\ServerRequestInterface as Request;
  14. use Slim\Exception\HttpNotFoundException;
  15. use Slim\Exception\HttpUnauthorizedException;
  16. /**
  17. * @property Session|null session
  18. * @property View view
  19. * @property DB|null database
  20. * @property Logger|null logger
  21. * @property Filesystem|null storage
  22. * @property Lang lang
  23. * @property array config
  24. */
  25. abstract class Controller
  26. {
  27. /** @var Container */
  28. protected $container;
  29. public function __construct(Container $container)
  30. {
  31. $this->container = $container;
  32. }
  33. /**
  34. * @param $name
  35. *
  36. * @return mixed|null
  37. * @throws NotFoundException
  38. *
  39. * @throws DependencyException
  40. */
  41. public function __get($name)
  42. {
  43. if ($this->container->has($name)) {
  44. return $this->container->get($name);
  45. }
  46. }
  47. /**
  48. * @param $id
  49. *
  50. * @return int
  51. */
  52. protected function getUsedSpaceByUser($id): int
  53. {
  54. $medias = $this->database->query('SELECT `uploads`.`storage_path` FROM `uploads` WHERE `user_id` = ?', $id);
  55. $totalSize = 0;
  56. $filesystem = $this->storage;
  57. foreach ($medias as $media) {
  58. try {
  59. $totalSize += $filesystem->getSize($media->storage_path);
  60. } catch (FileNotFoundException $e) {
  61. $this->logger->error('Error calculating file size', ['exception' => $e]);
  62. }
  63. }
  64. return $totalSize;
  65. }
  66. /**
  67. * @param Request $request
  68. * @param $id
  69. * @param bool $authorize
  70. *
  71. * @return mixed
  72. * @throws HttpUnauthorizedException
  73. *
  74. * @throws HttpNotFoundException
  75. */
  76. protected function getUser(Request $request, $id, $authorize = false)
  77. {
  78. $user = $this->database->query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $id)->fetch();
  79. if (!$user) {
  80. throw new HttpNotFoundException($request);
  81. }
  82. if ($authorize && $user->id !== $this->session->get('user_id') && !$this->session->get('admin', false)) {
  83. throw new HttpUnauthorizedException($request);
  84. }
  85. return $user;
  86. }
  87. /**
  88. * @param $userId
  89. * @throws \Exception
  90. */
  91. protected function refreshRememberCookie($userId)
  92. {
  93. $selector = bin2hex(random_bytes(8));
  94. $token = bin2hex(random_bytes(32));
  95. $expire = time() + 604800; // a week
  96. $this->database->query('UPDATE `users` SET `remember_selector`=?, `remember_token`=?, `remember_expire`=? WHERE `id`=?', [
  97. $selector,
  98. password_hash($token, PASSWORD_DEFAULT),
  99. date('Y-m-d\TH:i:s', $expire),
  100. $userId,
  101. ]);
  102. // Workaround for php <= 7.3
  103. if (PHP_VERSION_ID < 70300) {
  104. setcookie('remember', "{$selector}:{$token}", $expire, '; SameSite=Lax', '', false, true);
  105. } else {
  106. setcookie('remember', "{$selector}:{$token}", [
  107. 'expires' => $expire,
  108. 'httponly' => true,
  109. 'samesite' => 'Lax',
  110. ]);
  111. }
  112. }
  113. /**
  114. * @return string
  115. */
  116. protected function generateUserUploadToken(): string
  117. {
  118. do {
  119. $token = 'token_'.md5(uniqid('', true));
  120. } while ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `token` = ?', $token)->fetch()->count > 0);
  121. return $token;
  122. }
  123. }