Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.36% covered (success)
98.36%
60 / 61
85.71% covered (success)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
VisitsRepository
98.36% covered (success)
98.36%
60 / 61
85.71% covered (success)
85.71%
6 / 7
13
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getVisitCount
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 exists
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
3.01
 insert
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 update
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 getAll
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
 resetAll
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * Visits repository class
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 2025 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     2025-11-23
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Visits;
21
22use phpMyFAQ\Configuration;
23use phpMyFAQ\Database;
24
25/**
26 * Repository for faqvisits table access.
27 */
28final readonly class VisitsRepository implements VisitsRepositoryInterface
29{
30    public function __construct(
31        private Configuration $configuration,
32    ) {
33    }
34
35    public function getVisitCount(int $faqId, string $language): int
36    {
37        $query = sprintf(
38            "SELECT visits FROM %sfaqvisits WHERE id = %d AND lang = '%s'",
39            Database::getTablePrefix(),
40            $faqId,
41            $this->configuration->getDb()->escape($language),
42        );
43
44        $result = $this->configuration->getDb()->query($query);
45        if ($this->configuration->getDb()->numRows($result) !== 0) {
46            $row = $this->configuration->getDb()->fetchObject($result);
47            return $row instanceof \stdClass ? (int) $row->visits : 0;
48        }
49
50        return 0;
51    }
52
53    public function exists(int $faqId, string $language): bool
54    {
55        $query = sprintf(
56            "SELECT COUNT(*) AS cnt FROM %sfaqvisits WHERE id = %d AND lang = '%s'",
57            Database::getTablePrefix(),
58            $faqId,
59            $this->configuration->getDb()->escape($language),
60        );
61
62        $result = $this->configuration->getDb()->query($query);
63        if ($result) {
64            $row = $this->configuration->getDb()->fetchObject($result);
65            return $row instanceof \stdClass && (int) ($row->cnt ?? 0) > 0;
66        }
67
68        return false;
69    }
70
71    public function insert(int $faqId, string $language, int $timestamp): bool
72    {
73        $query = sprintf(
74            "INSERT INTO %sfaqvisits VALUES (%d, '%s', %d, %d)",
75            Database::getTablePrefix(),
76            $faqId,
77            $this->configuration->getDb()->escape($language),
78            1,
79            $timestamp,
80        );
81
82        return (bool) $this->configuration->getDb()->query($query);
83    }
84
85    public function update(int $faqId, string $language, int $timestamp): bool
86    {
87        $query = sprintf(
88            "UPDATE %sfaqvisits SET visits = visits+1, last_visit = %d WHERE id = %d AND lang = '%s'",
89            Database::getTablePrefix(),
90            $timestamp,
91            $faqId,
92            $this->configuration->getDb()->escape($language),
93        );
94
95        return (bool) $this->configuration->getDb()->query($query);
96    }
97
98    public function getAll(): array
99    {
100        $data = [];
101
102        $query = sprintf('SELECT * FROM %sfaqvisits ORDER BY visits DESC', Database::getTablePrefix());
103        $result = $this->configuration->getDb()->query($query);
104
105        while (true) {
106            $row = $this->configuration->getDb()->fetchObject($result);
107            if (!is_object($row)) {
108                break;
109            }
110
111            $data[] = [
112                'id' => $row->id,
113                'lang' => $row->lang,
114                'visits' => $row->visits,
115                'last_visit' => $row->last_visit,
116            ];
117        }
118
119        return $data;
120    }
121
122    public function resetAll(int $timestamp): bool
123    {
124        return (bool) $this->configuration
125            ->getDb()
126            ->query(sprintf(
127                'UPDATE %sfaqvisits SET visits = 1, last_visit = %d ',
128                Database::getTablePrefix(),
129                $timestamp,
130            ));
131    }
132}