Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
TerminEndpointTrait
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 7
306
0.00% covered (danger)
0.00%
0 / 1
 configureTerminEndpointTrait
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getEntityData
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
20
 updateEntityWithData
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
30
 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
 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\Termin;
6use Olz\Entity\Termine\TerminLabel;
7use Olz\Entity\Termine\TerminLocation;
8use Olz\Entity\Termine\TerminTemplate;
9use Olz\Utils\WithUtilsTrait;
10use PhpTypeScriptApi\HttpError;
11use PhpTypeScriptApi\PhpStan\IsoDate;
12use PhpTypeScriptApi\PhpStan\IsoDateTime;
13use PhpTypeScriptApi\PhpStan\IsoTime;
14
15/**
16 * @phpstan-type OlzTerminId int
17 * @phpstan-type OlzTerminData array{
18 *   fromTemplateId?: ?int,
19 *   startDate?: ?IsoDate,
20 *   startTime?: ?IsoTime,
21 *   endDate?: ?IsoDate,
22 *   endTime?: ?IsoTime,
23 *   title?: ?non-empty-string,
24 *   text: string,
25 *   deadline?: ?IsoDateTime,
26 *   shouldPromote: bool,
27 *   newsletter: bool,
28 *   solvId?: ?int,
29 *   go2olId?: ?non-empty-string,
30 *   types: array<non-empty-string>,
31 *   locationId?: ?int,
32 *   coordinateX?: ?int,
33 *   coordinateY?: ?int,
34 *   imageIds: array<non-empty-string>,
35 *   fileIds: array<non-empty-string>,
36 * }
37 */
38trait TerminEndpointTrait {
39    use WithUtilsTrait;
40
41    public function configureTerminEndpointTrait(): void {
42        $this->phpStanUtils->registerApiObject(IsoDate::class);
43        $this->phpStanUtils->registerApiObject(IsoTime::class);
44        $this->phpStanUtils->registerApiObject(IsoDateTime::class);
45    }
46
47    /** @return OlzTerminData */
48    public function getEntityData(Termin $entity): array {
49        $types_for_api = $this->getTypesForApi($entity->getLabels());
50
51        $valid_image_ids = $this->uploadUtils()->getValidUploadIds($entity->getImageIds());
52        $file_ids = $entity->getStoredFileUploadIds();
53
54        return [
55            'fromTemplateId' => $entity->getFromTemplate()?->getId(),
56            'startDate' => IsoDate::fromDateTime($entity->getStartDate()),
57            'startTime' => IsoTime::fromDateTime($entity->getStartTime()),
58            'endDate' => IsoDate::fromDateTime($entity->getEndDate()),
59            'endTime' => IsoTime::fromDateTime($entity->getEndTime()),
60            'title' => $entity->getTitle() ?: '-',
61            'text' => $entity->getText() ?? '',
62            'deadline' => IsoDateTime::fromDateTime($entity->getDeadline()),
63            'shouldPromote' => $entity->getShouldPromote(),
64            'newsletter' => $entity->getNewsletter(),
65            'solvId' => $entity->getSolvId() ?: null,
66            'go2olId' => $entity->getGo2olId() ?: null,
67            'types' => $types_for_api,
68            'locationId' => $entity->getLocation()?->getId(),
69            'coordinateX' => $entity->getCoordinateX(),
70            'coordinateY' => $entity->getCoordinateY(),
71            'imageIds' => $valid_image_ids,
72            'fileIds' => $file_ids,
73        ];
74    }
75
76    /** @param OlzTerminData $input_data */
77    public function updateEntityWithData(Termin $entity, array $input_data): void {
78        $valid_image_ids = $this->uploadUtils()->getValidUploadIds($input_data['imageIds']);
79        $termin_template_repo = $this->entityManager()->getRepository(TerminTemplate::class);
80        $from_template_id = $input_data['fromTemplateId'] ?? null;
81        $termin_template = $termin_template_repo->findOneBy(['id' => $from_template_id]);
82        $termin_label_repo = $this->entityManager()->getRepository(TerminLabel::class);
83        $termin_location_repo = $this->entityManager()->getRepository(TerminLocation::class);
84        $location_id = $input_data['locationId'] ?? null;
85        $termin_location = $termin_location_repo->findOneBy(['id' => $location_id]);
86
87        $entity->setFromTemplate($termin_template);
88        $entity->setStartDate($input_data['startDate'] ?? new \DateTime());
89        $entity->setStartTime($input_data['startTime'] ?? null);
90        $entity->setEndDate($input_data['endDate'] ?? null);
91        $entity->setEndTime($input_data['endTime'] ?? null);
92        $entity->setTitle($input_data['title'] ?? null);
93        $entity->setText($input_data['text']);
94        $entity->setDeadline($input_data['deadline'] ?? null);
95        if (count($valid_image_ids) > 0) {
96            $entity->setShouldPromote($input_data['shouldPromote']);
97        } else {
98            $entity->setShouldPromote(false);
99        }
100        $entity->setNewsletter($input_data['newsletter']);
101        $entity->setSolvId($input_data['solvId'] ?? null);
102        $entity->setGo2olId($input_data['go2olId'] ?? null);
103        $entity->clearLabels();
104        foreach ($input_data['types'] as $ident) {
105            $termin_label = $termin_label_repo->findOneBy(['ident' => $ident]);
106            if (!$termin_label) {
107                throw new HttpError(400, "No such TerminLabel: {$ident}");
108            }
109            $entity->addLabel($termin_label);
110        }
111        $entity->setLocation($termin_location);
112        $entity->setCoordinateX($input_data['coordinateX'] ?? null);
113        $entity->setCoordinateY($input_data['coordinateY'] ?? null);
114        $entity->setImageIds($valid_image_ids);
115
116        if ($entity->getSolvId() !== null) {
117            $this->termineUtils()->updateTerminFromSolvEvent($entity);
118        }
119    }
120
121    /** @param OlzTerminData $input_data */
122    public function persistUploads(Termin $entity, array $input_data): void {
123        $this->persistOlzImages($entity, $entity->getImageIds());
124        $this->persistOlzFiles($entity, $input_data['fileIds']);
125    }
126
127    public function editUploads(Termin $entity): void {
128        $this->editOlzImages($entity, $entity->getImageIds());
129        $this->editOlzFiles($entity);
130    }
131
132    protected function getEntityById(int $id): Termin {
133        $repo = $this->entityManager()->getRepository(Termin::class);
134        $entity = $repo->findOneBy(['id' => $id]);
135        if (!$entity) {
136            throw new HttpError(404, "Nicht gefunden.");
137        }
138        return $entity;
139    }
140
141    // ---
142
143    /**
144     * @param ?iterable<TerminLabel> $labels
145     *
146     * @return array<non-empty-string>
147     */
148    protected function getTypesForApi(?iterable $labels): array {
149        $types_for_api = [];
150        foreach ($labels ?? [] as $label) {
151            $ident = $label->getIdent();
152            if ($ident) {
153                $types_for_api[] = $ident;
154            }
155        }
156        return $types_for_api;
157    }
158}