Test Failed
Push — master ( 26590d...3034a5 )
by Jean-Christophe
14:48 queued 27s
created

Startup   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 285
Duplicated Lines 0 %

Test Coverage

Coverage 78.33%

Importance

Changes 15
Bugs 1 Features 1
Metric Value
wmc 50
eloc 108
c 15
b 1
f 1
dl 0
loc 285
ccs 94
cts 120
cp 0.7833
rs 8.4

20 Methods

Rating   Name   Duplication   Size   Complexity  
A getApplicationName() 0 2 1
A getControllerSimpleName() 0 2 1
A errorHandler() 0 6 3
A getFrameworkDir() 0 2 1
A getController() 0 2 1
A runAsString() 0 4 1
A getViewNameFileExtension() 0 2 1
A getAction() 0 2 1
A getApplicationDir() 0 2 1
A getActionParams() 0 2 1
A injectDependences() 0 17 6
A getTempateEngineInstance() 0 7 2
A run() 0 3 1
A parseUrl() 0 5 2
A startTemplateEngine() 0 10 3
B runAction() 0 30 9
A runCallable() 0 10 3
A init() 0 9 3
A _getControllerInstance() 0 12 4
A forward() 0 15 5

How to fix   Complexity   

Complex Class

Complex classes like Startup often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Startup, and based on these observations, apply Extract Interface, too.

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