Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
BackupRepository
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
8 / 8
18
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
 getNumberOfEntries
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getAll
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 findByFilename
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
4
 add
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
5
 deleteById
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 deleteByFilename
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 deleteAll
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * Backup Repository.
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-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     2025-10-16
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Administration\Backup;
21
22use phpMyFAQ\Configuration;
23use phpMyFAQ\Database;
24
25readonly class BackupRepository
26{
27    public function __construct(
28        private Configuration $configuration,
29    ) {
30    }
31
32    public function getNumberOfEntries(): int
33    {
34        $query = sprintf('SELECT id FROM %sfaqbackup', Database::getTablePrefix());
35
36        return $this->configuration->getDb()->numRows($this->configuration->getDb()->query($query));
37    }
38
39    /**
40     * @return array<int, \stdClass>
41     */
42    public function getAll(): array
43    {
44        $table = Database::getTablePrefix() . 'faqbackup';
45        $query = sprintf('SELECT id, filename, authkey, authcode, created FROM %s ORDER BY id DESC', $table);
46
47        $result = $this->configuration->getDb()->query($query);
48        $data = $this->configuration->getDb()->fetchAll($result);
49
50        return is_array($data) ? $data : [];
51    }
52
53    public function findByFilename(string $filename): ?\stdClass
54    {
55        if ($filename === '') {
56            return null;
57        }
58
59        $table = Database::getTablePrefix() . 'faqbackup';
60        $filenameEscaped = $this->configuration->getDb()->escape($filename);
61        $query = sprintf(
62            "SELECT id, filename, authkey, authcode, created FROM %s WHERE filename = '%s'",
63            $table,
64            $filenameEscaped,
65        );
66
67        $result = $this->configuration->getDb()->query($query);
68        if ($this->configuration->getDb()->numRows($result) > 0) {
69            $row = $this->configuration->getDb()->fetchObject($result);
70            return $row instanceof \stdClass ? $row : null;
71        }
72
73        return null;
74    }
75
76    public function add(string $filename, string $authKeyHex, string $authCodeHex, string $created): bool
77    {
78        if ($filename === '' || $authKeyHex === '' || $authCodeHex === '' || $created === '') {
79            return false;
80        }
81
82        $table = Database::getTablePrefix() . 'faqbackup';
83        $id = $this->configuration->getDb()->nextId(table: $table, column: 'id');
84
85        $filenameEscaped = $this->configuration->getDb()->escape($filename);
86        $authKeyEscaped = $this->configuration->getDb()->escape($authKeyHex);
87        $authCodeEscaped = $this->configuration->getDb()->escape($authCodeHex);
88        $createdEscaped = $this->configuration->getDb()->escape($created);
89
90        $query = sprintf(
91            "INSERT INTO %s (id, filename, authkey, authcode, created) VALUES (%d, '%s', '%s', '%s', '%s')",
92            $table,
93            $id,
94            $filenameEscaped,
95            $authKeyEscaped,
96            $authCodeEscaped,
97            $createdEscaped,
98        );
99
100        return (bool) $this->configuration->getDb()->query($query);
101    }
102
103    public function deleteById(int $id): bool
104    {
105        if ($id <= 0) {
106            return false;
107        }
108
109        $table = Database::getTablePrefix() . 'faqbackup';
110        $query = sprintf('DELETE FROM %s WHERE id = %d', $table, $id);
111
112        return (bool) $this->configuration->getDb()->query($query);
113    }
114
115    public function deleteByFilename(string $filename): bool
116    {
117        if ($filename === '') {
118            return false;
119        }
120
121        $table = Database::getTablePrefix() . 'faqbackup';
122        $filenameEscaped = $this->configuration->getDb()->escape($filename);
123        $query = sprintf("DELETE FROM %s WHERE filename = '%s'", $table, $filenameEscaped);
124
125        return (bool) $this->configuration->getDb()->query($query);
126    }
127
128    public function deleteAll(): bool
129    {
130        $table = Database::getTablePrefix() . 'faqbackup';
131        $query = sprintf('DELETE FROM %s', $table);
132
133        return (bool) $this->configuration->getDb()->query($query);
134    }
135}