Passed
Push — master ( 9e15fe...1d956f )
by Jean-Christophe
09:32
created

RouterCacheTrait   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 212
Duplicated Lines 0 %

Test Coverage

Coverage 59.11%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 54
eloc 111
c 1
b 0
f 0
dl 0
loc 212
ccs 81
cts 137
cp 0.5911
rs 6.4799

23 Methods

Rating   Name   Duplication   Size   Complexity  
A addControllerCache() 0 9 2
A initRouterCache() 0 7 2
A controllerCacheUpdated() 0 12 3
A storeDynamicRoutes() 0 4 2
A sortByPriority() 0 5 1
A storeRouteResponse() 0 3 1
A addAdminRoutes() 0 2 1
A isExpired() 0 2 1
A addRoutes_() 0 8 2
A setExpired() 0 4 2
A getControllersFiles() 0 2 1
A addRoute() 0 4 2
B getControllers() 0 24 9
A getRoutes() 0 3 1
A getRouteKey() 0 5 2
B getControllerRoutes() 0 18 7
A getControllerCache() 0 5 3
A expired() 0 2 1
A getRouteCache() 0 9 3
A setRouteCache() 0 4 1
A addRoutes() 0 2 1
A addRestRoutes() 0 2 1
A parseControllerFiles() 0 20 5

How to fix   Complexity   

Complex Class

Complex classes like RouterCacheTrait 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.

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 RouterCacheTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ubiquity\cache\traits;
4
5
use Ubiquity\controllers\Startup;
6
use Ubiquity\controllers\Router;
7
use Ubiquity\cache\parser\ControllerParser;
8
use Ubiquity\cache\ClassUtils;
9
use Ubiquity\utils\base\UArray;
10
use Ubiquity\cache\CacheManager;
11
use Ubiquity\controllers\di\DiManager;
12
13
/**
14
 *
15
 * Ubiquity\cache\traits$RouterCacheTrait
16
 * This class is part of Ubiquity
17
 *
18
 * @author jcheron <[email protected]>
19
 * @version 1.0.6
20
 * @property \Ubiquity\cache\system\AbstractDataCache $cache
21
 *
22
 */
23
trait RouterCacheTrait {
24
25
	abstract protected static function _getFiles(&$config, $type, $silent = false);
26
27
	private static function addControllerCache($classname) {
28
		$parser = new ControllerParser ();
29
		try {
30
			$parser->parse ( $classname );
31
			return $parser->asArray ();
32
		} catch ( \Exception $e ) {
33
			// Nothing to do
34
		}
35
		return [ ];
36
	}
37
38 16
	private static function parseControllerFiles(&$config, $silent = false) {
39 16
		$routes = [ "rest" => [ ],"default" => [ ] ];
40 16
		$files = self::getControllersFiles ( $config, $silent );
41 16
		foreach ( $files as $file ) {
42 16
			if (is_file ( $file )) {
43 16
				$controller = ClassUtils::getClassFullNameFromFile ( $file );
44 16
				$parser = new ControllerParser ();
45
				try {
46 16
					$parser->parse ( $controller );
47 16
					$ret = $parser->asArray ();
48 16
					$key = ($parser->isRest ()) ? "rest" : "default";
49 16
					$routes [$key] = \array_merge ( $routes [$key], $ret );
50
				} catch ( \Exception $e ) {
51
					// Nothing to do
52
				}
53
			}
54
		}
55 16
		self::sortByPriority ( $routes ['default'] );
56 16
		self::sortByPriority ( $routes ['rest'] );
57 16
		return $routes;
58
	}
59
60 16
	protected static function sortByPriority(&$array) {
61
		uasort ( $array, function ($item1, $item2) {
62 16
			return UArray::getRecursive ( $item2, "priority", 0 ) <=> UArray::getRecursive ( $item1, "priority", 0 );
63 16
		} );
64 16
		UArray::removeRecursive ( $array, "priority" );
65 16
	}
66
67 7
	private static function initRouterCache(&$config, $silent = false) {
68 7
		$routes = self::parseControllerFiles ( $config, $silent );
69 7
		self::$cache->store ( "controllers/routes.default", "return " . UArray::asPhpArray ( $routes ["default"], "array" ) . ";", 'controllers' );
70 7
		self::$cache->store ( "controllers/routes.rest", "return " . UArray::asPhpArray ( $routes ["rest"], "array" ) . ";", 'controllers' );
71 7
		DiManager::init ( $config );
72 7
		if (! $silent) {
73 7
			echo "Router cache reset\n";
74
		}
75 7
	}
76
77 11
	public static function controllerCacheUpdated(&$config) {
78 11
		$result = false;
79 11
		$newRoutes = self::parseControllerFiles ( $config, true );
80 11
		$ctrls = self::getControllerCache ();
81 11
		if ($newRoutes ['default'] != $ctrls) {
82 6
			$result ['default'] = true;
83
		}
84 11
		$ctrls = self::getControllerCache ( true );
85 11
		if ($newRoutes ['rest'] != $ctrls) {
86 3
			$result ['rest'] = true;
87
		}
88 11
		return $result;
89
	}
90
91
	public static function storeDynamicRoutes($isRest = false) {
92
		$routes = Router::getRoutes ();
93
		$part = ($isRest) ? 'rest' : 'default';
94
		self::$cache->store ( "controllers/routes." . $part, "return " . UArray::asPhpArray ( $routes, "array" ) . ";", 'controllers' );
95
	}
96
97
	private static function storeRouteResponse($key, $response) {
98
		self::$cache->store ( "controllers/" . $key, $response, 'controllers', false );
99
		return $response;
100
	}
101
102
	private static function getRouteKey($routePath) {
103
		if (is_array ( $routePath )) {
104
			return "path" . \md5 ( \implode ( "", $routePath ) );
105
		}
106
		return "path" . \md5 ( Router::slashPath ( $routePath ) );
107
	}
108
109
	/**
110
	 *
111
	 * @param boolean $isRest
112
	 * @return array
113
	 */
114 55
	public static function getControllerCache($isRest = false) {
115 55
		$key = ($isRest) ? "rest" : "default";
116 55
		if (self::$cache->exists ( "controllers/routes." . $key ))
117 52
			return self::$cache->fetch ( "controllers/routes." . $key );
118 4
		return [ ];
119
	}
120
121
	public static function getRouteCache($routePath, $routeArray, $duration) {
122
		$key = self::getRouteKey ( $routePath );
123
124
		if (self::$cache->exists ( "controllers/" . $key ) && ! self::expired ( $key, $duration )) {
125
			$response = self::$cache->file_get_contents ( "controllers/" . $key );
126
			return $response;
127
		} else {
128
			$response = Startup::runAsString ( $routeArray );
129
			return self::storeRouteResponse ( $key, $response );
130
		}
131
	}
132
133
	protected static function expired($key, $duration) {
134
		return self::$cache->expired ( "controllers/" . $key, $duration ) === true;
135
	}
136
137
	public static function isExpired($routePath, $duration) {
138
		return self::expired ( self::getRouteKey ( $routePath ), $duration );
139
	}
140
141
	public static function setExpired($routePath) {
142
		$key = self::getRouteKey ( $routePath );
143
		if (self::$cache->exists ( "controllers/" . $key )) {
144
			self::$cache->remove ( "controllers/" . $key );
145
		}
146
	}
147
148
	public static function setRouteCache($routePath) {
149
		$key = self::getRouteKey ( $routePath );
150
		$response = Startup::runAsString ( $routePath );
151
		return self::storeRouteResponse ( $key, $response );
152
	}
153
154
	public static function addAdminRoutes() {
155
		self::addControllerCache ( "Ubiquity\controllers\Admin" );
156
	}
157
158 2
	public static function getRoutes() {
159 2
		$result = self::getControllerCache ();
160 2
		return $result;
161
	}
162
163 1
	public static function getControllerRoutes($controllerClass, $isRest = false) {
164 1
		$result = [ ];
165 1
		$ctrlCache = self::getControllerCache ( $isRest );
166 1
		foreach ( $ctrlCache as $path => $routeAttributes ) {
167 1
			if (isset ( $routeAttributes ["controller"] )) {
168 1
				if ($routeAttributes ["controller"] === $controllerClass) {
169 1
					$result [$path] = $routeAttributes;
170
				}
171
			} else {
172 1
				$firstValue = current ( $routeAttributes );
173 1
				if (isset ( $firstValue ) && isset ( $firstValue ["controller"] )) {
174 1
					if ($firstValue ["controller"] === $controllerClass) {
175 1
						$result [$path] = $routeAttributes;
176
					}
177
				}
178
			}
179
		}
180 1
		return $result;
181
	}
182
183 1
	public static function addRoute($path, $controller, $action = "index", $methods = null, $name = "", $isRest = false, $priority = 0, $callback = null) {
184 1
		$controllerCache = self::getControllerCache ( $isRest );
185 1
		Router::addRouteToRoutes ( $controllerCache, $path, $controller, $action, $methods, $name, false, null, [ ], $priority, $callback );
186 1
		self::$cache->store ( 'controllers/routes.' . ($isRest ? 'rest' : 'default'), "return " . UArray::asPhpArray ( $controllerCache, "array" ) . ";", 'controllers' );
187 1
	}
188
189
	public static function addRoutes($pathArray, $controller, $action = "index", $methods = null, $name = "") {
190
		self::addRoutes_ ( $pathArray, $controller, $action, $methods, $name, false );
191
	}
192
193
	public static function addRestRoutes($pathArray, $controller, $action = "index", $methods = null, $name = "") {
194
		self::addRoutes_ ( $pathArray, $controller, $action, $methods, $name, true );
195
	}
196
197
	private static function addRoutes_($pathArray, $controller, $action = "index", $methods = null, $name = "", $isRest = false) {
198
		$controllerCache = self::getControllerCache ( $isRest );
199
		$postfix = "default";
200
		if ($isRest) {
201
			$postfix = "rest";
202
		}
203
		Router::addRoutesToRoutes ( $controllerCache, $pathArray, $controller, $action, $methods, $name );
204
		self::$cache->store ( "controllers/routes." . $postfix, "return " . UArray::asPhpArray ( $controllerCache, "array" ) . ";", 'controllers' );
205
	}
206
207 16
	public static function getControllersFiles(&$config, $silent = false) {
208 16
		return self::_getFiles ( $config, "controllers", $silent );
209
	}
210
211 9
	public static function getControllers($subClass = "\\Ubiquity\\controllers\\Controller", $backslash = false, $includeSubclass = false, $includeAbstract = false) {
212 9
		$result = [ ];
213 9
		if ($includeSubclass) {
214 1
			$result [] = $subClass;
215
		}
216 9
		$config = Startup::getConfig ();
217 9
		$files = self::getControllersFiles ( $config, true );
218
		try {
219 9
			$restCtrls = CacheManager::getRestCache ();
220 2
		} catch ( \Exception $e ) {
221 2
			$restCtrls = [ ];
222
		}
223 9
		foreach ( $files as $file ) {
224 9
			if (is_file ( $file )) {
225 9
				$controllerClass = ClassUtils::getClassFullNameFromFile ( $file, $backslash );
226 9
				if (isset ( $restCtrls [$controllerClass] ) === false) {
227 9
					$r = new \ReflectionClass ( $controllerClass );
228 9
					if ($r->isSubclassOf ( $subClass ) && ($includeAbstract || ! $r->isAbstract ())) {
229 9
						$result [] = $controllerClass;
230
					}
231
				}
232
			}
233
		}
234 9
		return $result;
235
	}
236
}
237