Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
34 / 34
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
RatingStatistics
100.00% covered (success)
100.00%
34 / 34
100.00% covered (success)
100.00%
4 / 4
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAll
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 buildQuery
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 mapRowToRating
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * The Rating statistics class for the administration.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2024-2026 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2024-03-29
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Administration;
21
22use phpMyFAQ\Configuration;
23use phpMyFAQ\Database;
24use phpMyFAQ\Link\Util\TitleSlugifier;
25use phpMyFAQ\Strings;
26
27readonly class RatingStatistics
28{
29    public function __construct(
30        private Configuration $configuration,
31    ) {
32    }
33
34    /**
35     * Returns all ratings of FAQ records.
36     */
37    public function getAll(): array
38    {
39        $ratings = [];
40        $query = $this->buildQuery();
41        $result = $this->configuration->getDb()->query($query);
42
43        while (true) {
44            $row = $this->configuration->getDb()->fetchObject($result);
45            if (!is_object($row)) {
46                break;
47            }
48
49            $ratings[] = $this->mapRowToRating($row);
50        }
51
52        return $ratings;
53    }
54
55    private function buildQuery(): string
56    {
57        $prefix = Database::getTablePrefix();
58        return match (Database::getType()) {
59            'sqlsrv' => sprintf('
60                    SELECT
61                        fd.id AS id,
62                        fd.lang AS lang,
63                        fcr.category_id AS category_id,
64                        CAST(fd.thema as char(2000)) AS question,
65                        (fv.vote / fv.usr) AS num,
66                        fv.usr AS usr
67                    FROM
68                        %sfaqvoting fv,
69                        %sfaqdata fd
70                    LEFT JOIN
71                        %sfaqcategoryrelations fcr
72                    ON
73                        fd.id = fcr.record_id
74                    AND
75                        fd.lang = fcr.record_lang
76                    WHERE
77                        fd.id = fv.artikel
78                    GROUP BY
79                        fd.id,
80                        fd.lang,
81                        fd.active,
82                        fcr.category_id,
83                        CAST(fd.thema as char(2000)),
84                        fv.vote,
85                        fv.usr
86                    ORDER BY
87                        fcr.category_id', $prefix, $prefix, $prefix),
88            default => sprintf('
89                    SELECT
90                        fd.id AS id,
91                        fd.lang AS lang,
92                        fcr.category_id AS category_id,
93                        fd.thema AS question,
94                        (fv.vote / fv.usr) AS num,
95                        fv.usr AS usr
96                    FROM
97                        %sfaqvoting fv,
98                        %sfaqdata fd
99                    LEFT JOIN
100                        %sfaqcategoryrelations fcr
101                    ON
102                        fd.id = fcr.record_id
103                    AND
104                        fd.lang = fcr.record_lang
105                    WHERE
106                        fd.id = fv.artikel
107                    GROUP BY
108                        fd.id,
109                        fd.lang,
110                        fd.active,
111                        fcr.category_id,
112                        fd.thema,
113                        fv.vote,
114                        fv.usr
115                    ORDER BY
116                        fcr.category_id', $prefix, $prefix, $prefix),
117        };
118    }
119
120    private function mapRowToRating(\stdClass $row): array
121    {
122        $question = Strings::htmlspecialchars(trim((string) $row->question));
123        $url = sprintf(
124            '%scontent/%d/%d/%s/%s.html',
125            $this->configuration->getDefaultUrl(),
126            (int) $row->category_id,
127            (int) $row->id,
128            (string) $row->lang,
129            TitleSlugifier::slug($question),
130        );
131
132        return [
133            'id' => $row->id,
134            'lang' => $row->lang,
135            'category_id' => $row->category_id,
136            'question' => $question,
137            'url' => $url,
138            'number' => $row->num,
139            'user' => $row->usr,
140        ];
141    }
142}