Test Failed
Pull Request — master (#197)
by
unknown
10:13
created

Startup::injectDependencies()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 6

Importance

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