TagController.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. namespace App\Controllers;
  3. use App\Web\ValidationChecker;
  4. use PDO;
  5. use Psr\Http\Message\ResponseInterface as Response;
  6. use Psr\Http\Message\ServerRequestInterface as Request;
  7. use Slim\Exception\HttpBadRequestException;
  8. use Slim\Exception\HttpNotFoundException;
  9. class TagController extends Controller
  10. {
  11. const PER_MEDIA_LIMIT = 10;
  12. /**
  13. * @param Request $request
  14. * @param Response $response
  15. * @return Response
  16. * @throws HttpBadRequestException
  17. */
  18. public function addTag(Request $request, Response $response): Response
  19. {
  20. $validator = $this->validateTag($request);
  21. if ($validator->fails()) {
  22. throw new HttpBadRequestException($request);
  23. }
  24. $tag = $this->database->query('SELECT * FROM `tags` WHERE `name` = ? LIMIT 1', param($request, 'tag'))->fetch();
  25. $connectedIds = $this->database->query('SELECT `tag_id` FROM `uploads_tags` WHERE `upload_id` = ?', [
  26. param($request, 'mediaId'),
  27. ])->fetchAll(PDO::FETCH_COLUMN, 0);
  28. if (!$tag && count($connectedIds) < self::PER_MEDIA_LIMIT) {
  29. $this->database->query('INSERT INTO `tags`(`name`) VALUES (?)', param($request, 'tag'));
  30. $tagId = $this->database->getPdo()->lastInsertId();
  31. $this->database->query('INSERT INTO `uploads_tags`(`upload_id`, `tag_id`) VALUES (?, ?)', [
  32. param($request, 'mediaId'),
  33. $tagId,
  34. ]);
  35. return json($response, [
  36. 'limitReached' => false,
  37. 'tagId' => $tagId,
  38. ]);
  39. }
  40. if (count($connectedIds) >= self::PER_MEDIA_LIMIT || in_array($tag->id, $connectedIds)) {
  41. return json($response, [
  42. 'limitReached' => true,
  43. 'tagId' => null,
  44. ]);
  45. }
  46. $this->database->query('INSERT INTO `uploads_tags`(`upload_id`, `tag_id`) VALUES (?, ?)', [
  47. param($request, 'mediaId'),
  48. $tag->id,
  49. ]);
  50. return json($response, [
  51. 'limitReached' => false,
  52. 'tagId' => $tag->id,
  53. ]);
  54. }
  55. /**
  56. * @param Request $request
  57. * @param Response $response
  58. * @return Response
  59. * @throws HttpBadRequestException
  60. * @throws HttpNotFoundException
  61. */
  62. public function removeTag(Request $request, Response $response): Response
  63. {
  64. $validator = $this->validateTag($request)
  65. ->addRule('tag.exists', false);
  66. if ($validator->fails()) {
  67. throw new HttpBadRequestException($request);
  68. }
  69. $tag = $this->database->query('SELECT * FROM `tags` WHERE `name` = ? LIMIT 1', param($request, 'tag'))->fetch();
  70. if (!$tag) {
  71. throw new HttpNotFoundException($request);
  72. }
  73. $this->database->query('DELETE FROM `uploads_tags` WHERE `upload_id` = ? AND `tag_id` = ?', [
  74. param($request, 'mediaId'),
  75. $tag->id,
  76. ]);
  77. if ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads_tags` WHERE `tag_id` = ?', $tag->id)->fetch()->count == 0) {
  78. $this->database->query('DELETE FROM `tags` WHERE `id` = ? ', $tag->id);
  79. }
  80. return $response;
  81. }
  82. protected function validateTag(Request $request)
  83. {
  84. return ValidationChecker::make()
  85. ->rules([
  86. 'tag.notEmpty' => !empty(param($request, 'tag')),
  87. 'mediaId.notEmpty' => !empty(param($request, 'mediaId')),
  88. 'media.exists' => $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `id` = ?', param($request, 'mediaId'))->fetch()->count > 0,
  89. 'same.userOrAdmin' => $this->session->get('admin', false) || $this->database->query('SELECT * FROM `uploads` WHERE `id` = ? LIMIT 1', param($request, 'mediaId'))->fetch()->user_id === $this->session->get('user_id'),
  90. ]);
  91. }
  92. }