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