Passed
Push — master ( c1d44b...f8fb84 )
by Jean-Christophe
06:07
created

Startup::runCallable()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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