Test Failed
Push — main ( b6e144...1a2341 )
by Rafael
05:34
created

DB::connectToDatabase()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 26
nc 8
nop 1
dl 0
loc 37
rs 8.8817
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright (C) 2022-2023  Rafael San José Tovar   <[email protected]>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
namespace Alxarafe\Database;
20
21
use Alxarafe\Core\Helpers\Auth;
22
use Alxarafe\Core\Singletons\Config;
23
use Alxarafe\Core\Singletons\Debug;
24
use Alxarafe\Core\Singletons\FlashMessages;
25
use Alxarafe\Database\SqlHelpers\SqlMySql;
26
use PDO;
27
28
/**
29
 * Class DB
30
 *
31
 * Esta clase proporciona acceso directo a la base de datos.
32
 *
33
 * @author  Rafael San José Tovar <[email protected]>
34
 * @version 2022.0721
35
 *
36
 */
37
abstract class DB
38
{
39
    /**
40
     * Motor utilizado, puede ser MySql, MariaDB, PostgreSql o cualquier otro PDO
41
     *
42
     * @var Engine
43
     */
44
    public static $engine;
45
46
    /**
47
     * Instancia de la clase con el código SQL específico del motor.
48
     *
49
     * @var SqlHelper
50
     */
51
    public static $helper;
52
53
    /**
54
     * Database name.
55
     *
56
     * @var string
57
     */
58
    public static string $dbName;
59
60
    /**
61
     * Contains de database tablename prefix
62
     *
63
     * @var string
64
     */
65
    public static string $dbPrefix;
66
67
    public static $user;
68
    public static $username;
69
70
    /**
71
     * Establece conexión con la base de datos
72
     *
73
     * @param string $db
74
     *
75
     * @return bool
76
     * @throws DebugBarException
77
     */
78
    public static function connectToDatabase($db = 'main'): bool
79
    {
80
        if (isset(self::$engine)) {
81
            return true;
82
        }
83
84
        $dbInfo = Config::getModuleVar('database');
85
        if ($dbInfo === null) {
86
            Debug::sqlMessage('empty-database-config');
87
            return false;
88
        }
89
90
        self::$dbPrefix = strtolower($dbInfo[$db]['dbPrefix'] ?? '');
91
        self::$dbName = strtolower($dbInfo[$db]['dbName']);
92
93
        $engineName = $dbInfo[$db]['dbEngineName'] ?? 'PdoMySql';
94
        $helperName = 'Sql' . substr($engineName, 3);
95
96
        Debug::sqlMessage("Using '$engineName' engine.");
97
        Debug::sqlMessage("Using '$helperName' SQL helper engine.");
98
99
        $sqlEngine = '\\Alxarafe\\Database\\SqlHelpers\\' . $helperName;
100
        $engine = '\\Alxarafe\\Database\\Engines\\' . $engineName;
101
        try {
102
            self::$helper = new $sqlEngine();
103
            self::$engine = new $engine([
104
                'dbUser' => $dbInfo[$db]['dbUser'],
105
                'dbPass' => $dbInfo[$db]['dbPass'],
106
                'dbName' => $dbInfo[$db]['dbName'],
107
                'dbHost' => $dbInfo[$db]['dbHost'],
108
                'dbPort' => $dbInfo[$db]['dbPort'],
109
            ]);
110
            return isset(self::$engine) && self::$engine->connect() && self::$engine->checkConnection();
111
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The type Alxarafe\Database\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
112
            Debug::addException($e);
113
        }
114
        return false;
115
    }
116
117
    public function __construct()
118
    {
119
        self::$engine = Config::getEngine();
0 ignored issues
show
Bug introduced by
The method getEngine() does not exist on Alxarafe\Core\Singletons\Config. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

119
        /** @scrutinizer ignore-call */ 
120
        self::$engine = Config::getEngine();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
120
        self::$helper = Config::getSqlHelper();
0 ignored issues
show
Bug introduced by
The method getSqlHelper() does not exist on Alxarafe\Core\Singletons\Config. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

120
        /** @scrutinizer ignore-call */ 
121
        self::$helper = Config::getSqlHelper();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
121
    }
122
123
    public static function connect()
124
    {
125
        return self::$engine->connect();
126
    }
127
128
    public static function disconnect()
129
    {
130
        return self::$engine->disconnect();
0 ignored issues
show
Bug introduced by
The method disconnect() does not exist on Alxarafe\Database\Engine. Did you maybe mean connect()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
        return self::$engine->/** @scrutinizer ignore-call */ disconnect();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
    }
132
133
    public static function connected()
134
    {
135
        return self::$engine->connected();
0 ignored issues
show
Bug introduced by
The method connected() does not exist on Alxarafe\Database\Engine. Did you maybe mean connect()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
        return self::$engine->/** @scrutinizer ignore-call */ connected();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
136
    }
137
138
    public static function getDataTypes()
139
    {
140
        return self::$helper->getDataTypes();
141
    }
142
143
    /**
144
     * Ejecuta una sentencia SQL retornando TRUE si ha tenido éxito
145
     *
146
     * @author  Rafael San José Tovar <[email protected]>
147
     * @version 2022.0721
148
     *
149
     * @param string $query
150
     * @param array  $vars
151
     *
152
     * @return bool
153
     */
154
    public static function exec(string $query, array $vars = []): bool
155
    {
156
        return self::$engine->exec($query, $vars);
0 ignored issues
show
Unused Code introduced by
The call to Alxarafe\Database\Engine::exec() has too many arguments starting with $vars. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
        return self::$engine->/** @scrutinizer ignore-call */ exec($query, $vars);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
157
    }
158
159
    /**
160
     * Ejecuta una sentencia SELECT, retornando false si hay error, o un array
161
     * con el resultado de la consulta.
162
     *
163
     * @author  Rafael San José Tovar <[email protected]>
164
     * @version 2022.0721
165
     *
166
     * @param string $query
167
     * @param array  $vars
168
     *
169
     * @return array|false
170
     */
171
    public static function select(string $query, array $vars = [])
172
    {
173
        return self::$engine->select($query, $vars);
0 ignored issues
show
Unused Code introduced by
The call to Alxarafe\Database\Engine::select() has too many arguments starting with $vars. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

173
        return self::$engine->/** @scrutinizer ignore-call */ select($query, $vars);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
174
    }
175
176
    public static function getErrors()
177
    {
178
        return self::$engine->getErrors();
0 ignored issues
show
Bug introduced by
The method getErrors() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

178
        return self::$engine->/** @scrutinizer ignore-call */ getErrors();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
179
    }
180
181
    public static function beginTransaction()
182
    {
183
        return self::$engine->beginTransaction();
184
    }
185
186
    public static function commit()
187
    {
188
        return self::$engine->commit();
189
    }
190
191
    public static function close()
192
    {
193
        return self::$engine->close();
0 ignored issues
show
Bug introduced by
The method close() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
        return self::$engine->/** @scrutinizer ignore-call */ close();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
194
    }
195
196
    public static function rollback()
197
    {
198
        return self::$engine->rollback();
199
    }
200
201
    public static function version()
202
    {
203
        return self::$engine->server_info();
0 ignored issues
show
Bug introduced by
The method server_info() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

203
        return self::$engine->/** @scrutinizer ignore-call */ server_info();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
204
    }
205
206
    public static function tableExists(string $tableName)
207
    {
208
        return self::$helper->tableExists(self::$dbPrefix . $tableName);
209
    }
210
211
    public static function getColumns(string $tableName)
212
    {
213
        return self::$helper->getColumns(self::$dbPrefix . $tableName);
214
    }
215
216
    public static function yamlFieldToDb(array $data): array
217
    {
218
        return self::$helper::yamlFieldToDb($data);
219
    }
220
221
    public static function yamlFieldToSchema(array $data): array
222
    {
223
        return self::$helper::yamlFieldToSchema($data);
224
    }
225
226
    public static function dbFieldToSchema(array $data): array
227
    {
228
        return self::$helper::dbFieldToSchema($data);
229
    }
230
231
    public static function dbFieldToYaml(array $data): array
232
    {
233
        return self::$helper::dbFieldToYaml($data);
234
    }
235
236
    public static function normalizeFromDb(array $data)
237
    {
238
        $result = self::$helper::normalizeDbField($data);
239
        dump([
240
            'normalizeFromDb',
241
            'data' => $data,
242
            'result' => $result,
243
        ]);
244
        return $result;
245
    }
246
247
    public static function normalizeFromYaml(array $yamlFields)
248
    {
249
        $result = [];
250
        foreach ($yamlFields as $field => $yamlField) {
251
            $result[$field] = self::$helper::normalizeYamlField($yamlField);
0 ignored issues
show
Bug introduced by
The method normalizeYamlField() does not exist on Alxarafe\Database\SqlHelper. Did you maybe mean normalizeDbField()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

251
            /** @scrutinizer ignore-call */ 
252
            $result[$field] = self::$helper::normalizeYamlField($yamlField);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
252
        }
253
        dump([
254
            'normalizeFromYaml',
255
            'data' => $yamlFields,
256
            'result' => $result,
257
        ]);
258
        return $result;
259
    }
260
261
    public static function normalize(array $data)
262
    {
263
        return self::$helper->normalizeField($data);
0 ignored issues
show
Bug introduced by
The method normalizeField() does not exist on Alxarafe\Database\SqlHelper. Did you maybe mean normalizeDbField()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

263
        return self::$helper->/** @scrutinizer ignore-call */ normalizeField($data);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
264
    }
265
266
    public static function getIndexType(): string
267
    {
268
        return self::$helper->getIndexType();
269
    }
270
271
    public static function modify(string $tableName, array $oldField, array $newField): string
272
    {
273
        return self::$helper->modify(self::$dbPrefix . $tableName, $oldField, $newField);
274
    }
275
276
    public static function getUsername()
277
    {
278
        return self::$username;
279
    }
280
281
    public static function connectToDatabaseAndAuth(): bool
282
    {
283
        if (!self::connectToDataBase()) {
284
            FlashMessages::setError('Database Connection error...');
285
            return false;
286
        }
287
        if (!isset(self::$user)) {
288
            self::$user = new Auth();
289
            self::$username = self::$user->getUser();
290
            if (self::$username === null) {
291
                self::$user->login();
292
            }
293
        }
294
        return true;
295
    }
296
297
}
298