Passed
Push — master ( f63d0b...f41ba3 )
by Jean-Christophe
10:17
created

Startup::getViewNameFileExtension()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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