Completed
Branch 4.0 (52c68b)
by Marc André
02:54
created

Core   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 287
Duplicated Lines 2.09 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 10
Bugs 2 Features 0
Metric Value
wmc 21
c 10
b 2
f 0
lcom 1
cbo 2
dl 6
loc 287
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 54 3
B initConfig() 0 42 3
A getLibrary() 3 21 4
A getController() 0 9 2
A getModel() 0 4 1
A getView() 0 4 1
A getPath() 3 12 2
A getTemplate() 0 4 1
A autoload() 0 14 4

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
4
/**
5
 *
6
 * Copyright (c) 2010-2016 Nevraxe inc. & Marc André Audet <[email protected]>. All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without modification, are
9
 * permitted provided that the following conditions are met:
10
 *
11
 *   1. Redistributions of source code must retain the above copyright notice, this list of
12
 *       conditions and the following disclaimer.
13
 *
14
 *   2. Redistributions in binary form must reproduce the above copyright notice, this list
15
 *       of conditions and the following disclaimer in the documentation and/or other materials
16
 *       provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 */
30
31
32
namespace Cervo;
33
34
35
use Cervo\Libraries\Route;
36
use Cervo\Libraries\Template;
37
38
39
/**
40
 * Core class for Cervo.
41
 *
42
 * @author Marc André Audet <[email protected]>
43
 */
44
class Core
45
{
46
    /**
47
     * The current version of Cervo.
48
     */
49
    const VERSION = '4.0.0';
50
51
    /**
52
     * All the libraries instances that have been initialized through getLibrary().
53
     * @var array
54
     */
55
    protected static $libraries = [];
56
57
    /**
58
     * All the controller instances that have been initialized through getController().
59
     * @var array
60
     */
61
    protected static $controllers = [];
62
63
    /**
64
     * Additinal autoloading functions.
65
     * @var callable[]
66
     */
67
    protected static $autoloads = [];
68
69
    /**
70
     * If Cervo have been initialized.
71
     * @var bool
72
     */
73
    private static $is_init = false;
74
75
    /**
76
     * If the configuration/autoloaders have been initialized.
77
     * @var bool
78
     */
79
    private static $is_init_config = false;
80
81
    /**
82
     * Initialize Cervo.
83
     *
84
     * @param string|null $json_config_file The path to the JSON configuration file to use.
85
     */
86
    public static function init($json_config_file = null)
87
    {
88
        // Check if the system is already initiated
89
90
        if (self::$is_init) {
91
            return;
92
        }
93
94
        self::$is_init = true;
95
96
97
        // Start the configuration process
98
99
        self::initConfig($json_config_file);
100
101
102
        // Events startup
103
104
        $events = self::getLibrary('Cervo/Events');
105
106
        $events->register('Cervo/System/Before');
107
        $events->register('Cervo/Controller/Before');
108
        $events->register('Cervo/Controller/After');
109
        $events->register('Cervo/System/After');
110
111
112
        // Fire the pre-system event
113
114
        $events->fire('Cervo/System/Before');
115
116
117
        // Get the required libraries
118
119
        $router = self::getLibrary('Cervo/Router');
120
121
122
        // Initialise the system
123
124
        $route = $router->dispatch();
125
126
        if ($route instanceof Route) {
127
            $events->fire('Cervo/Controller/Before');
128
129
            $method = $route->getMethod();
130
            self::getController($route->getModule() . '/' . $route->getController())->$method($route->getArguments(), $route->getParameters());
131
132
            $events->fire('Cervo/Controller/After');
133
        }
134
135
136
        // Fire the post-system event
137
138
        $events->fire('Cervo/System/After');
139
    }
140
141
    /**
142
     * Initialize the configuration for Cervo with default configs.
143
     *
144
     * @param string|null $json_config_file
145
     */
146
    public static function initConfig($json_config_file = null)
147
    {
148
        // Check if the system is already initiated
149
150
        if (self::$is_init_config) {
151
            return;
152
        }
153
154
        self::$is_init_config = true;
155
156
157
        // Add the autoloader
158
        spl_autoload_register('\Cervo\Core::autoload');
159
160
161
        // Small shortcut
162
163
        if (!defined('DS')) {
164
            define('DS', \DIRECTORY_SEPARATOR);
165
        }
166
167
168
        // Set the default configuration values
169
170
        $config = self::getLibrary('Cervo/Config');
171
172
        $cervo_directory = realpath(dirname(__FILE__)) . \DS;
173
174
        $config
175
            ->setDefault('Cervo/Application/Directory', '')
176
            ->setDefault('Cervo/Directory', $cervo_directory)
177
            ->setDefault('Cervo/Libraries/Directory', realpath($cervo_directory . 'Libraries') . \DS)
178
            ->setDefault('Cervo/Application/EventsPath', 'Events' . \DS)
179
            ->setDefault('Cervo/Application/ControllersPath', 'Controllers' . \DS)
180
            ->setDefault('Cervo/Application/ModelsPath', 'Models' . \DS)
181
            ->setDefault('Cervo/Application/ViewsPath', 'Views' . \DS)
182
            ->setDefault('Cervo/Application/LibariesPath', 'Libraries' . \DS)
183
            ->setDefault('Cervo/Application/TemplatesPath', 'Templates' . \DS)
184
            ->setDefault('Production', false);
185
186
        $config->importJSON($json_config_file);
187
    }
188
189
    /**
190
     * Return a library. It will be stored in an internal cache and reused if called again.
191
     * $name format: [Module]/[Name]
192
     * Name MAY contain slashes (/) to go deeper in the tree.
193
     * The module name Cervo may be used to access the Cervo standard libraries.
194
     *
195
     * If you do not want your library to be re-used, please access the library directly without
196
     * using any functions or methods. Ex:
197
     * new \Application\[Module]Module\Libraries\[Name]();
198
     *
199
     * @param string $name The path name
200
     *
201
     * @return object
202
     */
203
    public static function getLibrary($name)
204
    {
205
        if (is_object(self::$libraries[$name])) {
206
            return self::$libraries[$name];
207
        }
208
209
        $path = explode('/', $name);
210
211
        if (count($path) <= 1) {
212
            $i_name = '\Application\\' . $path[0] . 'Module\Libraries\\' . $path[0];
213
        } else {
214
            if ($path[0] === 'Cervo') {
215
                $i_name = '\Cervo\Libraries\\' . implode('\\', array_slice($path, 1));
216 View Code Duplication
            } else {
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...
217
                $i_name = '\Application\\' . $path[0] . 'Module\Libraries\\' . implode('\\', array_slice($path, 1));
218
            }
219
        }
220
221
        self::$libraries[$name] = new $i_name;
222
        return self::$libraries[$name];
223
    }
224
225
    /**
226
     * Return a controller. It will be stored in an internal cache and reused if called again.
227
     * $name format: [Module]/[Name]
228
     * $name MAY contain slashes (/) to go deeper in the tree.
229
     *
230
     * @param string $name The path name
231
     *
232
     * @return object
233
     */
234
    public static function getController($name)
235
    {
236
        if (is_object(self::$controllers[$name])) {
237
            return self::$controllers[$name];
238
        }
239
240
        self::$controllers[$name] = self::getPath($name, 'Controllers');
241
        return self::$controllers[$name];
242
    }
243
244
    /**
245
     * Return a model.
246
     * $name format: [Module]/[Name]
247
     * $name MAY contain slashes (/) to go deeper in the tree.
248
     *
249
     * @param string $name The path name
250
     *
251
     * @return object
252
     */
253
    public static function getModel($name)
254
    {
255
        return self::getPath($name, 'Models');
256
    }
257
258
    /**
259
     * Return a view.
260
     * $name format: [Module]/[Name]
261
     * $name MAY contain slashes (/) to go deeper in the tree.
262
     *
263
     * @param string $name The path name
264
     *
265
     * @return object
266
     */
267
    public static function getView($name)
268
    {
269
        return self::getPath($name, 'Views');
270
    }
271
272
    /**
273
     * Return an instanciated object depending on the module sub-folder.
274
     * $class_path format: [Module]/[Name]
275
     * $class_path MAY contain slashes (/) to go deeper in the tree.
276
     * $application_path is the module sub-folder to look in for.
277
     *
278
     * @param string $class_path The path name
279
     * @param string $application_path The sub-folder within the module
280
     *
281
     * @return object
282
     */
283
    public static function getPath($class_path, $application_path)
284
    {
285
        $path = explode('/', $class_path);
286
287
        if (count($path) <= 1) {
288
            $i_name = '\Application\\' . $path[0] . 'Module\\' . $application_path . '\\' . $path[0];
289 View Code Duplication
        } else {
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...
290
            $i_name = '\Application\\' . $path[0] . 'Module\\' . $application_path . '\\' . implode('\\', array_slice($path, 1));
291
        }
292
293
        return new $i_name;
294
    }
295
296
    /**
297
     * Return a template.
298
     * $name format: [Module]/[Name]
299
     * Name MAY contain slashes (/) to go deeper in the tree.
300
     *
301
     * @param string $name The path name
302
     *
303
     * @return Template
304
     */
305
    public static function getTemplate($name)
306
    {
307
        return new Template($name);
308
    }
309
310
    /**
311
     * The default class autoloader.
312
     * Also run any additional autoloaders added with register_autoload().
313
     *
314
     * @param string $name The class full name (Include the namespace(s))
315
     */
316
    public static function autoload($name)
317
    {
318
        if (strpos($name, 'Application\\') === 0) {
319
320
            $config = self::getLibrary('Cervo/Config');
321
322
            $ex = explode('\\', $name);
323
324
            if ($ex[0] === 'Application' && substr($ex[1], -1 * 6) === 'Module') {
325
                require $config->get('Cervo/Application/Directory') . substr($ex[1], 0, strlen($ex[1]) - 6) . \DS . implode(\DS, array_slice($ex, 2)) . '.php';
326
            }
327
328
        }
329
    }
330
}
331