Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
70 / 70
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
Instance
100.00% covered (success)
100.00%
70 / 70
100.00% covered (success)
100.00%
11 / 11
20
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
 create
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
2
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAll
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getById
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 update
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 delete
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 addConfig
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 getConfig
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 getInstanceConfig
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * The main phpMyFAQ instances 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 2012-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     2012-02-20
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ;
21
22use phpMyFAQ\Entity\InstanceEntity;
23use stdClass;
24
25/**
26 * Class Instance
27 *
28 * @package phpMyFAQ
29 */
30class Instance
31{
32    /**
33     * Instance ID.
34     */
35    protected int $id;
36
37    /**
38     * Instance configuration.
39     *
40     * @var string[]
41     */
42    protected array $instanceConfig = [];
43
44    /**
45     * Constructor.
46     */
47    public function __construct(
48        protected Configuration $configuration,
49    ) {
50    }
51
52    /**
53     * Adds a new instance.
54     *
55     * @return int $id
56     */
57    public function create(InstanceEntity $instanceEntity): int
58    {
59        $this->setId($this->configuration->getDb()->nextId(Database::getTablePrefix() . 'faqinstances', column: 'id'));
60
61        $query = "INSERT INTO %sfaqinstances VALUES (%d, '%s', '%s', '%s', %s, %s)";
62        $insert = sprintf(
63            $query,
64            Database::getTablePrefix(),
65            $this->getId(),
66            $this->configuration->getDb()->escape($instanceEntity->getUrl()),
67            $this->configuration->getDb()->escape($instanceEntity->getInstance()),
68            $this->configuration->getDb()->escape($instanceEntity->getComment()),
69            $this->configuration->getDb()->now(),
70            $this->configuration->getDb()->now(),
71        );
72
73        if (!$this->configuration->getDb()->query($insert)) {
74            return 0;
75        }
76
77        return $this->getId();
78    }
79
80    /**
81     * Returns the current instance id.
82     */
83    public function getId(): int
84    {
85        return $this->id;
86    }
87
88    /**
89     * Sets the instance ID.
90     */
91    public function setId(int $id): void
92    {
93        $this->id = $id;
94    }
95
96    /**
97     * Returns all instances.
98     *
99     * @return stdClass[]
100     */
101    public function getAll(): array
102    {
103        $query = 'SELECT * FROM %sfaqinstances ORDER BY id';
104        $select = sprintf($query, Database::getTablePrefix());
105
106        $result = $this->configuration->getDb()->query($select);
107
108        return $this->configuration->getDb()->fetchAll($result) ?? [];
109    }
110
111    /**
112     * Returns the instance.
113     */
114    public function getById(int $id): \stdClass
115    {
116        $query = 'SELECT * FROM %sfaqinstances WHERE id = %d';
117        $select = sprintf($query, Database::getTablePrefix(), $id);
118
119        $result = $this->configuration->getDb()->query($select);
120
121        $row = $this->configuration->getDb()->fetchObject($result);
122
123        return $row instanceof \stdClass ? $row : new \stdClass();
124    }
125
126    /**
127     * Updates the instance data.
128     */
129    public function update(int $id, InstanceEntity $instanceEntity): bool
130    {
131        $query = "UPDATE %sfaqinstances SET instance = '%s', comment = '%s', url = '%s' WHERE id = %d";
132        $update = sprintf(
133            $query,
134            Database::getTablePrefix(),
135            $this->configuration->getDb()->escape($instanceEntity->getInstance()),
136            $this->configuration->getDb()->escape($instanceEntity->getComment()),
137            $this->configuration->getDb()->escape($instanceEntity->getUrl()),
138            $id,
139        );
140
141        return (bool) $this->configuration->getDb()->query($update);
142    }
143
144    /**
145     * Deletes an instance.
146     *
147     */
148    public function delete(int $id): bool
149    {
150        $queryDeleteInstance = 'DELETE FROM %sfaqinstances WHERE id = %d';
151        $queryDeleteConfig = 'DELETE FROM %sfaqinstances_config WHERE instance_id = %d';
152
153        $deletes = [
154            sprintf($queryDeleteInstance, Database::getTablePrefix(), $id),
155            sprintf($queryDeleteConfig, Database::getTablePrefix(), $id),
156        ];
157
158        foreach ($deletes as $delete) {
159            $success = $this->configuration->getDb()->query($delete);
160            if (!$success) {
161                return false;
162            }
163        }
164
165        return true;
166    }
167
168    /**
169     * Adds a configuration item for the database.
170     *
171     */
172    public function addConfig(string $name, string $value): mixed
173    {
174        $query = "INSERT INTO %sfaqinstances_config VALUES (%d, '%s', '%s')";
175        $insert = sprintf(
176            $query,
177            Database::getTablePrefix(),
178            $this->getId(),
179            $this->configuration->getDb()->escape(trim($name)),
180            $this->configuration->getDb()->escape(trim($value)),
181        );
182
183        return (bool) $this->configuration->getDb()->query($insert);
184    }
185
186    /**
187     * Returns the configuration value.
188     */
189    public function getConfig(string $name): bool|string
190    {
191        if (!array_key_exists($name, $this->instanceConfig)) {
192            $this->getInstanceConfig($this->getId());
193        }
194
195        return match ($this->instanceConfig[$name]) {
196            'true' => true,
197            'false' => false,
198            default => $this->instanceConfig[$name],
199        };
200    }
201
202    /**
203     * Returns the configuration of the given instance ID.
204     *
205     * @return string[]
206     */
207    public function getInstanceConfig(int $instanceId): array
208    {
209        $query = 'SELECT config_name, config_value FROM %sfaqinstances_config WHERE instance_id = %d';
210        $query = sprintf($query, Database::getTablePrefix(), $instanceId);
211
212        $result = $this->configuration->getDb()->query($query);
213        $config = $this->configuration->getDb()->fetchAll($result) ?? [];
214
215        foreach ($config as $items) {
216            $this->instanceConfig[(string) $items->config_name] = (string) $items->config_value;
217        }
218
219        return $this->instanceConfig;
220    }
221}