Test Failed
Push — master ( 7dd754...0568ce )
by Jean-Christophe
15:22
created

Startup::getControllerInstance()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.2

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 11
c 2
b 1
f 0
dl 0
loc 16
ccs 8
cts 10
cp 0.8
rs 9.6111
cc 5
nc 4
nop 1
crap 5.2
1
<?php
2
3
namespace Ubiquity\controllers;
4
5
use Ubiquity\controllers\di\DiManager;
6
use Ubiquity\controllers\traits\StartupConfigTrait;
7
use Ubiquity\log\Logger;
8
use Ubiquity\utils\http\USession;
9
use Ubiquity\views\engine\TemplateEngine;
10
11
/**
12
 * Starts the framework.
13
 * This class is part of Ubiquity
14
 *
15
 * @author jcheron <[email protected]>
16
 * @version 1.1.6
17
 *
18
 */
19
class Startup {
20
	use StartupConfigTrait;
21
	public static $urlParts;
22
	public static $templateEngine;
23
	private static $controller;
24
	private static $action;
25
	private static $actionParams;
26
	private static $controllers = [ ];
27
28 47
	private static function parseUrl(&$url): array {
29 47
		if (! $url) {
30 3
			$url = '_default';
31
		}
32 47
		return self::$urlParts = \explode ( '/', \rtrim ( $url, '/' ) );
33
	}
34
35 48
	public static function getControllerInstance($controllerName): ?object {
36 48
		if (! isset ( self::$controllers [$controllerName] )) {
37
			if (\class_exists ( $controllerName, true )) {
38 41
				$controller = new $controllerName ();
39
				// Dependency injection
40 41
				if (isset ( self::$config ['di'] ) && \is_array ( self::$config ['di'] )) {
41 41
					self::injectDependences ( $controller );
42
				}
43 41
				self::$controllers [$controllerName] = $controller;
44 34
			} else {
45
				Logger::warn ( 'Startup', 'The controller `' . $controllerName . '` doesn\'t exists! <br/>', 'runAction' );
46
				self::getHttpInstance ()->header ( 'HTTP/1.0 404 Not Found', '', true, 404 );
47
				return null;
48
			}
49 48
		}
50
		return self::$controllers [$controllerName];
51
	}
52 46
53
	private static function startTemplateEngine(&$config): void {
54 46
		try {
55 46
			$templateEngine = $config ['templateEngine'];
56 46
			$engineOptions = $config ['templateEngineOptions'] ?? array ('cache' => false );
57 46
			$engine = new $templateEngine ( $engineOptions );
58 46
			if ($engine instanceof TemplateEngine) {
59
				self::$templateEngine = $engine;
60
			}
61
		} catch ( \Exception $e ) {
62
			echo $e->getTraceAsString ();
63 46
		}
64
	}
65
66
	/**
67
	 * Handles the request
68
	 *
69
	 * @param array $config The loaded config array
70 46
	 */
71 46
	public static function run(array &$config): void {
72 46
		self::init ( $config );
73 46
		self::forward ( $_GET ['c'] );
74
	}
75
76
	/**
77
	 * Initialize the app with $config array
78
	 *
79
	 * @param array $config
80 46
	 */
81 46
	public static function init(array &$config): void {
82 46
		self::$config = $config;
83 46
		if (isset ( $config ['templateEngine'] )) {
84
			self::startTemplateEngine ( $config );
85 46
		}
86 46
		if (isset ( $config ['sessionName'] )) {
87
			USession::start ( $config ['sessionName'] );
88 46
		}
89
	}
90
91
	/**
92
	 * Forwards to url
93
	 *
94
	 * @param string $url The url to forward to
95
	 * @param boolean $initialize If true, the **initialize** method of the controller is called
96
	 * @param boolean $finalize If true, the **finalize** method of the controller is called
97 47
	 */
98 47
	public static function forward($url, $initialize = true, $finalize = true): void {
99 47
		$u = self::parseUrl ( $url );
100 19
		if (\is_array ( Router::getRoutes () ) && ($ru = Router::getRoute ( $url, true, self::$config ['debug'] ?? false)) !== false) {
101 19
			if (\is_array ( $ru )) {
102 19
				if (\is_string ( $ru [0] )) {
103
					self::runAction ( $ru, $initialize, $finalize );
104 19
				} else {
105
					self::runCallable ( $ru );
106
				}
107 19
			} else {
108
				echo $ru; // Displays route response from cache
109
			}
110 46
		} else {
111 46
			$u [0] = self::setCtrlNS () . $u [0];
112
			self::runAction ( $u, $initialize, $finalize );
113 47
		}
114
	}
115
116
	/**
117
	 * Returns the template engine instance
118
	 *
119
	 * @return TemplateEngine
120 3
	 */
121 3
	public static function getTempateEngineInstance(): ?TemplateEngine {
122 3
		$config = self::$config;
123 3
		if (isset ( $config ['templateEngine'] )) {
124 3
			$templateEngine = $config ['templateEngine'];
125
			return new $templateEngine ( [ ] );
126
		}
127
		return null;
128
	}
129
130
	/**
131
	 * Runs an action on a controller
132
	 *
133
	 * @param array $u An array containing controller, action and parameters
134
	 * @param boolean $initialize If true, the **initialize** method of the controller is called
135
	 * @param boolean $finalize If true, the **finalize** method of the controller is called
136 48
	 */
137 48
	public static function runAction(array &$u, $initialize = true, $finalize = true): void {
138 48
		self::$controller = $ctrl = $u [0];
139 48
		$uSize = \sizeof ( $u );
140 48
		self::$action = $u [1] ?? 'index';
141
		self::$actionParams = ($uSize > 2) ? \array_slice ( $u, 2 ) : [ ];
142 48
143 48
		try {
144 6
			if (null !== $controller = self::getControllerInstance ( $ctrl )) {
145
				if (! $controller->isValid ( self::$action )) {
146 48
					$controller->onInvalidControl ();
147 48
				} else {
148
					if ($initialize) {
149
						$controller->initialize ();
150 48
					}
151
					try {
152 48
						if (\call_user_func_array ( [ $controller,self::$action ], self::$actionParams ) === false) {
153
							Logger::warn ( 'Startup', 'The action ' . self::$action . " does not exists on controller `{$ctrl}`", 'runAction' );
154
							self::getHttpInstance ()->header ( 'HTTP/1.0 404 Not Found', '', true, 404 );
155
						}
156
					} catch ( \Error $e ) {
157
						Logger::warn ( 'Startup', $e->getTraceAsString (), 'runAction' );
158
						if (self::$config ['debug']) {
159
							throw $e;
160 48
						}
161 48
					}
162
					if ($finalize) {
163
						$controller->finalize ();
164 48
					}
165
				}
166
			}
167
		} catch ( \Error $eC ) {
168
			Logger::warn ( 'Startup', $eC->getTraceAsString (), 'runAction' );
169
			if (self::$config ['debug']) {
170
				throw $eC;
171
			}
172
		}
173
	}
174
175
	/**
176
	 * Runs a callback
177
	 *
178
	 * @param array $u An array containing a callback, and some parameters
179
	 */
180
	public static function runCallable(array &$u): void {
181
		self::$actionParams = [ ];
182
		if (\sizeof ( $u ) > 1) {
183
			self::$actionParams = \array_slice ( $u, 1 );
184
		}
185
		if (isset ( self::$config ['di'] )) {
186
			$di = self::$config ['di'];
187
			if (\is_array ( $di )) {
188
				self::$actionParams = \array_merge ( self::$actionParams, $di );
189
			}
190 44
		}
191 44
		\call_user_func_array ( $u [0], self::$actionParams );
192 44
	}
193 36
194 36
	/**
195 36
	 * Injects the dependencies from the **di** config key in a controller
196 4
	 *
197
	 * @param Controller $controller The controller
198 36
	 */
199
	public static function injectDependences($controller): void {
200
		$di = DiManager::fetch ( $controller );
201
		if ($di !== false) {
202
			foreach ( $di as $k => $v ) {
203 44
				$setter = 'set' . ucfirst ( $k );
204 44
				if (\method_exists ( $controller, $setter )) {
205 41
					$controller->$setter ( $v ( $controller ) );
206 41
				} else {
207
					$controller->$k = $v ( $controller );
208
				}
209 44
			}
210
		}
211
212
		$di = self::$config ['di'] ?? [ ];
213
		if (isset ( $di ['@exec'] )) {
214
			foreach ( $di ['@exec'] as $k => $v ) {
215
				$controller->$k = $v ( $controller );
216
			}
217
		}
218
	}
219 1
220 1
	/**
221 1
	 * Runs an action on a controller and returns a string
222 1
	 *
223
	 * @param array $u
224
	 * @param boolean $initialize If true, the **initialize** method of the controller is called
225
	 * @param boolean $finalize If true, the **finalize** method of the controller is called
226
	 * @return string
227
	 */
228
	public static function runAsString(array &$u, $initialize = true, $finalize = true): string {
229
		\ob_start ();
230
		self::runAction ( $u, $initialize, $finalize );
231
		return \ob_get_clean ();
232
	}
233
234
	public static function errorHandler($message = '', $code = 0, $severity = 1, $filename = null, int $lineno = 0, $previous = NULL) {
235
		if (\error_reporting () == 0) {
236
			return;
237
		}
238
		if (\error_reporting () & $severity) {
239 8
			throw new \ErrorException ( $message, 0, $severity, $filename, $lineno, $previous );
240 8
		}
241
	}
242
243
	/**
244
	 * Returns the active controller name
245
	 *
246
	 * @return string
247
	 */
248 2
	public static function getController(): string {
249 2
		return self::$controller;
250
	}
251
252
	/**
253
	 * Returns the class simple name of the active controller
254
	 *
255
	 * @return string
256
	 */
257 1
	public static function getControllerSimpleName(): string {
258 1
		return (new \ReflectionClass ( self::$controller ))->getShortName ();
259
	}
260
261
	/**
262
	 * Returns the extension for view files
263
	 *
264
	 * @return string
265
	 */
266 21
	public static function getViewNameFileExtension(): string {
267 21
		return "html";
268
	}
269
270
	/**
271
	 * Returns tha active action
272
	 *
273
	 * @return string
274
	 */
275 4
	public static function getAction(): string {
276 4
		return self::$action;
277
	}
278
279
	/**
280
	 * Returns the active parameters
281
	 *
282
	 * @return array
283
	 */
284 48
	public static function getActionParams(): array {
285 48
		return self::$actionParams;
286
	}
287
288
	/**
289
	 * Returns the framework directory
290
	 *
291
	 * @return string
292
	 */
293 3
	public static function getFrameworkDir(): string {
294 3
		return \dirname ( __FILE__ );
295
	}
296
297
	/**
298
	 * Returns the application directory (app directory)
299
	 *
300
	 * @return string
301
	 */
302 1
	public static function getApplicationDir(): string {
303 1
		return \dirname ( \ROOT );
304
	}
305
306
	/**
307
	 * Returns the application name
308
	 *
309
	 * @return string
310
	 */
311
	public static function getApplicationName(): string {
312
		return \basename ( \dirname ( \ROOT ) );
313
	}
314
}
315