Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 115
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
OlzTermineListsTile
0.00% covered (danger)
0.00%
0 / 115
0.00% covered (danger)
0.00%
0 / 9
342
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRelevance
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHtml
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 renderAllUpcomingList
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 renderProgramList
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
42
 renderWeekendsList
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 renderTrophyList
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 renderUpcomingTrainingsList
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 getNumberOfEntries
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3// =============================================================================
4// Zeigt eine Startseiten-Kachel mit relevanten Termine-Links an.
5// =============================================================================
6
7namespace Olz\Startseite\Components\OlzTermineListsTile;
8
9use Olz\Entity\Users\User;
10use Olz\Startseite\Components\AbstractOlzTile\AbstractOlzTile;
11use Olz\Termine\Utils\TermineFilterUtils;
12
13class OlzTermineListsTile extends AbstractOlzTile {
14    private TermineFilterUtils $termine_utils;
15    private ?\mysqli $db = null;
16    private ?int $this_year = null;
17
18    public function __construct() {
19        $this->termine_utils = TermineFilterUtils::fromEnv();
20    }
21
22    public function getRelevance(?User $user): float {
23        return 0.8;
24    }
25
26    public function getHtml(mixed $args): string {
27        $this->termine_utils->loadTypeOptions();
28        $this->db = $this->dbUtils()->getDb();
29        $this->this_year = intval($this->dateUtils()->getCurrentDateInFormat('Y'));
30
31        $out = "<h3>Termine</h3>";
32
33        $out .= "<ul class='links'>";
34        $out .= $this->renderAllUpcomingList();
35        $out .= $this->renderProgramList();
36        $out .= $this->renderWeekendsList();
37        $out .= $this->renderTrophyList();
38        $out .= $this->renderUpcomingTrainingsList();
39        $out .= "</ul>";
40
41        return $out;
42    }
43
44    protected function renderAllUpcomingList(): string {
45        $code_href = $this->envUtils()->getCodeHref();
46        $icon = "{$code_href}assets/icns/termine_type_all_20.svg";
47        $icon_img = "<img src='{$icon}' alt='' class='link-icon'>";
48        $filter = $this->termine_utils->getDefaultFilter();
49        $filter['typ'] = 'alle';
50        $filter['datum'] = 'bevorstehend';
51        $enc_json_filter = urlencode(json_encode($filter) ?: '{}');
52        return <<<ZZZZZZZZZZ
53            <li><a href='{$code_href}termine?filter={$enc_json_filter}&von=startseite'>
54                {$icon_img} <b>Nächste Termine</b>
55            </a></li>
56            ZZZZZZZZZZ;
57    }
58
59    protected function renderProgramList(): string {
60        $code_href = $this->envUtils()->getCodeHref();
61        $icon = "{$code_href}assets/icns/termine_type_programm_20.svg";
62        $icon_img = "<img src='{$icon}' alt='' class='link-icon'>";
63        $this_year = $this->this_year;
64        $next_year = $this->this_year + 1;
65        $imminent_filter = [
66            ...$this->termine_utils->getDefaultFilter(),
67            'typ' => 'programm',
68            'datum' => 'bevorstehend',
69        ];
70        $this_year_filter = [
71            ...$this->termine_utils->getDefaultFilter(),
72            'typ' => 'programm',
73            'datum' => strval($this_year),
74        ];
75        $num_imminent = $this->getNumberOfEntries($imminent_filter);
76        $out = '';
77        if ($num_imminent > 0) {
78            $num_this_year = $this->getNumberOfEntries($this_year_filter);
79            $enc_json_filter = urlencode(json_encode($this_year_filter) ?: '{}');
80            $out .= <<<ZZZZZZZZZZ
81                <li><a href='{$code_href}termine?filter={$enc_json_filter}&von=startseite'>
82                    {$icon_img} <b>Jahresprogramm {$this_year}</b><span class='secondary'>({$num_this_year})</span>
83                </a></li>
84                ZZZZZZZZZZ;
85        }
86        $current_month = intval($this->dateUtils()->getCurrentDateInFormat('m'));
87        if ($current_month > 8) {
88            $next_year_filter = [
89                ...$this->termine_utils->getDefaultFilter(),
90                'typ' => 'programm',
91                'datum' => strval($next_year),
92            ];
93            $num_next_year = $this->getNumberOfEntries($next_year_filter);
94
95            if ($num_next_year > 0) {
96                $enc_json_filter = urlencode(json_encode($next_year_filter) ?: '{}');
97                $out .= <<<ZZZZZZZZZZ
98                    <li><a href='{$code_href}termine?filter={$enc_json_filter}&von=startseite'>
99                        {$icon_img} <b>Jahresprogramm {$next_year}</b><span class='secondary'>({$num_next_year})</span>
100                    </a></li>
101                    ZZZZZZZZZZ;
102            }
103        }
104        return $out;
105    }
106
107    protected function renderWeekendsList(): string {
108        $code_href = $this->envUtils()->getCodeHref();
109        $icon = "{$code_href}assets/icns/termine_type_weekend_20.svg";
110        $icon_img = "<img src='{$icon}' alt='' class='link-icon'>";
111        $imminent_filter = [
112            ...$this->termine_utils->getDefaultFilter(),
113            'typ' => 'weekend',
114            'datum' => 'bevorstehend',
115        ];
116        $num_imminent = $this->getNumberOfEntries($imminent_filter);
117        $enc_json_filter = urlencode(json_encode($imminent_filter) ?: '{}');
118        return <<<ZZZZZZZZZZ
119            <li><a href='{$code_href}termine?filter={$enc_json_filter}&von=startseite'>
120                {$icon_img} <b>Bevorstehende Weekends</b><span class='secondary'>({$num_imminent})</span>
121            </a></li>
122            ZZZZZZZZZZ;
123    }
124
125    protected function renderTrophyList(): string {
126        $code_href = $this->envUtils()->getCodeHref();
127        $icon = "{$code_href}assets/icns/termine_type_trophy_20.svg";
128        $icon_img = "<img src='{$icon}' alt='' class='link-icon'>";
129        $this_year = $this->this_year;
130        $this_year_filter = [
131            ...$this->termine_utils->getDefaultFilter(),
132            'typ' => 'trophy',
133            'datum' => strval($this_year),
134        ];
135        $num_this_year = $this->getNumberOfEntries($this_year_filter);
136        $enc_json_filter = urlencode(json_encode($this_year_filter) ?: '{}');
137        return <<<ZZZZZZZZZZ
138            <li><a href='{$code_href}termine?filter={$enc_json_filter}&von=startseite'>
139                {$icon_img} <b>OLZ Trophy {$this_year}</b><span class='secondary'>({$num_this_year})</span>
140            </a></li>
141            ZZZZZZZZZZ;
142    }
143
144    protected function renderUpcomingTrainingsList(): string {
145        $code_href = $this->envUtils()->getCodeHref();
146        $icon = "{$code_href}assets/icns/termine_type_training_20.svg";
147        $icon_img = "<img src='{$icon}' alt='' class='link-icon'>";
148        $imminent_filter = [
149            ...$this->termine_utils->getDefaultFilter(),
150            'typ' => 'training',
151            'datum' => 'bevorstehend',
152        ];
153        $enc_json_filter = urlencode(json_encode($imminent_filter) ?: '{}');
154        return <<<ZZZZZZZZZZ
155            <li><a href='{$code_href}termine?filter={$enc_json_filter}&von=startseite'>
156                {$icon_img} <b>Nächste Trainings</b>
157            </a></li>
158            ZZZZZZZZZZ;
159    }
160
161    /** @param array{typ?: string, datum?: string, archiv?: string} $filter */
162    protected function getNumberOfEntries(array $filter): int {
163        $date_filter = $this->termine_utils->getSqlDateRangeFilter($filter, 'c');
164        $type_filter = $this->termine_utils->getSqlTypeFilter($filter, 'c');
165        $filter_sql = "({$date_filter}) AND ({$type_filter})";
166        $sql = <<<ZZZZZZZZZZ
167            SELECT * 
168            FROM (
169                SELECT
170                    t.id AS id,
171                    t.start_date AS start_date,
172                    t.end_date AS end_date,
173                    (
174                        SELECT GROUP_CONCAT(l.ident ORDER BY l.position ASC SEPARATOR ' ')
175                        FROM
176                            termin_label_map tl
177                            JOIN termin_labels l ON (l.id = tl.label_id)
178                        WHERE tl.termin_id = t.id
179                        GROUP BY t.id
180                    ) as typ
181                FROM termine t
182            ) AS c
183            WHERE {$filter_sql}
184            ZZZZZZZZZZ;
185        $res = $this->db?->query($sql);
186        // @phpstan-ignore-next-line
187        return $res->num_rows;
188    }
189}