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

Размер файла: 3.57Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Controllers;
  6.  
  7. use App\Models\Comment;
  8. use App\Models\Poll;
  9. use App\Models\Story;
  10. use App\Services\Session;
  11. use App\Services\Validator;
  12. use Psr\Http\Message\ResponseInterface as Response;
  13. use Psr\Http\Message\ServerRequestInterface as Request;
  14.  
  15. /**
  16. * RatingController
  17. */
  18. class RatingController extends Controller
  19. {
  20. public function __construct(
  21. protected Session $session,
  22. protected Validator $validator,
  23. ) {}
  24.  
  25. /**
  26. * Change rating
  27. *
  28. * @param int $id
  29. * @param Request $request
  30. * @param Response $response
  31. *
  32. * @return Response
  33. */
  34. public function change(int $id, Request $request, Response $response): Response
  35. {
  36. $input = (array) $request->getParsedBody();
  37.  
  38. $modelName = $this->getModelByType($input['type']);
  39.  
  40. if (! $modelName) {
  41. return $this->json($response, [
  42. 'success' => false,
  43. 'message' => 'Неверный тип записи!',
  44. ]);
  45. }
  46.  
  47. $model = $modelName::query()->find($id);
  48.  
  49. if (! $model) {
  50. return $this->json($response, [
  51. 'success' => false,
  52. 'message' => 'Запись не найдена!',
  53. ]);
  54. }
  55.  
  56. $this->validator
  57. ->required(['csrf', 'vote'])
  58. ->same('csrf', $this->session->get('csrf'), 'Неверный идентификатор сессии, повторите действие!')
  59. ->in('vote', ['+', '-'])
  60. ->custom($model->user_id !== getUser('id'), 'Нельзя изменять рейтинг своей записи!');
  61.  
  62. if ($this->validator->isValid($input)) {
  63.  
  64. $poll = Poll::query()
  65. ->where('entity_id', $id)
  66. ->where('entity_name', $input['type'])
  67. ->where('user_id', getUser('id'))
  68. ->first();
  69.  
  70. $cancel = false;
  71.  
  72. if ($poll) {
  73. if ($poll->vote === $input['vote']) {
  74. return $this->json($response, [
  75. 'success' => false,
  76. ]);
  77. }
  78.  
  79. $poll->delete();
  80. $cancel = true;
  81. } else {
  82. Poll::query()->create([
  83. 'user_id' => getUser('id'),
  84. 'entity_id' => $id,
  85. 'entity_name' => $input['type'],
  86. 'vote' => $input['vote'],
  87. 'created_at' => time(),
  88. ]);
  89. }
  90.  
  91. if ($input['vote'] === '+') {
  92. $rating = $model->rating + 1;
  93. } else {
  94. $rating = $model->rating - 1;
  95. }
  96.  
  97. $model->rating = $rating;
  98. $model->save();
  99.  
  100. return $this->json($response, [
  101. 'success' => true,
  102. 'cancel' => $cancel,
  103. 'rating' => $model->getRating(),
  104. ]);
  105. }
  106.  
  107. return $this->json($response, [
  108. 'success' => false,
  109. 'message' => current($this->validator->getErrors()),
  110. ]);
  111. }
  112.  
  113. /**
  114. * Get map types
  115. *
  116. * @return string[]
  117. */
  118. private function getMapTypes(): array
  119. {
  120. return [
  121. 'story' => Story::class,
  122. 'comment' => Comment::class,
  123. ];
  124. }
  125.  
  126. /**
  127. * Get model by type
  128. *
  129. * @param string $type
  130. *
  131. * @return string|null
  132. */
  133. private function getModelByType(string $type): ?string
  134. {
  135. return $this->getMapTypes()[$type] ?? null;
  136. }
  137. }