Completed
Pull Request — master (#10)
by Mathieu
05:19 queued 02:50
created

Suricate::configureAppMode()   B

Complexity

Conditions 10
Paths 96

Size

Total Lines 52
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 40.6727

Importance

Changes 7
Bugs 1 Features 0
Metric Value
cc 10
eloc 42
c 7
b 1
f 0
nc 96
nop 0
dl 0
loc 52
ccs 14
cts 43
cp 0.3256
crap 40.6727
rs 7.6666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Suricate;
6
7
/**
8
 * Suricate - Another micro PHP framework
9
 *
10
 * @author      Mathieu LESNIAK <[email protected]>
11
 * @copyright   2013-2019 Mathieu LESNIAK
12
 * @version     0.3.2
13
 * @package     Suricate
14
 *
15
 * @method static \Suricate\App             App($newInstance = false)             Get instance of App service
16
 * @method static \Suricate\Cache           Cache($newInstance = false)           Get instance of Cache service
17
 * @method static \Suricate\CacheMemcache   CacheMemcache($newInstance = false)   Get instance of CacheMemcache service
18
 * @method static \Suricate\CacheMemcached  CacheMemcached($newInstance = false)  Get instance of CacheMemcached service
19
 * @method static \Suricate\CacheApc        CacheApc($newInstance = false)        Get instance of CacheApc service
20
 * @method static \Suricate\CacheFile       CacheFile($newInstance = false)       Get instance of CacheFile service
21
 * @method static \Suricate\Curl            Curl($newInstance = false)            Get instance of Curl service
22
 * @method static \Suricate\Database        Database($newInstance = false)        Get instance of Database service
23
 * @method static \Suricate\Error           Error($newInstance = false)           Get instance of Error service
24
 * @method static \Suricate\Event\EventDispatcher EventDispatcher($newInstance = false) Get instance of EventDispatcher service
25
 * @method static \Suricate\I18n            I18n($newInstance = false)            Get instance of I18n service
26
 * @method static \Suricate\Logger          Logger($newInstance = false)          Get instance of Logger service
27
 * @method static \Suricate\Request         Request($newInstance = false)         Get instance of Request service
28
 * @method static \Suricate\Request         Response($newInstance = false)        Get instance of Request/Response service
29
 * @method static \Suricate\Router          Router($newInstance = false)          Get instance of Router service
30
 * @method static \Suricate\Session         Session($newInstance = false)         Get instance of Session service
31
 * @method static \Suricate\SessionNative   SessionNative($newInstance = false)   Get instance of Session service
32
 * @method static \Suricate\SessionCookie   SessionCookie($newInstance = false)   Get instance of Session service
33
 * @method static \Suricate\SessionMemcache SessionMemcache($newInstance = false) Get instance of Session service
34
 */
35
36
class Suricate
37
{
38
    const VERSION = '0.3.3';
39
40
    const CONF_DIR = '/conf/';
41
42
    private $config = [];
43
    private $configFile = [];
44
45
    private $useAutoloader = false;
46
47
    private static $servicesContainer;
48
    private static $servicesRepository;
49
50
    private $servicesList = [
51
        'App' => '\Suricate\App',
52
        'Cache' => '\Suricate\Cache',
53
        'CacheMemcache' => '\Suricate\Cache\Memcache',
54
        'CacheMemcached' => '\Suricate\Cache\Memcached',
55
        'CacheApc' => '\Suricate\Cache\Apc',
56
        'CacheFile' => '\Suricate\Cache\File',
57
        'Curl' => '\Suricate\Curl',
58
        'Database' => '\Suricate\Database',
59
        'Error' => '\Suricate\Error',
60
        'EventDispatcher' => '\Suricate\Event\EventDispatcher',
61
        'I18n' => '\Suricate\I18n',
62
        'Logger' => '\Suricate\Logger',
63
        'Request' => '\Suricate\Request',
64
        'Response' => '\Suricate\Request',
65
        'Router' => '\Suricate\Router',
66
        'Session' => '\Suricate\Session',
67
        'SessionNative' => '\Suricate\Session\Native',
68
        'SessionCookie' => '\Suricate\Session\Cookie',
69
        'SessionMemcache' => '\Suricate\Session\Memcache'
70
    ];
71
72
    /**
73
     * Suricate contructor
74
     *
75
     * @param array $paths Application paths
76
     * @param string|array|null $configFile path of configuration file(s)
77
     *
78
     * @SuppressWarnings(PHPMD.StaticAccess)
79
     */
80 8
    public function __construct($paths = [], $configFile = null)
81
    {
82 8
        if ($configFile !== null) {
83 6
            $this->setConfigFile($configFile);
84
        }
85
86
        // Load helpers
87 8
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'Helper.php';
88
89 8
        $this->loadConfig();
90 8
        $this->setAppPaths($paths);
91
92 8
        if ($this->useAutoloader) {
93
            // Configure autoloader
94
            require_once __DIR__ . DIRECTORY_SEPARATOR . 'AutoLoader.php';
95
            AutoLoader::register();
96
        }
97
98
        // Define error handler
99 8
        set_exception_handler(['\Suricate\Error', 'handleException']);
100 8
        set_error_handler(['\Suricate\Error', 'handleError']);
101 8
        register_shutdown_function(['\Suricate\Error', 'handleShutdownError']);
102
103 8
        self::$servicesRepository = new Container();
104
105 8
        $this->initServices();
106 8
    }
107
108 1
    public function getConfig()
109
    {
110 1
        return $this->config;
111
    }
112
113 8
    private function setAppPaths($paths = [])
114
    {
115 8
        foreach ($paths as $key => $value) {
116
            $this->config['App']['path.' . $key] = realpath($value);
117
        }
118
119 8
        return $this;
120
    }
121
    /**
122
     * Initialize Framework services
123
     * @return null
124
     */
125 8
    private function initServices()
126
    {
127 8
        self::$servicesRepository->setWarehouse($this->servicesList);
128
129 8
        self::$servicesRepository['Request']->parse();
130 8
        if (isset($this->config['App']['locale'])) {
131
            $this->config['I18n'] = [
132
                'locale' => $this->config['App']['locale']
133
            ];
134
        }
135
        // first sync, && init, dependency to Suricate::request
136 8
        self::$servicesContainer = clone self::$servicesRepository;
137
138 8
        foreach (array_keys($this->servicesList) as $serviceName) {
139 8
            if (isset($this->config[$serviceName])) {
140 8
                self::$servicesRepository[$serviceName]->configure(
141 8
                    $this->config[$serviceName]
142
                );
143
144
                /**
145
                 TODO : remove sync in service creation
146
                 */
147 8
                self::$servicesContainer = clone self::$servicesRepository;
148
            }
149
        }
150
151 8
        if (isset($this->config['Constants'])) {
152
            foreach (
153 1
                $this->config['Constants']
154
                as $constantName => $constantValue
155
            ) {
156 1
                $constantName = strtoupper($constantName);
157 1
                define($constantName, $constantValue);
158
            }
159
        }
160
161
        // final sync, repository is complete
162 8
        self::$servicesContainer = clone self::$servicesRepository;
163 8
    }
164
165 1
    public function hasService(string $serviceName): bool
166
    {
167 1
        return isset(self::$servicesContainer[$serviceName]);
168
    }
169
170 6
    private function setConfigFile($configFile)
171
    {
172 6
        foreach ((array) $configFile as $file) {
173 6
            if (is_file($file)) {
174 6
                $this->configFile[] = $file;
175
            }
176
        }
177
178 6
        return $this;
179
    }
180
    /**
181
     * Load framework configuration from ini file
182
     * @return null
183
     */
184 8
    private function loadConfig()
185
    {
186 8
        $userConfig = [];
187 8
        if (count($this->configFile)) {
188 6
            $userConfig = [];
189 6
            foreach ($this->configFile as $configFile) {
190 6
                $userConfig = array_merge_recursive(
191 6
                    $userConfig,
192 6
                    (array) parse_ini_file($configFile, true, INI_SCANNER_TYPED)
193
                );
194
            }
195
196
            // Advanced ini parsing, split key with '.' into subarrays
197 6
            foreach ($userConfig as $section => $configData) {
198 5
                foreach (array_keys($configData) as $name) {
199 5
                    $name = (string) $name;
200 5
                    if (stripos($name, '.') !== false) {
201
                        $subkeys = explode('.', $name);
202
                        unset($userConfig[$section][$name]);
203
                        $str =
204
                            "['" . implode("']['", $subkeys) . "'] = \$value;";
205
                        eval("\$userConfig[\$section]" . $str);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
206
                    }
207
                }
208
            }
209
        }
210
211 8
        foreach ($this->getDefaultConfig() as $context => $directives) {
212 8
            if (isset($userConfig[$context])) {
213
                $this->config[$context] = array_merge(
214
                    $directives,
215
                    $userConfig[$context]
216
                );
217
                unset($userConfig[$context]);
218
            } else {
219 8
                $this->config[$context] = $directives;
220
            }
221
        }
222
223 8
        $this->config = array_merge($this->config, $userConfig);
224
225 8
        $this->configureAppMode();
226 8
    }
227
228 8
    private function configureAppMode()
229
    {
230 8
        $errorReporting = true;
231 8
        $errorDumpContext = true;
232 8
        $logLevel = Logger::LOGLEVEL_WARN;
233 8
        $logFile = 'php://stdout';
234
235 8
        if (isset($this->config['App']['mode'])) {
236
            switch ($this->config['App']['mode']) {
237
                case App::DEVELOPMENT_MODE:
238
                    $errorReporting = true;
239
                    $errorDumpContext = true;
240
                    $logLevel = Logger::LOGLEVEL_INFO;
241
                    $logFile = 'php://stdout';
242
                    break;
243
                case App::DEBUG_MODE:
244
                    $errorReporting = true;
245
                    $errorDumpContext = true;
246
                    $logLevel = Logger::LOGLEVEL_DEBUG;
247
                    $logFile = 'php://stdout';
248
                    break;
249
                case App::PRELIVE_MODE:
250
                    $errorReporting = true;
251
                    $errorDumpContext = false;
252
                    $logLevel = Logger::LOGLEVEL_WARN;
253
                    $logFile = 'php://stderr';
254
                    break;
255
                case App::PRODUCTION_MODE:
256
                    $errorReporting = false;
257
                    $errorDumpContext = false;
258
                    $logLevel = Logger::LOGLEVEL_WARN;
259
                    $logFile = 'php://stderr';
260
                    break;
261
            }
262
        }
263 8
        if (isset($this->config['Logger']['level'])) {
264
            $logLevel = $this->config['Logger']['level'];
265
        }
266 8
        if (isset($this->config['Logger']['logfile'])) {
267
            $logFile = $this->config['Logger']['logfile'];
268
        }
269 8
        if (isset($this->config['Error']['report'])) {
270
            $errorReporting = $this->config['Error']['report'];
271
        }
272 8
        if (isset($this->config['Error']['dumpContext'])) {
273
            $errorDumpContext = $this->config['Error']['dumpContext'];
274
        }
275
276 8
        $this->config['Logger']['level'] = $logLevel;
277 8
        $this->config['Logger']['logfile'] = $logFile;
278 8
        $this->config['Error']['report'] = $errorReporting;
279 8
        $this->config['Error']['dumpContext'] = $errorDumpContext;
280 8
    }
281
    /**
282
     * Default setup template
283
     * @return array setup
284
     */
285 8
    private function getDefaultConfig()
286
    {
287
        return [
288 8
            'Router' => [],
289
            'Logger' => [
290
                'enabled' => true
291
            ],
292
            'App' => ['base_uri' => '/']
293
        ];
294
    }
295
296
    public function run()
297
    {
298
        self::$servicesContainer['Router']->doRouting();
299
    }
300
301 19
    public static function __callStatic($name, $arguments)
302
    {
303 19
        if (isset($arguments[0]) && $arguments[0] === true) {
304 1
            return clone self::$servicesRepository[$name];
305
        }
306
307 19
        return self::$servicesContainer[$name];
308
    }
309
}
310