Completed
Push — 4.0 ( bb82bd...2eee71 )
by Marc André
02:22
created

Core::getInjectedControllers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
4
/**
5
 *
6
 * Copyright (c) 2010-2017 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
/**
36
 * Core class for Cervo.
37
 *
38
 * @author Marc André Audet <[email protected]>
39
 */
40
final class Core
41
{
42
    /**
43
     * The current version of Cervo.
44
     */
45
    const VERSION = '4.0.0';
46
47
    /**
48
     * All the libraries instances that have been initialized through getLibrary().
49
     * @var array
50
     */
51
    private static $libraries = [];
52
53
    /**
54
     * All the library classes to be used whend not found in the application through getLibrary().
55
     * @var array
56
     */
57
    private static $injected_libraries = [];
58
59
    /**
60
     * All the controller instances that have been initialized through getController().
61
     * @var array
62
     */
63
    private static $controllers = [];
64
65
    /**
66
     * All the controller classes to be used when not found in the application through getController().
67
     * @var array
68
     */
69
    private static $injected_controllers = [];
70
71
    /**
72
     * If Cervo have been initialized.
73
     * @var bool
74
     */
75
    private static $is_init = false;
76
77
    /**
78
     * If the configuration/autoloaders have been initialized.
79
     * @var bool
80
     */
81
    private static $is_init_config = false;
82
83
    /**
84
     * Initialize Cervo.
85
     *
86
     * @param string|null $json_config_file The path to the JSON configuration file to use.
87
     */
88
    public static function init(?string $json_config_file = null) : void
89
    {
90
        // Check if the system is already initiated
91
92
        if (self::$is_init) {
93
            return;
94
        }
95
96
        self::$is_init = true;
97
98
99
        // Start the configuration process
100
101
        self::initConfig($json_config_file);
102
103
104
        // Events startup
105
106
        $events = self::getLibrary('Cervo/Events');
107
108
        $events->register('Cervo/System/Before');
109
        $events->register('Cervo/Controller/Before');
110
        $events->register('Cervo/Controller/After');
111
        $events->register('Cervo/System/After');
112
113
114
        // Fire the pre-system event
115
116
        $events->fire('Cervo/System/Before');
117
118
119
        // Get the required libraries
120
121
        $router = self::getLibrary('Cervo/Router');
122
123
124
        // Initialise the system
125
126
        $route = $router->dispatch();
127
128
        if ($route instanceof Route) {
129
            $events->fire('Cervo/Controller/Before');
130
131
            $method = $route->getMethod();
132
            self::getController($route->getModule() . '/' . $route->getController())->$method($route->getArguments(), $route->getParameters());
133
134
            $events->fire('Cervo/Controller/After');
135
        }
136
137
138
        // Fire the post-system event
139
140
        $events->fire('Cervo/System/After');
141
    }
142
143
    public static function getInjectedLibraries() : array
144
    {
145
        return self::$injected_libraries;
146
    }
147
148
    public static function getInjectedControllers() : array
149
    {
150
        return self::$injected_controllers;
151
    }
152
153
    /**
154
     * Initialize the configuration for Cervo with default configs.
155
     *
156
     * @param string|null $json_config_file
157
     */
158
    public static function initConfig(?string $json_config_file = null) : void
159
    {
160
        // Check if the system is already initiated
161
162
        if (self::$is_init_config) {
163
            return;
164
        }
165
166
        self::$is_init_config = true;
167
168
169
        // Add the autoloader
170
        spl_autoload_register('\Cervo\Core::autoload');
171
172
173
        // Small shortcut
174
175
        if (!defined('DS')) {
176
            define('DS', \DIRECTORY_SEPARATOR);
177
        }
178
179
180
        // Set the default configuration values
181
182
        $config = self::getLibrary('Cervo/Config');
183
184
        $cervo_directory = realpath(dirname(__FILE__)) . \DS;
185
186
        $config
187
            ->setDefault('Cervo/Application/Directory', '')
188
            ->setDefault('Cervo/Directory', $cervo_directory)
189
            ->setDefault('Cervo/Libraries/Directory', realpath($cervo_directory . 'Libraries') . \DS)
190
            ->setDefault('Production', false);
191
192
        $config->importJSON($json_config_file);
193
    }
194
195
    /**
196
     * First iteration of a provider interface to inject elements into Cervo.
197
     *
198
     * @param ProviderInterface $provider
199
     */
200
    public static function register(ProviderInterface $provider)
201
    {
202
        $provider->register();
203
    }
204
205
    /**
206
     * Return a library. It will be stored in an internal cache and reused if called again.
207
     * $name format: [Module]/[Name]
208
     * Name MAY contain slashes (/) to go deeper in the tree.
209
     * The module name Cervo may be used to access the Cervo standard libraries.
210
     *
211
     * @param string $name The path name
212
     *
213
     * @return object
214
     */
215
    public static function getLibrary(string $name)
216
    {
217
        if (is_object(self::$libraries[$name])) {
218
            return self::$libraries[$name];
219
        }
220
221
        $path = explode('/', $name);
222
223
        if ($path[0] === 'Cervo') {
224
            $i_name = '\Cervo\Libraries\\' . implode('\\', array_slice($path, 1));
225
        } else {
226
            $i_name = self::getPath($name, 'Libraries');
227
        }
228
229
        if (!class_exists($i_name, true) && isset(self::$injected_libraries[$name])) {
230
            $i_name = self::$injected_libraries[$name];
231
        }
232
233
        return (self::$libraries[$name] = new $i_name);
234
    }
235
236
    /**
237
     * Injects a library to be used in getLibrary() if not found in the application.
238
     *
239
     * @param string $name The path name
240
     * @param string $i_name The class name
241
     */
242
    public static function injectLibrary(string $name, string $i_name)
243
    {
244
        self::$injected_libraries[$name] = $i_name;
245
    }
246
247
    /**
248
     * Return a controller. It will be stored in an internal cache and reused if called again.
249
     * $name format: [Module]/[Name]
250
     * $name MAY contain slashes (/) to go deeper in the tree.
251
     *
252
     * @param string $name The path name
253
     *
254
     * @return object
255
     */
256
    public static function getController(string $name)
257
    {
258
        if (is_object(self::$controllers[$name])) {
259
            return self::$controllers[$name];
260
        }
261
262
        $i_name = self::getPath($name, 'Libraries');
263
264
        if (!class_exists($i_name, true) && isset(self::$injected_controllers[$name])) {
265
            $i_name = self::$injected_controllers[$name];
266
        }
267
268
        return (self::$controllers[$name] = new $i_name);
269
    }
270
271
    /**
272
     * Injects a controller to be used in getController() if not found in the application.
273
     *
274
     * @param string $name The path name
275
     * @param string $i_name The class name
276
     */
277
    public static function injectController(string $name, string $i_name)
278
    {
279
        self::$injected_controllers[$name] = $i_name;
280
    }
281
282
    /**
283
     * Return an instanciated object depending on the module sub-folder.
284
     * $class_path format: [Module]/[Name]
285
     * $class_path MAY contain slashes (/) to go deeper in the tree.
286
     * $application_path is the module sub-folder to look in for.
287
     *
288
     * @param string $name The path name
289
     * @param string $application_path The sub-folder within the module
290
     *
291
     * @return object
292
     */
293
    public static function getPath(string $name, string $application_path)
294
    {
295
        $path = explode('/', $name);
296
297
        if (count($path) <= 1) {
298
            $i_name = '\Application\\' . $path[0] . 'Module\\' . $application_path . '\\' . $path[0];
299
        } else {
300
            $i_name = '\Application\\' . $path[0] . 'Module\\' . $application_path . '\\' . implode('\\', array_slice($path, 1));
301
        }
302
303
        return new $i_name;
304
    }
305
306
    /**
307
     * Return a template.
308
     * $name format: [Module]/[Name]
309
     * Name MAY contain slashes (/) to go deeper in the tree.
310
     *
311
     * @param string $name The path name
312
     *
313
     * @return Template
314
     */
315
    public static function getTemplate(string $name) : Template
316
    {
317
        return new Template($name);
318
    }
319
320
    /**
321
     * The default class autoloader.
322
     * Also run any additional autoloaders added with register_autoload().
323
     *
324
     * @param string $name The class full name (Include the namespace(s))
325
     */
326
    public static function autoload(string $name) : void
327
    {
328
        if (strpos($name, 'Application\\') === 0) {
329
330
            $config = self::getLibrary('Cervo/Config');
331
332
            $ex = explode('\\', $name);
333
334
            if ($ex[0] === 'Application' && substr($ex[1], -1 * 6) === 'Module') {
335
                require $config->get('Cervo/Application/Directory') . substr($ex[1], 0, strlen($ex[1]) - 6) . \DS . implode(\DS, array_slice($ex, 2)) . '.php';
336
            }
337
338
        }
339
    }
340
}
341