Completed
Branch master (740422)
by Mathieu
02:04
created

Suricate   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 230
Duplicated Lines 8.7 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 10
Bugs 0 Features 0
Metric Value
dl 20
loc 230
ccs 0
cts 3
cp 0
rs 9.3999
c 10
b 0
f 0
wmc 33
lcom 1
cbo 2

9 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 27 3
A setAppPaths() 0 8 2
B initServices() 0 32 6
A setConfigFile() 0 12 3
C loadConfig() 0 35 8
B configureAppMode() 20 35 6
A getDefaultConfig() 0 13 1
A run() 0 4 1
A __callStatic() 0 8 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Fwk - Another micro PHP 5 framework
4
 *
5
 * @author      Mathieu LESNIAK <[email protected]>
6
 * @copyright   2013-2014 Mathieu LESNIAK
7
 * @version     0.1
8
 * @package     Suricate
9
 *
10
 * @method App          App() App() Get instance of App service
11
 * @method Database     Database() Database() Get instance of Database service
12
 * @method Error        Error() Error() Get instance of Error service
13
 * @method I18n         I18n() I18n() Get instance of I18n service
14
 * @method Request      Request() Request() Get instance of Request service
15
 */
16
namespace Suricate;
17
18
class Suricate
19
{
20
21
    const VERSION = '0.1';
22
23
    const CONF_DIR = '/conf/';
24
25
    protected $router;
26
27
    private $config;
28
    private $configFile;
29
30
    private $useAutoloader = false;
31
32
    private static $servicesContainer;
33
    private static $servicesRepository;
34
35
    private $servicesList = array(
36
        'Logger'            => '\Suricate\Logger',
37
        'App'               => '\Suricate\App',
38
        'I18n'              => '\Suricate\I18n',
39
        'Error'             => '\Suricate\Error',
40
        'Router'            => '\Suricate\Router',
41
        'Request'           => '\Suricate\Request',
42
        'Database'          => '\Suricate\Database',
43
        'Cache'             => '\Suricate\Cache',
44
        'CacheMemcache'     => '\Suricate\Cache\Memcache',
45
        'CacheApc'          => '\Suricate\Cache\Apc',
46
        'Curl'              => '\Suricate\Curl',
47
        'Response'          => '\Suricate\Request',
48
        'Session'           => '\Suricate\Session',
49
        'SessionNative'     => '\Suricate\Session\Native',
50
        'SessionCookie'     => '\Suricate\Session\Cookie',
51
        'SessionMemcache'   => '\Suricate\Session\Memcache',
52
    );
53
54
55
    public function __construct($paths = array(), $configFile = null)
56
    {
57
        if ($configFile !== null) {
58
            $this->setConfigFile($configFile);
59
        }
60
       
61
        // Load helpers
62
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'Helper.php';
63
64
        $this->loadConfig();
65
        $this->setAppPaths($paths);
66
67
        if ($this->useAutoloader) {
68
            // Configure autoloader
69
            require_once __DIR__ . DIRECTORY_SEPARATOR . 'AutoLoader.php';
70
            AutoLoader::register();
71
        }
72
73
        // Define error handler
74
        set_exception_handler(array('\Suricate\Error', 'handleException'));
75
        set_error_handler(array('\Suricate\Error', 'handleError'));
76
        register_shutdown_function(array('\Suricate\Error', 'handleShutdownError'));
77
78
        self::$servicesRepository = new Container();
79
80
        $this->initServices();
81
    }
82
83
    private function setAppPaths($paths = array())
84
    {
85
        foreach ($paths as $key=>$value) {
86
            $this->config['App']['path.' . $key] = realpath($value);
87
        }
88
89
        return $this;
90
    }
91
    /**
92
     * Initialize Framework services
93
     * @return null
94
     */
95
    private function initServices()
96
    {
97
        self::$servicesRepository->setWarehouse($this->servicesList);
98
99
        self::$servicesRepository['Request']->parse();
100
        if (isset($this->config['App']['locale'])) {
101
            $this->config['I18n'] = array('locale' => $this->config['App']['locale']);
102
        }
103
        // first sync, && init, dependency to Suricate::request
104
        self::$servicesContainer = clone self::$servicesRepository;
105
106
        foreach (array_keys($this->servicesList) as $serviceName) {
107
            if (isset($this->config[$serviceName])) {
108
                self::$servicesRepository[$serviceName]->configure($this->config[$serviceName]);
109
110
                /**
111
                 TODO : remove sync in service creation
112
                */
113
                self::$servicesContainer = clone self::$servicesRepository;
114
            }
115
        }
116
117
        if (isset($this->config['Constants'])) {
118
            foreach ($this->config['Constants'] as $constantName => $constantValue) {
119
                $constantName = strtoupper($constantName);
120
                define($constantName, $constantValue);
121
            }
122
        }
123
124
        // final sync, repository is complete
125
        self::$servicesContainer = clone self::$servicesRepository;
126
    }
127
128
    private function setConfigFile($configFile)
129
    {
130
        foreach ((array) $configFile as $file) {
131
            if (is_file($file)) {
132
                $this->configFile[] = $file;
133
            }
134
        }
135
        
136
        
137
138
        return $this;
139
    }
140
    /**
141
     * Load framework configuration from ini file
142
     * @return null
143
     */
144
    private function loadConfig()
145
    {
146
        $userConfig = array();
147
        if ($this->configFile !== null) {
148
            $userConfig = array();
149
            foreach ($this->configFile as $configFile) {
150
                $userConfig = array_merge($userConfig, parse_ini_file($configFile, true));
151
            }
152
153
            // Advanced ini parsing, split key with '.' into subarrays
154
            foreach ($userConfig as $section => $configData) {
155
                foreach ($configData as $name => $value) {
156
                    if (stripos($name, '.') !== false) {
157
                        $subkeys = explode('.', $name);
158
                        unset($userConfig[$section][$name]);
159
                        $str = "['" . implode("']['", $subkeys) . "'] = \$value;";
160
                        eval("\$userConfig[\$section]" . $str);
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
161
                    }
162
                }
163
            }
164
        }
165
166
        foreach ($this->getDefaultConfig() as $context => $directives) {
167
            if (isset($userConfig[$context])) {
168
                $this->config[$context] = array_merge($directives, $userConfig[$context]);
169
                unset($userConfig[$context]);
170
            } else {
171
                $this->config[$context] = $directives;
172
            }
173
        }
174
175
        $this->config = array_merge($this->config, $userConfig);
176
        
177
        $this->configureAppMode();
178
    }
179
180
    private function configureAppMode()
181
    {
182
        $errorReporting     = false;
183
        $errorDumpContext   = false;
184
        $logLevel           = Logger::LOGLEVEL_WARN;
185
        
186
        if (isset($this->config['App']['mode'])) {
187
            switch ($this->config['App']['mode']) {
188 View Code Duplication
                case App::DEVELOPMENT_MODE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
189
                    $errorReporting     = true;
190
                    $errorDumpContext   = true;
191
                    $logLevel           = Logger::LOGLEVEL_INFO;
192
                    break;
193 View Code Duplication
                case App::DEBUG_MODE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
                    $errorReporting     = true;
195
                    $errorDumpContext   = true;
196
                    $logLevel           = Logger::LOGLEVEL_DEBUG;
197
                    break;
198 View Code Duplication
                case App::PRELIVE_MODE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
                    $errorReporting     = true;
200
                    $errorDumpContext   = false;
201
                    $logLevel           = Logger::LOGLEVEL_WARN;
202
                    break;
203 View Code Duplication
                case App::PRODUCTION_MODE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
                    $errorReporting     = false;
205
                    $errorDumpContext   = false;
206
                    $logLevel           = Logger::LOGLEVEL_WARN;
207
                    break;
208
            }
209
        }
210
211
        $this->config['Error']['report']        = $errorReporting;
212
        $this->config['Error']['dumpContext']   = $errorDumpContext;
213
        $this->config['Logger']['level']        = $logLevel;
214
    }
215
216
    /**
217
     * Default setup template
218
     * @return array setup
219
     */
220
    private function getDefaultConfig()
221
    {
222
        return array(
223
                'Router'    => array(),
224
                'Session'   => array('type' => 'native'),
225
                'Logger'    => array(
226
                                'logfile'   => 'php://output',
227
                                'enabled'   => true,
228
                                'level'     => Logger::LOGLEVEL_INFO,
229
                            ),
230
                'App'       => array('base_uri' => '/'),
231
                );
232
    }
233
234
    public function run()
235
    {
236
        self::$servicesContainer['Router']->doRouting();
237
    }
238
239
    public static function __callStatic($name, $arguments)
240
    {
241
        if (isset($arguments[0]) && $arguments[0] === true) {
242
            return clone self::$servicesRepository[$name];
243
        } else {
244
            return self::$servicesContainer[$name];
245
        }
246
    }
247
}
248