Completed
Push — master ( 3845e2...5afe3b )
by Jean-Christophe
02:10
created

Startup   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 61
lcom 1
cbo 5
dl 0
loc 251
rs 3.52
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 7 2
A forward() 0 18 4
A getNS() 0 8 3
A setCtrlNS() 0 3 1
A parseUrl() 0 10 3
A startTemplateEngine() 0 17 5
B runAction() 0 27 7
A injectDependences() 0 10 4
A runAsString() 0 5 1
A callController() 0 21 4
A getConfig() 0 3 1
A setConfig() 0 3 1
A needsKeyInConfigArray() 0 7 4
A checkDbConfig() 0 11 2
A checkModelsConfig() 0 10 2
A getModelsDir() 0 3 1
A getModelsCompletePath() 0 3 1
A errorHandler() 0 8 3
A getController() 0 3 1
A getControllerSimpleName() 0 3 1
A getViewNameFileExtension() 0 3 1
A getAction() 0 3 1
A getActionParams() 0 3 1
A getFrameworkDir() 0 3 1
A getApplicationDir() 0 3 1
A getApplicationName() 0 3 1
A reloadConfig() 0 7 1
A saveConfig() 0 9 3

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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\utils\base\UString;
6
use Ubiquity\views\engine\TemplateEngine;
7
use Ubiquity\utils\http\USession;
8
use Ubiquity\utils\base\UFileSystem;
9
use Ubiquity\log\Logger;
10
11
class Startup {
12
	public static $urlParts;
13
	public static $templateEngine;
14
	private static $config;
15
	private static $ctrlNS;
16
	private static $controller;
17
	private static $action;
18
	private static $actionParams;
19
20
	public static function run(array &$config, $url) {
21
		self::$config = $config;
22
		self::startTemplateEngine ( $config );
23
		if (isset ( $config ["sessionName"] ))
24
			USession::start ( $config ["sessionName"] );
25
		self::forward ( $url );
26
	}
27
28
	public static function forward($url) {
29
		$u = self::parseUrl ( $url );
30
		if (($ru = Router::getRoute ( $url )) !== false) {
31
			if (\is_array ( $ru ))
32
				self::runAction ( $ru );
33
			else
34
				echo $ru;
35
		} else {
36
			self::setCtrlNS ();
37
			$u [0] = self::$ctrlNS . $u [0];
38
			if (\class_exists ( $u [0] )) {
39
				self::runAction ( $u );
40
			} else {
41
				\header ( 'HTTP/1.0 404 Not Found', true, 404 );
42
				Logger::warn("Startup", "The controller `" . $u [0] . "` doesn't exists! <br/>","forward");
43
			}
44
		}
45
	}
46
47
	public static function getNS($part = "controllers") {
48
		$config = self::$config;
49
		$ns = $config ["mvcNS"] [$part];
50
		if ($ns !== "" && $ns !== null) {
51
			$ns .= "\\";
52
		}
53
		return $ns;
54
	}
55
56
	private static function setCtrlNS() {
57
		self::$ctrlNS = self::getNS ();
58
	}
59
60
	private static function parseUrl(&$url) {
61
		if (! $url) {
62
			$url = "_default";
63
		}
64
		if (UString::endswith ( $url, "/" ))
65
			$url = \substr ( $url, 0, strlen ( $url ) - 1 );
66
		self::$urlParts = \explode ( "/", $url );
67
68
		return self::$urlParts;
69
	}
70
71
	private static function startTemplateEngine($config) {
72
		try {
73
			$engineOptions = array ('cache' => ROOT . DS . "views/cache/" );
74
			if (isset ( $config ["templateEngine"] )) {
75
				$templateEngine = $config ["templateEngine"];
76
				if (isset ( $config ["templateEngineOptions"] )) {
77
					$engineOptions = $config ["templateEngineOptions"];
78
				}
79
				$engine = new $templateEngine ( $engineOptions );
80
				if ($engine instanceof TemplateEngine) {
81
					self::$templateEngine = $engine;
82
				}
83
			}
84
		} catch ( \Exception $e ) {
85
			echo $e->getTraceAsString ();
86
		}
87
	}
88
89
	public static function runAction($u, $initialize = true, $finalize = true) {
90
		$config = self::getConfig ();
91
		$ctrl = $u [0];
92
		self::$controller = $ctrl;
93
		self::$action = "index";
94
		if (\sizeof ( $u ) > 1)
95
			self::$action = $u [1];
96
		if (\sizeof ( $u ) > 2)
97
			self::$actionParams=array_slice ( $u, 2 );
98
99
		$controller = new $ctrl ();
100
		if (! $controller instanceof Controller) {
101
			print "`{$u[0]}` isn't a controller instance.`<br/>";
102
			return;
103
		}
104
		// Dependency injection
105
		self::injectDependences($controller, $config);
106
		if(!$controller->isValid(self::$action)){
107
			$controller->onInvalidControl();
108
		}else{
109
			if ($initialize)
110
				$controller->initialize ();
111
			self::callController ( $controller, $u );
112
			if ($finalize)
113
				$controller->finalize ();
114
		}
115
	}
116
	
117
	public static function injectDependences($controller,$config){
118
		if (\array_key_exists ( "di", $config )) {
119
			$di = $config ["di"];
120
			if (\is_array ( $di )) {
121
				foreach ( $di as $k => $v ) {
122
					$controller->$k = $v ( $controller );
123
				}
124
			}
125
		}
126
	}
127
128
	public static function runAsString($u, $initialize = true, $finalize = true) {
129
		\ob_start ();
130
		self::runAction ( $u, $initialize, $finalize );
131
		return \ob_get_clean ();
132
	}
133
134
	private static function callController(Controller $controller, $u) {
135
		$urlSize = sizeof ( $u );
136
		switch ($urlSize) {
137
			case 1 :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
138
				$controller->index ();
139
				break;
140
			case 2 :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
141
				$action = $u [1];
142
				// Appel de la méthode (2ème élément du tableau)
143
				if (\method_exists ( $controller, $action )) {
144
					$controller->$action ();
145
				} else {
146
					Logger::warn("Startup","The method `{$action}` doesn't exists on controller `" . $u [0] . "`","callController");
147
				}
148
				break;
149
			default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
150
				// Appel de la méthode en lui passant en paramètre le reste du tableau
151
				\call_user_func_array ( array ($controller,$u [1] ), self::$actionParams );
152
				break;
153
		}
154
	}
155
156
	public static function getConfig() {
157
		return self::$config;
158
	}
159
160
	public static function setConfig($config) {
161
		self::$config = $config;
162
	}
163
164
	private static function needsKeyInConfigArray(&$result, $array, $needs) {
165
		foreach ( $needs as $need ) {
166
			if (! isset ( $array [$need] ) || UString::isNull ( $array [$need] )) {
167
				$result [] = $need;
168
			}
169
		}
170
	}
171
172
	public static function checkDbConfig() {
173
		$config = self::$config;
174
		$result = [ ];
175
		$needs = [ "type","dbName","serverName" ];
176
		if (! isset ( $config ["database"] )) {
177
			$result [] = "database";
178
		} else {
179
			self::needsKeyInConfigArray ( $result, $config ["database"], $needs );
180
		}
181
		return $result;
182
	}
183
184
	public static function checkModelsConfig() {
185
		$config = self::$config;
186
		$result = [ ];
187
		if (! isset ( $config ["mvcNS"] )) {
188
			$result [] = "mvcNS";
189
		} else {
190
			self::needsKeyInConfigArray ( $result, $config ["mvcNS"], [ "models" ] );
191
		}
192
		return $result;
193
	}
194
195
	public static function getModelsDir() {
196
		return self::$config ["mvcNS"] ["models"];
197
	}
198
199
	public static function getModelsCompletePath() {
200
		return ROOT . DS . self::getModelsDir ();
201
	}
202
203
	public static function errorHandler($message = "", $code = 0, $severity = 1, $filename = null, int $lineno = 0, $previous = NULL) {
204
		if (\error_reporting () == 0) {
205
			return;
206
		}
207
		if (\error_reporting () & $severity) {
208
			throw new \ErrorException ( $message, 0, $severity, $filename, $lineno, $previous );
209
		}
210
	}
211
212
	public static function getController() {
213
		return self::$controller;
214
	}
215
	
216
	public static function getControllerSimpleName() {
217
		return (new \ReflectionClass(self::$controller))->getShortName();
218
	}
219
	
220
	public static function getViewNameFileExtension(){
221
		return "html";
222
	}
223
224
	public static function getAction() {
225
		return self::$action;
226
	}
227
	
228
	public static function getActionParams() {
229
		return self::$actionParams;
230
	}
231
232
	public static function getFrameworkDir() {
233
		return \dirname ( __FILE__ );
234
	}
235
236
	public static function getApplicationDir() {
237
		return \dirname ( ROOT );
238
	}
239
	
240
	public static function getApplicationName() {
241
		return basename(\dirname ( ROOT ));
242
	}
243
	
244
	public static function reloadConfig(){
245
		$appDir=\dirname ( ROOT );
246
		$filename=$appDir."/app/config/config.php";
247
		self::$config=include($filename);
248
		self::startTemplateEngine(self::$config);
249
		return self::$config;
250
	}
251
	
252
	public static function saveConfig($content){
253
		$appDir=\dirname ( ROOT );
254
		$filename=$appDir."/app/config/config.php";
255
		$oldFilename=$appDir."/app/config/config.old.php";
256
		if (!file_exists($filename) || copy($filename, $oldFilename)) {
257
			return UFileSystem::save($filename,$content);
258
		}
259
		return false;
260
	}
261
}
262