Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
95.00% |
38 / 40 |
|
0.00% |
0 / 1 |
CRAP | |
0.00% |
0 / 1 |
| ToggleTerminReactionEndpoint | |
95.00% |
38 / 40 |
|
0.00% |
0 / 1 |
14 | |
0.00% |
0 / 1 |
| handle | |
95.00% |
38 / 40 |
|
0.00% |
0 / 1 |
14 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Olz\Termine\Endpoints; |
| 4 | |
| 5 | use Olz\Api\OlzTypedEndpoint; |
| 6 | use Olz\Entity\Termine\Termin; |
| 7 | use Olz\Entity\Termine\TerminReaction; |
| 8 | use PhpTypeScriptApi\HttpError; |
| 9 | |
| 10 | /** |
| 11 | * @phpstan-import-type OlzReaction from ListTerminReactionsEndpoint |
| 12 | * |
| 13 | * @extends OlzTypedEndpoint< |
| 14 | * array{ |
| 15 | * terminId: int<1, max>, |
| 16 | * emoji: non-empty-string, |
| 17 | * action: 'on'|'off'|'toggle', |
| 18 | * }, |
| 19 | * array{ |
| 20 | * result: ?OlzReaction, |
| 21 | * } |
| 22 | * > |
| 23 | */ |
| 24 | class ToggleTerminReactionEndpoint extends OlzTypedEndpoint { |
| 25 | protected function handle(mixed $input): mixed { |
| 26 | $has_access = $this->authUtils()->hasPermission('any'); |
| 27 | $user = $this->authUtils()->getCurrentUser(); |
| 28 | if (!$has_access || !$user) { |
| 29 | throw new HttpError(403, 'Kein Zugriff'); |
| 30 | } |
| 31 | if (mb_strlen($input['emoji']) !== 1) { |
| 32 | throw new HttpError(400, 'Ungültiges Emoji'); |
| 33 | } |
| 34 | |
| 35 | $termin_reaction_repo = $this->entityManager()->getRepository(TerminReaction::class); |
| 36 | $reactions = $termin_reaction_repo->findBy([ |
| 37 | 'termin' => $input['terminId'], |
| 38 | 'emoji' => $input['emoji'], |
| 39 | 'user' => $user, |
| 40 | ]); |
| 41 | // Hack for prod not applying the emoji filter correctly. |
| 42 | $reactions = array_filter( |
| 43 | $reactions, |
| 44 | fn ($reaction) => $input['emoji'] === $reaction->getEmoji(), |
| 45 | ); |
| 46 | $has_reactions = count($reactions) > 0; |
| 47 | $want_reaction = $input['action'] === 'on' || ($input['action'] === 'toggle' && !$has_reactions); |
| 48 | $result = null; |
| 49 | |
| 50 | if (!$has_reactions && $want_reaction) { |
| 51 | $termin_repo = $this->entityManager()->getRepository(Termin::class); |
| 52 | $termin = $termin_repo->findOneBy(['id' => $input['terminId']]); |
| 53 | if (!$termin) { |
| 54 | throw new HttpError(400, "Kein solcher Termin"); |
| 55 | } |
| 56 | $reaction = new TerminReaction(); |
| 57 | $reaction->setTermin($termin); |
| 58 | $reaction->setUser($user); |
| 59 | $reaction->setEmoji($input['emoji']); |
| 60 | $this->entityManager()->persist($reaction); |
| 61 | $this->entityManager()->flush(); |
| 62 | $result = [ |
| 63 | 'userId' => $reaction->getUser()->getId() ?? 0, |
| 64 | 'name' => $reaction->getUser()->getFullName() ?: '?', |
| 65 | 'emoji' => $reaction->getEmoji() ?: '?', |
| 66 | ]; |
| 67 | } |
| 68 | if ($has_reactions && !$want_reaction) { |
| 69 | foreach ($reactions as $reaction) { |
| 70 | $this->entityManager()->remove($reaction); |
| 71 | } |
| 72 | $this->entityManager()->flush(); |
| 73 | } |
| 74 | |
| 75 | return ['result' => $result]; |
| 76 | } |
| 77 | } |