Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
OlzSucheParams
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
OlzSuche
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 5
182
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
 getTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDescription
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 / 26
0.00% covered (danger)
0.00%
0 / 1
2
 getHtmlWhenHasAccess
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2
3namespace Olz\Suche\Components\OlzSuche;
4
5use Olz\Components\Common\OlzPostingListItem\OlzPostingListItem;
6use Olz\Components\Common\OlzRootComponent;
7use Olz\Components\Page\OlzFooter\OlzFooter;
8use Olz\Components\Page\OlzHeader\OlzHeader;
9use Olz\Utils\HttpParams;
10
11/** @extends HttpParams<array{anfrage: string}> */
12class OlzSucheParams extends HttpParams {
13}
14
15/** @extends OlzRootComponent<array<string, mixed>> */
16class OlzSuche extends OlzRootComponent {
17    public function hasAccess(): bool {
18        return true;
19    }
20
21    public function getTitle(): string {
22        return "Suche";
23    }
24
25    public function getDescription(string $pretty_terms): string {
26        return "Stichwort-Suche nach \"{$pretty_terms}\" auf der Website der OL Zimmerberg.";
27    }
28
29    public string $description = "Stichwort-Suche auf der Website der OL Zimmerberg.";
30
31    public function searchSqlWhenHasAccess(array $terms): string|array|null {
32        $code_href = $this->envUtils()->getCodeHref();
33        $db = $this->dbUtils()->getDb();
34        $esc_title = $db->real_escape_string($this->getTitle());
35        $esc_content = $db->real_escape_string($this->getDescription('Suche'));
36        $where = implode(' AND ', array_map(function ($term) {
37            return <<<ZZZZZZZZZZ
38                (
39                    title LIKE '%{$term}%'
40                    OR text LIKE '%{$term}%'
41                )
42                ZZZZZZZZZZ;
43        }, $terms));
44        return [
45            'with' => [
46                <<<ZZZZZZZZZZ
47                    base_suche AS (
48                        SELECT
49                            '{$code_href}suche?anfrage=Suche' AS link,
50                            '{$code_href}assets/icns/magnifier_16.svg' AS icon,
51                            NULL AS date,
52                            '{$esc_title}' AS title,
53                            '{$esc_content}' AS text
54                    )
55                    ZZZZZZZZZZ,
56            ],
57            'query' => <<<ZZZZZZZZZZ
58                    SELECT
59                        link, icon, date, title, text,
60                        0.9 AS time_relevance
61                    FROM base_suche
62                    WHERE {$where}
63                ZZZZZZZZZZ,
64        ];
65    }
66
67    public function getHtmlWhenHasAccess(mixed $args): string {
68        $params = $this->httpUtils()->validateGetParams(OlzSucheParams::class);
69
70        $terms = preg_split('/[\s,\.;]+/', $params['anfrage']);
71        $this->generalUtils()->checkNotFalse($terms, "Could not split search terms '{$params['anfrage']}'");
72        $pretty_terms = implode(', ', $terms);
73        $esc_pretty_terms = htmlspecialchars($pretty_terms);
74
75        $out = OlzHeader::render([
76            'title' => "\"{$pretty_terms}\" - {$this->getTitle()}",
77            'description' => $this->getDescription($pretty_terms),
78        ]);
79
80        $out .= <<<'ZZZZZZZZZZ'
81            <div class='content-right'>
82            </div>
83            <div class='content-middle olz-suche'>
84            ZZZZZZZZZZ;
85
86        $out .= "<h1>Suchresultate für \"{$esc_pretty_terms}\"</h1>";
87
88        if (($terms[0] ?? '') === '') {
89            $out .= "<p><i>Keine Resultate</i></p>";
90            $out .= OlzFooter::render();
91            return $out;
92        }
93
94        $start_time = microtime(true);
95
96        $results = $this->searchUtils()->getSearchResults($terms);
97        foreach ($results as $result) {
98            $pretty_date = null;
99            if ($result['date']) {
100                $pretty_date = $this->dateUtils()->olzDate("tt.mm.jj", $result['date']);
101                $date_formattings = implode(' ', $this->searchUtils()->getDateFormattings($result['date']));
102                $is_date_matching = false;
103                foreach ($terms as $term) {
104                    $esc_term = preg_quote($term);
105                    if (preg_match("/{$esc_term}/i", $date_formattings)) {
106                        $is_date_matching = true;
107                        break;
108                    }
109                }
110                if ($is_date_matching) {
111                    $pretty_date = $this->searchUtils()->highlight($pretty_date, [$pretty_date]);
112                }
113            }
114            $pretty_debug = $this->authUtils()->hasPermission('all') ? "<pre>{$result['debug']}</pre>" : '';
115            $out .= OlzPostingListItem::render([
116                'link' => $result['link'],
117                'icon' => $result['icon'],
118                'date' => $pretty_date,
119                'title' => $this->searchUtils()->highlight($result['title'], $terms),
120                'text' => $pretty_debug.$this->searchUtils()->highlight($result['text'] ?? '', $terms),
121            ]);
122        }
123        if (count($results) === 0) {
124            $out .= "<p><i>Keine Resultate</i></p>";
125        }
126
127        $duration = microtime(true) - $start_time;
128        $pretty_duration = number_format($duration, 3, '.', '\'');
129        $this->log()->info("Search for '{$pretty_terms}' took {$pretty_duration}s.");
130
131        $out .= "</div>";
132
133        $out .= OlzFooter::render();
134        return $out;
135    }
136}