Passed
Push — master ( 75437d...7ef250 )
by Jean-Christophe
07:19
created

Startup::callController()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4.0072

Importance

Changes 0
Metric Value
cc 4
eloc 15
nc 4
nop 2
dl 0
loc 19
ccs 12
cts 13
cp 0.9231
crap 4.0072
rs 9.7666
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 38
	private static function _preRunAction(&$u, $initialize = true, $finalize = true) {
29 38
		if (\class_exists ( $u [0] )) {
30 38
			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 38
	}
36
37 38
	private static function parseUrl(&$url) {
38 38
		if (! $url) {
39 3
			$url = "_default";
40
		}
41 38
		if (UString::endswith ( $url, "/" ))
42 11
			$url = \substr ( $url, 0, strlen ( $url ) - 1 );
43 38
		self::$urlParts = \explode ( "/", $url );
44
45 38
		return self::$urlParts;
46
	}
47
48 37
	private static function startTemplateEngine(&$config) {
49
		try {
50 37
			if (isset ( $config ['templateEngine'] )) {
51 37
				$templateEngine = $config ['templateEngine'];
52 37
				$engineOptions = $config ['templateEngineOptions'] ?? array ('cache' => \ROOT . \DS . 'views/cache/' );
53 37
				$engine = new $templateEngine ( $engineOptions );
54 37
				if ($engine instanceof TemplateEngine) {
55 37
					self::$templateEngine = $engine;
56
				}
57
			}
58
		} catch ( \Exception $e ) {
59
			echo $e->getTraceAsString ();
60
		}
61 37
	}
62
63
	/**
64
	 * Handles the request
65
	 *
66
	 * @param array $config The loaded config array
67
	 */
68 37
	public static function run(array &$config) {
69 37
		self::$config = $config;
70 37
		self::startTemplateEngine ( $config );
71 37
		if (isset ( $config ['sessionName'] ))
72 37
			USession::start ( $config ['sessionName'] );
73 37
		self::forward ( $_GET ['c'] );
74 37
	}
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 38
	public static function forward($url, $initialize = true, $finalize = true) {
84 38
		$u = self::parseUrl ( $url );
85 38
		if (($ru = Router::getRoute ( $url )) !== false) {
86 14
			if (\is_array ( $ru )) {
87 14
				if (is_callable ( $ru [0] )) {
88
					self::runCallable ( $ru );
89
				} else {
90 14
					self::_preRunAction ( $ru, $initialize, $finalize );
91
				}
92
			} else {
93 5
				echo $ru; // Displays route response from cache
94
			}
95
		} else {
96 31
			self::setCtrlNS ();
97 31
			$u [0] = self::$ctrlNS . $u [0];
98 31
			self::_preRunAction ( $u, $initialize, $finalize );
99
		}
100 38
	}
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 39
	public static function runAction(array &$u, $initialize = true, $finalize = true) {
123 39
		$ctrl = $u [0];
124 39
		self::$controller = $ctrl;
125 39
		self::$action = "index";
126 39
		self::$actionParams = [ ];
127 39
		if (\sizeof ( $u ) > 1)
128 38
			self::$action = $u [1];
129 39
		if (\sizeof ( $u ) > 2)
130 17
			self::$actionParams = array_slice ( $u, 2 );
131
132 39
		$controller = new $ctrl ();
133 39
		if (! $controller instanceof Controller) {
134
			print "`{$u[0]}` isn't a controller instance.`<br/>";
135
			return;
136
		}
137
		// Dependency injection
138 39
		self::injectDependences ( $controller );
139 39
		if (! $controller->isValid ( self::$action )) {
140 6
			$controller->onInvalidControl ();
141
		} else {
142 39
			if ($initialize)
143 39
				$controller->initialize ();
144 39
			self::callController ( $controller, $u );
145 39
			if ($finalize)
146 39
				$controller->finalize ();
147
		}
148 39
	}
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 42
	public static function injectDependences($controller) {
175 42
		$di = DiManager::fetch ( $controller );
176 42
		if ($di !== false) {
177 21
			foreach ( $di as $k => $v ) {
178 21
				$setter = 'set' . ucfirst ( $k );
179 21
				if (method_exists ( $controller, $setter )) {
180 4
					$controller->$setter ( $v ( $controller ) );
181
				} else {
182 21
					$controller->$k = $v ( $controller );
183
				}
184
			}
185
		}
186
187 42
		$di = self::$config ['di'] ?? [ ];
188 42
		if (isset ( $di ['@exec'] )) {
189 8
			foreach ( $di ['@exec'] as $k => $v ) {
190 8
				$controller->$k = $v ( $controller );
191
			}
192
		}
193 42
	}
194
195
	/**
196
	 * Runs an action on a controller and returns a string
197
	 *
198
	 * @param array $u
199
	 * @param boolean $initialize If true, the **initialize** method of the controller is called
200
	 * @param boolean $finalize If true, the **finalize** method of the controller is called
201
	 * @return string
202
	 */
203 1
	public static function runAsString(array &$u, $initialize = true, $finalize = true) {
204 1
		\ob_start ();
205 1
		self::runAction ( $u, $initialize, $finalize );
206 1
		return \ob_get_clean ();
207
	}
208
209 39
	private static function callController(Controller $controller, array &$u) {
210 39
		$urlSize = sizeof ( $u );
211
		switch ($urlSize) {
212 39
			case 1 :
213 16
				$controller->index ();
214 16
				break;
215 36
			case 2 :
216 27
				$action = $u [1];
217
				// Appel de la méthode (2ème élément du tableau)
218 27
				if (\method_exists ( $controller, $action )) {
219 27
					$controller->$action ();
220
				} else {
221
					Logger::warn ( "Startup", "The method `{$action}` doesn't exists on controller `" . $u [0] . "`", "callController" );
222
				}
223 27
				break;
224
			default :
225
				// Appel de la méthode en lui passant en paramètre le reste du tableau
226 17
				\call_user_func_array ( array ($controller,$u [1] ), self::$actionParams );
227 17
				break;
228
		}
229 39
	}
230
231
	public static function errorHandler($message = "", $code = 0, $severity = 1, $filename = null, int $lineno = 0, $previous = NULL) {
232
		if (\error_reporting () == 0) {
233
			return;
234
		}
235
		if (\error_reporting () & $severity) {
236
			throw new \ErrorException ( $message, 0, $severity, $filename, $lineno, $previous );
237
		}
238
	}
239
240
	/**
241
	 * Returns the active controller name
242
	 *
243
	 * @return string
244
	 */
245 13
	public static function getController() {
246 13
		return self::$controller;
247
	}
248
249
	/**
250
	 * Returns the class simple name of the active controller
251
	 *
252
	 * @return string
253
	 */
254 1
	public static function getControllerSimpleName() {
255 1
		return (new \ReflectionClass ( self::$controller ))->getShortName ();
256
	}
257
258
	/**
259
	 * Returns the extension for view files
260
	 *
261
	 * @return string
262
	 */
263 1
	public static function getViewNameFileExtension() {
264 1
		return "html";
265
	}
266
267
	/**
268
	 * Returns tha active action
269
	 *
270
	 * @return string
271
	 */
272 20
	public static function getAction() {
273 20
		return self::$action;
274
	}
275
276
	/**
277
	 * Returns the active parameters
278
	 *
279
	 * @return array
280
	 */
281 10
	public static function getActionParams() {
282 10
		return self::$actionParams;
283
	}
284
285
	/**
286
	 * Returns the framework directory
287
	 *
288
	 * @return string
289
	 */
290 40
	public static function getFrameworkDir() {
291 40
		return \dirname ( __FILE__ );
292
	}
293
294
	/**
295
	 * Returns the application directory (app directory)
296
	 *
297
	 * @return string
298
	 */
299 3
	public static function getApplicationDir() {
300 3
		return \dirname ( \ROOT );
301
	}
302
303
	/**
304
	 * Returns the application name
305
	 *
306
	 * @return string
307
	 */
308 1
	public static function getApplicationName() {
309 1
		return basename ( \dirname ( \ROOT ) );
310
	}
311
}
312