Passed
Push — master ( ab5b91...849dc0 )
by Fran
03:17
created

Config::dumpConfig()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
1
<?php
2
3
namespace PSFS\base\config;
4
5
use PSFS\base\exception\ConfigException;
6
use PSFS\base\Logger;
7
use PSFS\base\Request;
8
use PSFS\base\Security;
9
use PSFS\base\types\helpers\Inspector;
10
use PSFS\base\types\traits\SingletonTrait;
11
use PSFS\base\types\traits\TestTrait;
12
13
/**
14
 * Class Config
15
 * @package PSFS\base\config
16
 */
17
class Config
18
{
19
    use SingletonTrait;
20
    use TestTrait;
21
22
    const DEFAULT_LANGUAGE = 'es';
23
    const DEFAULT_ENCODE = 'UTF-8';
24
    const DEFAULT_CTYPE = 'text/html';
25
    const DEFAULT_DATETIMEZONE = 'Europe/Madrid';
26
27
    const CONFIG_FILE = 'config.json';
28
29
    protected array $config = [];
30
    static public array $defaults = [
31
        'db.host' => 'localhost',
32
        'db.port' => '3306',
33
        'default.language' => 'es_ES',
34
        'debug' => true,
35
        'front.version' => 'v1',
36
        'version' => 'v1',
37
    ];
38
    static public array $required = ['db.host', 'db.port', 'db.name', 'db.user', 'db.password', 'home.action', 'default.language', 'debug'];
39
    static public array $encrypted = ['db.password'];
40
    static public array $optional = [
41
        'platform.name', // Platform name
42
        'restricted', // Restrict the web access
43
        'admin.login', // Enable web login for admin
44
        'logger.phpFire', // Enable phpFire to trace the logs in the browser
45
        'logger.memory', // Enable log memory usage un traces
46
        'poweredBy', // Show PoweredBy header customized
47
        'author', // Author for auto generated files
48
        'author.email', // Author email for auto generated files
49
        'version', // Platform version(for cache purposes)
50
        'front.version', // Static resources version
51
        'cors.enabled', // Enable CORS (regex with the domains, * for all)
52
        'pagination.limit', // Pagination limit for autogenerated api admin
53
        'api.secret', // Secret passphrase to securize the api
54
        'api.admin', // Enable the autogenerated api admin(wok)
55
        'log.level', // Max log level(default INFO)
56
        'admin_action', // Default admin url when access to /admin
57
        'cache.var', // Static cache var
58
        'twig.autoreload', // Enable or disable auto reload templates for twig
59
        'modules.extend', // Variable for extending the current functionality
60
        'psfs.auth', // Variable for extending PSFS with the AUTH module
61
        'errors.strict', // Variable to trace all strict errors
62
        'psfs.memcache', // Add Memcache to prod cache process, ONLY for PROD environments
63
        'angular.protection', // Add an angular suggested prefix in order to avoid JSONP injections
64
        'cors.headers', // Add extra headers to the CORS check
65
        'json.encodeUTF8', // Encode the json response
66
        'cache.data.enable', // Enable data caching with PSFS
67
        'profiling.enable', // Enable the profiling headers
68
        'api.extrafields.compat', // Disbale retro compatibility with extra field mapping in api
69
        'output.json.strict_numbers', // Enable strict numbers in json responses
70
        'admin.version', // Determines the version for the admin ui
71
        'api.block.limit', // Determine the number of rows for bulk insert
72
        'api.field.types', // Extract __fields from api with their types
73
        'i18n.locales', // Default locales for any project
74
        'log.slack.hook', // Hook for slack traces
75
        'i18n.autogenerate', // Set PSFS auto generate i18n mode
76
        'resources.cdn.url', // CDN URL base path
77
        'api.field.case', // Field type for API dtos (phpName|camelName|camelName|fieldName) @see Propel TableMap class
78
        'route.404', // Set route for 404 pages
79
        'project.timezone', // Set the timezone for the timestamps in PSFS(Europe/madrid by default)
80
        'curl.returnTransfer', // Curl option CURLOPT_RETURNTRANSFER
81
        'curl.followLocation', // Curl option CURLOPT_FOLLOWLOCATION
82
        'curl.sslVerifyHost', // Curl option CURLOPT_SSL_VERIFYHOST
83
        'curl.sslVerifyPeer', // Curl option CURLOPT_SSL_VERIFYPEER
84
        'assets.obfuscate', // Allow to obfuscate and gzip js and css files
85
        'allow.double.slashes', // Allow // in url paths, allowed as default
86
        'default.log.path', // Default logger path
87
        'force.https', // Force https protocol for static resources
88
        'hide.modules', // Hide modules from menu, separated by comma
89
        'skip.route_generation', // Skip routes generation
90
    ];
91
    protected bool $debug = false;
92
    public static array $cleanable_config_files = ['domains.json', 'urls.json'];
93
94
    /**
95
     * Method that load the configuration data into the system
96
     * @return Config
97
     */
98 1
    protected function init()
99
    {
100 1
        if (file_exists(CONFIG_DIR . DIRECTORY_SEPARATOR . self::CONFIG_FILE)) {
101 1
            $this->loadConfigData();
102
        }
103 1
        return $this;
104
    }
105
106
    /**
107
     * @return bool
108
     */
109 1
    public function isLoaded()
110
    {
111 1
        return !empty($this->config);
112
    }
113
114
    /**
115
     * Method that saves the configuration
116
     * @param array $data
117
     * @param array $extra
118
     * @return array
119
     */
120 8
    protected static function saveConfigParams(array $data, $extra = null)
121
    {
122 8
        Logger::log('Saving required config parameters');
123
        //En caso de tener parámetros nuevos los guardamos
124 8
        if (!empty($extra) && array_key_exists('label', $extra) && is_array($extra['label'])) {
125 3
            foreach ($extra['label'] as $index => $field) {
126 3
                if (array_key_exists($index, $extra['value']) && !empty($extra['value'][$index])) {
127
                    /** @var $data array */
128 3
                    $data[$field] = $extra['value'][$index];
129
                }
130
            }
131
        }
132 8
        return $data;
133
    }
134
135
    /**
136
     * Method that saves the extra parameters into the configuration
137
     * @param array $data
138
     * @return array
139
     */
140 8
    protected static function saveExtraParams(array $data)
141
    {
142 8
        $finalData = array();
143 8
        if (count($data) > 0) {
144 8
            Logger::log('Saving extra configuration parameters');
145 8
            foreach ($data as $key => $value) {
146 8
                if (null !== $value || $value !== '') {
147 8
                    $finalData[$key] = $value;
148
                }
149
            }
150
        }
151 8
        return $finalData;
152
    }
153
154
    /**
155
     * Method that returns if the system is in debug mode
156
     * @return boolean
157
     */
158 3
    public function getDebugMode()
159
    {
160 3
        return $this->debug;
161
    }
162
163
    /**
164
     * @param bool $debug
165
     */
166 2
    public function setDebugMode($debug = true)
167
    {
168 2
        $this->debug = $debug;
169 2
        $this->config['debug'] = $this->debug;
170
    }
171
172
    /**
173
     * Method that checks if the platform is proper configured
174
     * @return boolean
175
     */
176 2
    public function isConfigured()
177
    {
178 2
        Inspector::stats('[Config] Checking configuration', Inspector::SCOPE_DEBUG);
179 2
        $configured = (count($this->config) > 0);
180 2
        if ($configured) {
181 1
            foreach (static::$required as $required) {
182 1
                if (!array_key_exists($required, $this->config)) {
183 1
                    $configured = false;
184 1
                    break;
185
                }
186
            }
187
        }
188 2
        return $configured || $this->checkTryToSaveConfig() || self::isTest();
189
    }
190
191
    /**
192
     * Method that check if the user is trying to save the config
193
     * @return bool
194
     */
195 5
    public function checkTryToSaveConfig()
196
    {
197 5
        $uri = Request::getInstance()->getRequestUri();
198 5
        $method = Request::getInstance()->getMethod();
199 5
        return (preg_match('/^\/admin\/(config|setup)$/', $uri) !== false && strtoupper($method) === 'POST');
200
    }
201
202
    /**
203
     * Method that saves all the configuration in the system
204
     *
205
     * @param array $data
206
     * @param array|null $extra
207
     * @return boolean
208
     */
209 8
    public static function save(array $data, $extra = null)
210
    {
211 8
        $data = self::saveConfigParams($data, $extra);
212 8
        $finalData = self::saveExtraParams($data);
213 8
        $saved = false;
214
        try {
215 8
            $finalData = array_filter($finalData, function ($key, $value) {
216 8
                return in_array($key, self::$required, true) || !empty($value);
217 8
            }, ARRAY_FILTER_USE_BOTH);
218 8
            $saved = (false !== file_put_contents(CONFIG_DIR . DIRECTORY_SEPARATOR . self::CONFIG_FILE, json_encode($finalData, JSON_PRETTY_PRINT)));
219 8
            self::getInstance()->loadConfigData();
220 8
            $saved = true;
221
        } catch (ConfigException $e) {
222
            Logger::log($e->getMessage(), LOG_ERR);
223
        }
224 8
        return $saved;
225
    }
226
227
    /**
228
     * Method that returns a config value
229
     * @param string $param
230
     * @param mixed $defaultValue
231
     *
232
     * @return mixed|null
233
     */
234 39
    public function get($param, $defaultValue = null)
235
    {
236 39
        return array_key_exists($param, $this->config) ? $this->config[$param] : $defaultValue;
237
    }
238
239
    /**
240
     * Method that returns all the configuration
241
     * @return array
242
     */
243 8
    public function dumpConfig()
244
    {
245 8
        return $this->config ?: [];
246
    }
247
248
    /**
249
     * Method that reloads config file
250
     */
251 8
    public function loadConfigData()
252
    {
253 8
        $this->config = json_decode(file_get_contents(CONFIG_DIR . DIRECTORY_SEPARATOR . self::CONFIG_FILE), true) ?: [];
254 8
        $this->debug = array_key_exists('debug', $this->config) ? (bool)$this->config['debug'] : FALSE;
255 8
        if (array_key_exists('cache.var', $this->config)) {
256 1
            Security::getInstance()->setSessionKey('config.cache.var', $this->config['cache.var']);
257
        }
258
    }
259
260
    /**
261
     * Clear configuration set
262
     */
263 1
    public function clearConfig()
264
    {
265 1
        $this->config = [];
266
    }
267
268
    /**
269
     * Static wrapper for extracting params
270
     * @param string $key
271
     * @param mixed|null $defaultValue
272
     * @param string $module
273
     * @return mixed|null
274
     */
275 37
    public static function getParam($key, $defaultValue = null, $module = null)
276
    {
277 37
        if (null !== $module) {
278 2
            return self::getParam(strtolower($module) . '.' . $key, self::getParam($key, $defaultValue));
279
        }
280 37
        $param = self::getInstance()->get($key);
281 37
        return (null !== $param) ? $param : $defaultValue;
282
    }
283
284 1
    public static function initialize()
285
    {
286 1
        Config::getInstance();
287 1
        Logger::getInstance();
288
    }
289
290 1
    public static function clearConfigFiles(): bool
291
    {
292 1
        $done = true;
293 1
        foreach (self::$cleanable_config_files as $configFile) {
294 1
            if (file_exists(CONFIG_DIR . DIRECTORY_SEPARATOR . $configFile)) {
295 1
                if (!unlink(CONFIG_DIR . DIRECTORY_SEPARATOR . $configFile)) {
296
                    $done = false;
297
                }
298
            }
299
        }
300 1
        return $done;
301
    }
302
}
303