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