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