Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 159
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
OlzTerminTemplateDetailParams
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
OlzTerminTemplateDetail
0.00% covered (danger)
0.00%
0 / 159
0.00% covered (danger)
0.00%
0 / 6
380
0.00% covered (danger)
0.00%
0 / 1
 hasAccess
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 searchSqlWhenHasAccess
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
2
 getPageTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPageDescription
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHtmlWhenHasAccess
0.00% covered (danger)
0.00%
0 / 136
0.00% covered (danger)
0.00%
0 / 1
210
 getTerminTemplateById
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Olz\Termine\Components\OlzTerminTemplateDetail;
4
5use Olz\Common\Components\OlzLocationMap\OlzLocationMap;
6use Olz\Common\Components\OlzRootComponent;
7use Olz\Components\Page\OlzFooter\OlzFooter;
8use Olz\Components\Page\OlzHeader\OlzHeader;
9use Olz\Entity\Termine\TerminLabel;
10use Olz\Entity\Termine\TerminNotificationTemplate;
11use Olz\Entity\Termine\TerminTemplate;
12use Olz\Users\Components\OlzUserInfoModal\OlzUserInfoModal;
13use Olz\Utils\HttpParams;
14
15/** @extends HttpParams<array{filter?: ?string}> */
16class OlzTerminTemplateDetailParams extends HttpParams {
17}
18
19/** @extends OlzRootComponent<array<string, mixed>> */
20class OlzTerminTemplateDetail extends OlzRootComponent {
21    public function hasAccess(): bool {
22        return $this->authUtils()->hasPermission('termine');
23    }
24
25    public function searchSqlWhenHasAccess(array $terms): string|array|null {
26        $code_href = $this->envUtils()->getCodeHref();
27        $where = implode(' AND ', array_map(function ($term) {
28            return <<<ZZZZZZZZZZ
29                (
30                    tt.title LIKE '%{$term}%'
31                    OR tt.text LIKE '%{$term}%'
32                    OR tl.name LIKE '%{$term}%'
33                )
34                ZZZZZZZZZZ;
35        }, $terms));
36        return <<<ZZZZZZZZZZ
37            SELECT
38                CONCAT('{$code_href}termine/vorlagen/', tt.id) AS link,
39                '{$code_href}assets/icns/termine_type_all_20.svg' AS icon,
40                NULL AS date,
41                CONCAT('Termin-Vorlage: ', tt.title) AS title,
42                CONCAT(IFNULL(tl.name, ''), ' ', IFNULL(tt.text, ''), ' Typ: ', (
43                    SELECT GROUP_CONCAT(l.name ORDER BY l.position ASC SEPARATOR ', ')
44                    FROM
45                        termin_template_label_map ttlm
46                        JOIN termin_labels l ON (l.id = ttlm.label_id)
47                    WHERE ttlm.termin_template_id = tt.id
48                    GROUP BY tt.id
49                )) AS text,
50                1.0 AS time_relevance
51            FROM termin_templates tt LEFT JOIN termin_locations tl ON (tt.location_id = tl.id)
52            WHERE
53                tt.on_off = '1'
54                AND {$where}
55            ZZZZZZZZZZ;
56    }
57
58    public function getPageTitle(): string {
59        return "";
60    }
61
62    public function getPageDescription(): string {
63        return "";
64    }
65
66    public function getHtmlWhenHasAccess(mixed $args): string {
67        $this->httpUtils()->validateGetParams(OlzTerminTemplateDetailParams::class);
68
69        $code_href = $this->envUtils()->getCodeHref();
70        $code_path = $this->envUtils()->getCodePath();
71        $id = $args['id'] ?? null;
72
73        $termin_template = $this->getTerminTemplateById($id);
74
75        if (!$termin_template) {
76            $this->httpUtils()->dieWithHttpError(404);
77            throw new \Exception('should already have failed');
78        }
79
80        $title = $termin_template->getTitle() ?? '';
81        $back_link = "{$code_href}termine/vorlagen";
82        $out = OlzHeader::render([
83            'back_link' => $back_link,
84            'title' => "{$title} - Vorlagen",
85            'description' => "Vorlagen, um OL Zimmerberg-Termine zu erstellen.",
86            'norobots' => true,
87        ]);
88
89        // Creation Tools
90        $esc_template_id = json_encode($id);
91        $creation_tools = <<<ZZZZZZZZZZ
92            <div>
93                <button
94                    id='create-termin-template-button'
95                    class='btn btn-secondary'
96                    onclick='return olz.initOlzEditTerminModal(undefined, {$esc_template_id})'
97                >
98                    <img src='{$code_href}assets/icns/new_white_16.svg' class='noborder' />
99                    Neuer Termin aus dieser Vorlage
100                </button>
101            </div>
102            ZZZZZZZZZZ;
103
104        $out .= <<<ZZZZZZZZZZ
105            <div class='content-right'>
106                <div style='padding:4px 3px 10px 3px;'>
107                    {$creation_tools}
108                </div>
109            </div>
110            <div class='content-middle'>
111            ZZZZZZZZZZ;
112
113        $start_time = $termin_template->getStartTime() ?? '';
114        $duration_seconds = $termin_template->getDurationSeconds() ?? '';
115        $title = $termin_template->getTitle() ?? '';
116        $text = $termin_template->getText() ?? '';
117        $organizer = $termin_template->getOrganizerUser();
118        $labels = [...$termin_template->getLabels()];
119        $termin_location = $termin_template->getLocation();
120        $image_ids = $termin_template->getImageIds();
121
122        $out .= "<div class='olz-termin-template-detail'>";
123
124        // Editing Tools
125        $json_id = json_encode($id);
126        $out .= <<<ZZZZZZZZZZ
127            <div>
128                <button
129                    id='edit-termin-template-button'
130                    class='btn btn-primary'
131                    onclick='return olz.editTerminTemplate({$json_id})'
132                >
133                    <img src='{$code_href}assets/icns/edit_white_16.svg' class='noborder' />
134                    Bearbeiten
135                </button>
136            </div>
137            ZZZZZZZZZZ;
138        $add_termin_notification_template_admin = <<<ZZZZZZZZZZ
139            <div>
140                <button
141                    id='add-termin-notification-template-button'
142                    class='btn btn-primary'
143                    onclick='return olz.addTerminNotificationTemplate({$json_id})'
144                >
145                    <img src='{$code_href}assets/icns/new_white_16.svg' class='noborder' />
146                    Neue Benachrichtigung
147                </button>
148            </div>
149            ZZZZZZZZZZ;
150
151        $pretty_date = '(irgendwann)';
152        $duration_interval = \DateInterval::createFromDateString("+{$duration_seconds} seconds");
153        if ($start_time) {
154            $end_time = (clone $start_time)->add($duration_interval);
155            $pretty_date = $duration_seconds
156                ? $start_time->format('H:i')." – ".$end_time->format('H:i')
157                : $start_time->format('H:i');
158        }
159        $labels_html = implode('', array_map(function (TerminLabel $label) use ($code_path, $code_href) {
160            $ident = $label->getIdent();
161            // TODO: Remove fallback mechanism?
162            $fallback_path = "{$code_path}assets/icns/termine_type_{$ident}_20.svg";
163            $fallback_href = is_file($fallback_path)
164                ? "{$code_href}assets/icns/termine_type_{$ident}_20.svg" : null;
165            $icon_href = $label->getIcon() ? $label->getFileHref($label->getIcon()) : $fallback_href;
166            return $icon_href ? <<<ZZZZZZZZZZ
167                <div class='filter'>
168                    <img src='{$icon_href}' alt='' class='type-icon'>{$label->getName()}
169                </div>
170                ZZZZZZZZZZ : '';
171        }, $labels));
172        $out .= "<h5>{$pretty_date}</h5>";
173        $out .= "<h1>{$title}</h1>";
174        $out .= "<div class='filters'>{$labels_html}</div>";
175        if ($organizer) {
176            $pretty_organizer = OlzUserInfoModal::render(['user' => $organizer]);
177            $out .= "<div>Organisator: {$pretty_organizer}</div><br>";
178        }
179
180        if ($termin_location) {
181            $out .= OlzLocationMap::render([
182                'name' => $termin_location->getName(),
183                'latitude' => $termin_location->getLatitude(),
184                'longitude' => $termin_location->getLongitude(),
185                'zoom' => 13,
186            ]);
187        }
188
189        $text_html = $this->htmlUtils()->renderMarkdown($text);
190        $text_html = $termin_template->replaceImagePaths($text_html);
191        $text_html = $termin_template->replaceFilePaths($text_html);
192        $out .= "<div class='text'>{$text_html}</div>";
193
194        if (count($image_ids) > 0) {
195            $out .= "<h3>Bilder</h3><div class='lightgallery gallery-container'>";
196            foreach ($image_ids as $image_id) {
197                $out .= "<div class='gallery-image'>";
198                $out .= $this->imageUtils()->olzImage(
199                    'termin_templates',
200                    $id,
201                    $image_id,
202                    128,
203                    'gallery[myset]'
204                );
205                $out .= "</div>";
206            }
207            $out .= "</div>";
208        }
209
210        // Reactions
211        $linked_reactions = $this->htmlUtils()->getLinkedReactions($text_html);
212        $json_reactions = json_encode($linked_reactions) ?: '[]';
213        $out .= "<div id='termin-template-reactions'></div><script>olz.initTerminTemplateReactions({$json_reactions});</script>";
214
215        // Termin Notification Templates
216        $termin_notification_repo = $this->entityManager()->getRepository(TerminNotificationTemplate::class);
217        $termin_notifications = $termin_notification_repo->findBy(
218            ['termin_template' => $termin_template],
219            ['fires_earlier_seconds' => 'DESC'],
220        );
221        $num_termin_notifications = count($termin_notifications);
222        $out .= "<div id='termin-notification-templates'>";
223        if ($num_termin_notifications === 0) {
224            $out .= "<p><i>Keine Benachrichtigungen</i></p>";
225            $out .= $add_termin_notification_template_admin;
226        } else {
227            $out .= $add_termin_notification_template_admin;
228            $out .= "<table id='termin-notification-templates-table' class='boxy'>";
229            $out .= "<tr><th>Zeitpunkt</th><th>Titel</th><th>Empfänger</th></tr>";
230            foreach ($termin_notifications as $termin_notification) {
231                $out .= "<tr class='termin-notification-template'>";
232                $json_id = json_encode(intval($termin_notification->getId()));
233                $row_admin = <<<ZZZZZZZZZZ
234                    <button
235                        id='edit-termin-notification-template-button-{$json_id}'
236                        class='btn btn-secondary-outline btn-sm edit-termin-notification-template-button'
237                        onclick='return olz.editTerminNotificationTemplate({$json_id})'
238                    >
239                        <img src='{$code_href}assets/icns/edit_16.svg' class='noborder' />
240                    </button>
241                    ZZZZZZZZZZ;
242                $pretty_fires_earlier = $this->dateUtils()->formatDateInterval(
243                    $termin_notification->getFiresEarlierSeconds()
244                );
245                $pretty_recipients = implode('', array_map(
246                    fn ($recipient) => "<div>{$recipient}</div>",
247                    $this->termineUtils()->formatNotificationRecipients($termin_notification),
248                ));
249                $out .= "<td>{$row_admin}{$pretty_fires_earlier} vorher</td>";
250                $out .= "<td><b>{$termin_notification->getTitle()}</b></td>";
251                $out .= "<td>{$pretty_recipients}</td>";
252                $out .= "</tr>";
253            }
254            $out .= "</table>";
255        }
256        $out .= "</div>";
257
258        $out .= "</div>"; // olz-termin-template-detail
259        $out .= "</div>"; // content-middle
260
261        $out .= OlzFooter::render();
262
263        return $out;
264    }
265
266    protected function getTerminTemplateById(int $id): ?TerminTemplate {
267        $termin_template_repo = $this->entityManager()->getRepository(TerminTemplate::class);
268        return $termin_template_repo->findOneBy([
269            'id' => $id,
270            'on_off' => 1,
271        ]);
272    }
273}