Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.65% covered (success)
93.65%
59 / 63
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
TerminTemplateEndpointTrait
93.65% covered (success)
93.65%
59 / 63
62.50% covered (warning)
62.50%
5 / 8
16.07
0.00% covered (danger)
0.00%
0 / 1
 getEntityData
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
1
 updateEntityWithData
91.30% covered (success)
91.30%
21 / 23
0.00% covered (danger)
0.00%
0 / 1
4.01
 persistUploads
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 editUploads
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getEntityById
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getDurationSeconds
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getDeadlineEarlierSeconds
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getTypesForApi
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Olz\Termine\Endpoints;
4
5use Olz\Entity\Termine\TerminLabel;
6use Olz\Entity\Termine\TerminLocation;
7use Olz\Entity\Termine\TerminTemplate;
8use Olz\Utils\WithUtilsTrait;
9use PhpTypeScriptApi\HttpError;
10use PhpTypeScriptApi\PhpStan\IsoTime;
11
12/**
13 * @phpstan-type OlzTerminTemplateId int
14 * @phpstan-type OlzTerminTemplateData array{
15 *   startTime?: ?IsoTime,
16 *   durationSeconds?: ?int<0, max>,
17 *   title: string,
18 *   text: string,
19 *   deadlineEarlierSeconds?: ?int<0, max>,
20 *   deadlineTime?: ?IsoTime,
21 *   shouldPromote: bool,
22 *   newsletter: bool,
23 *   types: array<non-empty-string>,
24 *   locationId?: ?int,
25 *   imageIds: array<non-empty-string>,
26 *   fileIds: array<non-empty-string>,
27 * }
28 */
29trait TerminTemplateEndpointTrait {
30    use WithUtilsTrait;
31
32    /** @return OlzTerminTemplateData */
33    public function getEntityData(TerminTemplate $entity): array {
34        $types_for_api = $this->getTypesForApi($entity->getLabels());
35
36        $valid_image_ids = $this->uploadUtils()->getValidUploadIds($entity->getImageIds());
37        $file_ids = $entity->getStoredFileUploadIds();
38
39        return [
40            'startTime' => IsoTime::fromDateTime($entity->getStartTime()),
41            'durationSeconds' => $this->getDurationSeconds($entity),
42            'title' => $entity->getTitle() ?? '',
43            'text' => $entity->getText() ?? '',
44            'deadlineEarlierSeconds' => $this->getDeadlineEarlierSeconds($entity),
45            'deadlineTime' => IsoTime::fromDateTime($entity->getDeadlineTime()),
46            'shouldPromote' => $entity->getShouldPromote(),
47            'newsletter' => $entity->getNewsletter(),
48            'types' => $types_for_api,
49            'locationId' => $entity->getLocation()?->getId(),
50            'imageIds' => $valid_image_ids,
51            'fileIds' => $file_ids,
52        ];
53    }
54
55    /** @param OlzTerminTemplateData $input_data */
56    public function updateEntityWithData(TerminTemplate $entity, array $input_data): void {
57        $valid_image_ids = $this->uploadUtils()->getValidUploadIds($input_data['imageIds']);
58        $termin_label_repo = $this->entityManager()->getRepository(TerminLabel::class);
59        $termin_location_repo = $this->entityManager()->getRepository(TerminLocation::class);
60        $location_id = $input_data['locationId'] ?? null;
61        $termin_location = $termin_location_repo->findOneBy(['id' => $location_id]);
62
63        $entity->setStartTime($input_data['startTime'] ?? null);
64        $entity->setDurationSeconds($input_data['durationSeconds'] ?? null);
65        $entity->setTitle($input_data['title']);
66        $entity->setText($input_data['text']);
67        $entity->setDeadlineEarlierSeconds($input_data['deadlineEarlierSeconds'] ?? null);
68        $entity->setDeadlineTime($input_data['deadlineTime'] ?? null);
69        if (count($valid_image_ids) > 0) {
70            $entity->setShouldPromote($input_data['shouldPromote']);
71        } else {
72            $entity->setShouldPromote(false);
73        }
74        $entity->setNewsletter($input_data['newsletter']);
75        $entity->clearLabels();
76        foreach ($input_data['types'] as $ident) {
77            $termin_label = $termin_label_repo->findOneBy(['ident' => $ident]);
78            if (!$termin_label) {
79                throw new HttpError(400, "No such TerminLabel: {$ident}");
80            }
81            $entity->addLabel($termin_label);
82        }
83        $entity->setLocation($termin_location);
84        $entity->setImageIds($valid_image_ids);
85    }
86
87    /** @param OlzTerminTemplateData $input_data */
88    public function persistUploads(TerminTemplate $entity, array $input_data): void {
89        $this->persistOlzImages($entity, $entity->getImageIds());
90        $this->persistOlzFiles($entity, $input_data['fileIds']);
91    }
92
93    public function editUploads(TerminTemplate $entity): void {
94        $this->editOlzImages($entity, $entity->getImageIds());
95        $this->editOlzFiles($entity);
96    }
97
98    protected function getEntityById(int $id): TerminTemplate {
99        $repo = $this->entityManager()->getRepository(TerminTemplate::class);
100        $entity = $repo->findOneBy(['id' => $id]);
101        if (!$entity) {
102            throw new HttpError(404, "Nicht gefunden.");
103        }
104        return $entity;
105    }
106
107    // ---
108
109    /** @return ?int<0, max> */
110    protected function getDurationSeconds(TerminTemplate $entity): ?int {
111        $number = $entity->getDurationSeconds() ?? null;
112        if ($number < 0) {
113            throw new \Exception("Invalid duration seconds: {$number} ({$entity})");
114        }
115        return $number;
116    }
117
118    /** @return ?int<0, max> */
119    protected function getDeadlineEarlierSeconds(TerminTemplate $entity): ?int {
120        $number = $entity->getDeadlineEarlierSeconds() ?? null;
121        if ($number < 0) {
122            throw new \Exception("Invalid deadline earlier seconds: {$number} ({$entity})");
123        }
124        return $number;
125    }
126
127    /**
128     * @param ?iterable<TerminLabel> $labels
129     *
130     * @return array<non-empty-string>
131     */
132    protected function getTypesForApi(?iterable $labels): array {
133        $types_for_api = [];
134        foreach ($labels ?? [] as $label) {
135            $ident = $label->getIdent();
136            if ($ident) {
137                $types_for_api[] = $ident;
138            }
139        }
140        return $types_for_api;
141    }
142}