Test Failed
Push — main ( 8e55b2...88c391 )
by Rafael
10:33
created

Config::connectToDatabaseAndAuth()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 14
rs 9.9666
1
<?php
2
/**
3
 * Copyright (C) 2021-2021  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\Core\Singletons;
20
21
use Alxarafe\Core\Helpers\Auth;
22
use Alxarafe\Core\Base\Singleton;
23
use Alxarafe\Database\Engine;
24
use Alxarafe\Database\SqlHelper;
25
use DebugBar\DebugBarException;
26
use Exception;
27
use Symfony\Component\Yaml\Yaml;
28
29
/**
30
 * All variables and global functions are centralized through the static class Config.
31
 * The Config class can be instantiated and passed to the class that needs it,
32
 * sharing the data and methods that are in them.
33
 *
34
 * @package Alxarafe\Helpers
35
 */
36
class Config extends Singleton
37
{
38
    /**
39
     * Contains the full name of the configuration file or null
40
     *
41
     * @var string::null
42
     */
43
    private static string $configFilename;
44
45
    /**
46
     * Contains an array with the variables defined in the configuration file.
47
     * Use setVar to assign or getVar to access the variables of the array.
48
     *
49
     * @var array
50
     */
51
    private static array $global;
52
53
    /**
54
     * Contains the instance to the database engine (or null)
55
     *
56
     * @var Engine
57
     */
58
    public Engine $dbEngine;
59
60
    /**
61
     * Contains the instance to the specific SQL engine helper (or null)
62
     *
63
     * @var sqlHelper
64
     */
65
    private SqlHelper $sqlHelper;
66
67
    /**
68
     * It is a static instance of the Auth class that contains the data of the
69
     * currently identified user.
70
     *
71
     * @var Auth
72
     */
73
    private Auth $user;
74
75
    /**
76
     * Contains the user's name or null
77
     *
78
     * @var string|null
79
     */
80
    private ?string $username;
81
82
    private TemplateRender $render;
83
    private DebugTool $debug;
84
85
    public function __construct(string $index = 'main')
86
    {
87
        parent::__construct($index);
88
        $this->username = null;
89
        $this->render = TemplateRender::getInstance();
90
        $this->debug = DebugTool::getInstance();
91
    }
92
93
    /**
94
     * Initializes the global variable with the configuration, connects with
95
     * the database and authenticates the user.
96
     *
97
     * @return bool
98
     * @throws DebugBarException
99
     */
100
    public function loadConfig(): bool
101
    {
102
        if (!isset(self::$global)) {
103
            self::$global = self::loadConfigurationFile();
104
        }
105
106
        if (isset(self::$global['templaterender']['main']['skin'])) {
107
            $templatesFolder = BASE_FOLDER . TemplateRender::SKINS_FOLDER;
108
            $skinFolder = $templatesFolder . '/' . self::$global['templaterender']['main']['skin'];
109
            if (is_dir($templatesFolder) && !is_dir($skinFolder)) {
110
                FlashMessages::setError("Skin folder '$skinFolder' does not exists!");
111
                return false;
112
            }
113
            $this->render->setSkin(self::getVar('templaterender', 'main', 'skin'));
114
        }
115
        return true;
116
    }
117
118
    /**
119
     * @throws DebugBarException
120
     */
121
    public function connectToDatabaseAndAuth(): bool
122
    {
123
        if (!$this->connectToDataBase()) {
124
            FlashMessages::setError('Database Connection error...');
125
            return false;
126
        }
127
        if (!isset($this->user)) {
128
            $this->user = new Auth();
129
            $this->username = $this->user->getUser();
130
            if ($this->username === null) {
131
                $this->user->login();
132
            }
133
        }
134
        return true;
135
    }
136
137
    /**
138
     * Returns an array with the configuration defined in the configuration file.
139
     * If the configuration file does not exist, take us to the application
140
     * configuration form to create it
141
     *
142
     * @return array
143
     */
144
    public static function loadConfigurationFile(): array
145
    {
146
        $filename = self::getConfigFileName();
147
        if (isset($filename) && file_exists($filename)) {
148
            $yaml = file_get_contents($filename);
149
            if ($yaml) {
150
                return YAML::parse($yaml);
151
            }
152
        }
153
        return [];
154
    }
155
156
    /**
157
     * Returns the name of the configuration file. By default, create the config
158
     * folder and enter the config.yaml file inside it.
159
     * If you want to use another folder for the configuration, you will have to
160
     * define it in the constant CONFIGURATION_PATH before invoking this method,
161
     * this folder must exist.
162
     *
163
     * @return string|null
164
     */
165
    public static function getConfigFileName(): ?string
166
    {
167
        if (isset(self::$configFilename)) {
168
            return self::$configFilename;
169
        }
170
        $filename = CONFIGURATION_PATH . '/config.yaml';
171
        if (file_exists($filename) || is_dir(CONFIGURATION_PATH) || mkdir(CONFIGURATION_PATH, 0777, true)) {
172
            self::$configFilename = $filename;
173
        }
174
        return self::$configFilename;
175
    }
176
177
    /**
178
     * Gets the contents of a variable. If the variable does not exist, return null.
179
     *
180
     * @param string $module
181
     * @param string $section
182
     * @param string $name
183
     *
184
     * @return string|null ?string
185
     */
186
    static public function getVar(string $module, string $section, string $name): ?string
187
    {
188
        return self::$global[$module][$section][$name] ?? null;
189
    }
190
191
    /**
192
     * If $this->dbEngine contain null, create an Engine instance with the
193
     * database connection and assigns it to $this->dbEngine.
194
     *
195
     * @param string $db
196
     *
197
     * @return bool
198
     * @throws DebugBarException
199
     */
200
    public function connectToDatabase($db = 'main'): bool
201
    {
202
        if (isset($this->dbEngine)) {
203
            return true;
204
        }
205
206
        $dbEngineName = self::$global['database'][$db]['dbEngineName'] ?? 'PdoMySql';
207
        $helperName = 'Sql' . substr($dbEngineName, 3);
208
209
        $this->debug->addMessage('SQL', "Using '$dbEngineName' engine.");
210
        $this->debug->addMessage('SQL', "Using '$helperName' SQL helper engine.");
211
212
        $sqlEngine = '\\Alxarafe\\Database\\SqlHelpers\\' . $helperName;
213
        $engine = '\\Alxarafe\\Database\\Engines\\' . $dbEngineName;
214
        try {
215
            $this->sqlHelper = new $sqlEngine();
216
            $this->dbEngine = new $engine([
217
                'dbUser' => self::$global['database'][$db]['dbUser'],
218
                'dbPass' => self::$global['database'][$db]['dbPass'],
219
                'dbName' => self::$global['database'][$db]['dbName'],
220
                'dbHost' => self::$global['database'][$db]['dbHost'],
221
                'dbPort' => self::$global['database'][$db]['dbPort'],
222
            ]);
223
            return isset($this->dbEngine) && $this->dbEngine->connect() && $this->dbEngine->checkConnection();
224
        } catch (Exception $e) {
225
            $this->debug->addException($e);
226
        }
227
        return false;
228
    }
229
230
    public function getEngine(): Engine
231
    {
232
        return $this->dbEngine;
233
    }
234
235
    public function getSqlHelper(): SqlHelper
236
    {
237
        return $this->sqlHelper;
238
    }
239
240
    /**
241
     * Return true y the config file exists
242
     *
243
     * @return bool
244
     */
245
    public function configFileExists(): bool
246
    {
247
        return (file_exists(self::getConfigFileName()));
248
    }
249
250
    public function getUsername()
251
    {
252
        return $this->username;
253
    }
254
255
    /**
256
     * Set the display settings.
257
     *
258
     * @return void
259
     */
260
    public function loadViewsConfig()
261
    {
262
        dump(debug_backtrace());
263
        die('loadViewsConfig');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
264
        $this->render->setSkin(self::getVar('templaterender', 'main', 'skin') ?? 'default');
0 ignored issues
show
Unused Code introduced by
$this->render->setSkin(s..., 'skin') ?? 'default') is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
265
        $this->render->setTemplate(self::getVar('templaterender', 'main', 'skin') ?? 'default');
266
    }
267
268
    /**
269
     * Stores all the variables in a permanent file so that they can be loaded
270
     * later with loadConfigFile()
271
     * Returns true if there is no error when saving the file.
272
     *
273
     * @return bool
274
     */
275
    public function saveConfigFile(): bool
276
    {
277
        $configFile = self::getConfigFileName();
278
        if (!isset($configFile)) {
279
            return false;
280
        }
281
        return file_put_contents($configFile, YAML::dump(self::$global, 3)) !== false;
282
    }
283
284
    /**
285
     * Stores a variable.
286
     *
287
     * @param string $module
288
     * @param string $section
289
     * @param string $name
290
     * @param string $value
291
     */
292
    public function setVar(string $module, string $section, string $name, string $value)
293
    {
294
        self::$global[$module][$section][$name] = $value;
295
    }
296
}
297