Test Failed
Push — master ( 979b33...a449fa )
by Jean-Christophe
25:45
created

RouterCacheTrait   B

Complexity

Total Complexity 52

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Test Coverage

Coverage 39.09%

Importance

Changes 4
Bugs 0 Features 1
Metric Value
wmc 52
eloc 95
c 4
b 0
f 1
dl 0
loc 204
ccs 43
cts 110
cp 0.3909
rs 7.44

20 Methods

Rating   Name   Duplication   Size   Complexity  
A addAdminRoutes() 0 2 1
A storeRouteResponse() 0 4 1
A controllerCacheUpdated() 0 13 4
A storeDynamicRoutes() 0 4 2
A getControllerCacheIndex() 0 6 3
A isExpired() 0 2 1
A addRoutes_() 0 8 2
A setExpired() 0 4 2
A addRoute() 0 4 2
A getRoutes() 0 2 1
A getRouteKey() 0 2 1
B getControllerRoutes() 0 18 7
A getControllerCache() 0 6 3
A warmUpControllers() 0 8 5
A expired() 0 2 1
A getRouteCache() 0 12 4
A setRouteCache() 0 6 1
A addRoutes() 0 2 1
A addRestRoutes() 0 2 1
B getControllerCacheByDomain() 0 26 9

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\Controller;
6
use Ubiquity\controllers\Router;
7
use Ubiquity\controllers\Startup;
8
use Ubiquity\controllers\StartupAsync;
9
use Ubiquity\domains\DDDManager;
10
use Ubiquity\utils\base\UIntrospection;
11
use Ubiquity\utils\base\UString;
12
use Ubiquity\utils\http\UResponse;
13
14
/**
15
 *
16
 * Ubiquity\cache\traits$RouterCacheTrait
17
 * This class is part of Ubiquity
18
 *
19
 * @author jcheron <[email protected]>
20
 * @version 1.0.14
21
 * @property \Ubiquity\cache\system\AbstractDataCache $cache
22
 *
23
 */
24
trait RouterCacheTrait {
25
26
	abstract public static function getControllers(string $subClass = "\\Ubiquity\\controllers\\Controller", bool $backslash = false, bool $includeSubclass = false, bool $includeAbstract = false): array;
27
28 11
	public static function controllerCacheUpdated(array &$config): array {
29 11
		$result = [];
30 11
		$domain = DDDManager::getActiveDomain();
31 11
		$newRoutes = self::parseControllerFiles($config, true, $domain != '');
32 11
		$ctrls = self::getControllerCacheByDomain(false, $domain);
33 11
		if ($newRoutes ['default'] != $ctrls && !(false)) {
34 3
			$result ['default'] = true;
35
		}
36 11
		$ctrls = self::getControllerCacheByDomain(true, $domain);
37 11
		if ($newRoutes ['rest'] != $ctrls) {
38
			$result ['rest'] = true;
39
		}
40 11
		return $result;
41
	}
42
43
	public static function storeDynamicRoutes(bool $isRest = false): void {
44
		$routes = Router::getRoutes();
45
		$part = ($isRest) ? 'rest' : 'default';
46
		self::$cache->store('controllers/routes.' . $part, $routes, 'controllers');
47
	}
48
49
	private static function storeRouteResponse(string $key, ?string $response): ?string {
50
		$cache = ['content-type' => UResponse::$headers ['Content-Type'] ?? 'text/html', 'content' => $response];
51
		self::$cache->store('controllers/' . $key, $cache, 'controllers');
52
		return $response;
53
	}
54
55 1
	private static function getRouteKey(string $routePath): string {
56 1
		return 'path' . \md5(Router::slashPath($routePath));
57
	}
58
59 1
	/**
60
	 *
61
	 * @param boolean $isRest
62
	 * @return array
63
	 */
64
	public static function getControllerCache(bool $isRest = false): array {
65
		$key = ($isRest) ? 'rest' : 'default';
66
		if (self::$cache->exists('controllers/routes.' . $key)) {
67 92
			return self::$cache->fetch('controllers/routes.' . $key);
68 92
		}
69 92
		return [];
70 92
	}
71
72
	/**
73
	 *
74
	 * @param boolean $isRest
75
	 * @param string $domain
76
	 * @return array
77
	 */
78
	public static function getControllerCacheByDomain(bool $isRest = false, string $domain = ''): array {
79
		$key = ($isRest) ? 'rest' : 'default';
80
		if (self::$cache->exists('controllers/routes.' . $key)) {
81 11
			if ($domain == '') {
82 11
				return self::$cache->fetch('controllers/routes.' . $key);
83 11
			} else {
84 11
				$ns = Startup::getNS();
85 11
				$routes = self::$cache->fetch('controllers/routes.' . $key);
86
				$result = [];
87
				foreach ($routes as $k => $route) {
88
					if (isset($route['controller'])) {
89
						if (UString::startswith($route['controller'], $ns)) {
90
							$result[$k] = $route;
91
						}
92
					} else {
93
						foreach ($route as $method => $routePart) {
94
							if (UString::startswith($routePart['controller'], $ns)) {
95
								$result[$k][$method] = $routePart;
96
							}
97
						}
98
					}
99
				}
100
				return $result;
101
			}
102
		}
103
		return [];
104
	}
105
106
	/**
107
	 *
108
	 * @param boolean $isRest
109
	 * @return array
110
	 */
111
	public static function getControllerCacheIndex(bool $isRest = false): array {
112
		$key = ($isRest) ? 'rest-index' : 'default-index';
113
		if (self::$cache->exists('controllers/routes.' . $key)) {
114
			return self::$cache->fetch('controllers/routes.' . $key);
115
		}
116
		return [];
117
	}
118
119
	public static function getRouteCache(string $routePath, array $routeArray, int $duration) {
120
		$key = self::getRouteKey($routePath);
121
122
		if (self::$cache->exists('controllers/' . $key) && !self::expired($key, $duration)) {
123
			$response = self::$cache->fetch('controllers/' . $key);
124
			if ($ct = $response ['content-type'] ?? false) {
125
				UResponse::setContentType($ct);
126
			}
127
			return $response ['content'] ?? '';
128
		} else {
129
			$response = Startup::runAsString($routeArray);
130
			return self::storeRouteResponse($key, $response);
131
		}
132
	}
133
134
	protected static function expired(string $key, int $duration): bool {
135
		return self::$cache->expired("controllers/" . $key, $duration) === true;
136
	}
137
138
	public static function isExpired(string $routePath, int $duration): bool {
139
		return self::expired(self::getRouteKey($routePath), $duration);
140
	}
141
142
	public static function setExpired(string $routePath): void {
143
		$key = self::getRouteKey($routePath);
144
		if (self::$cache->exists('controllers/' . $key)) {
145 1
			self::$cache->remove('controllers/' . $key);
146 1
		}
147 1
	}
148
149
	/**
150
	 * Stores a route response in cache.
151
	 * @param string $routePath The route path
152
	 * @return string|null
153
	 */
154
	public static function setRouteCache(string $routePath): ?string {
155
		$key = self::getRouteKey($routePath);
156
		\ob_start();
157
		Startup::forward($routePath);
158
		$response = \ob_get_clean();
159
		return self::storeRouteResponse($key, $response);
160
	}
161
162 2
	public static function addAdminRoutes(): void {
163 2
		self::addControllerCache('Ubiquity\controllers\Admin');
164
	}
165
166 1
	public static function getRoutes(): array {
167 1
		return self::getControllerCache();
168 1
	}
169 1
170 1
	public static function getControllerRoutes(string $controllerClass, bool $isRest = false): array {
171 1
		$result = [];
172 1
		$ctrlCache = self::getControllerCache($isRest);
173
		foreach ($ctrlCache as $path => $routeAttributes) {
174
			if (isset ($routeAttributes ['controller'])) {
175 1
				if ($routeAttributes ['controller'] === $controllerClass) {
176 1
					$result [$path] = $routeAttributes;
177 1
				}
178 1
			} else {
179
				$firstValue = current($routeAttributes);
180
				if (isset ($firstValue) && isset ($firstValue ['controller'])) {
181
					if ($firstValue ['controller'] === $controllerClass) {
182
						$result [$path] = $routeAttributes;
183 1
					}
184
				}
185
			}
186 1
		}
187 1
		return $result;
188 1
	}
189 1
190
	public static function addRoute(string $path, string $controller, string $action = 'index', ?array $methods = null, string $name = '', bool $isRest = false, int $priority = 0, $callback = null) {
191
		$controllerCache = self::getControllerCache($isRest);
192
		Router::addRouteToRoutes($controllerCache, $path, $controller, $action, $methods, $name, false, null, [], $priority, $callback);
193
		self::$cache->store('controllers/routes.' . ($isRest ? 'rest' : 'default'), $controllerCache, 'controllers');
194
	}
195
196
	public static function addRoutes($pathArray, $controller, $action = 'index', $methods = null, $name = '') {
197
		self::addRoutes_($pathArray, $controller, $action, $methods, $name, false);
198
	}
199
200
	public static function addRestRoutes($pathArray, $controller, $action = 'index', $methods = null, $name = '') {
201
		self::addRoutes_($pathArray, $controller, $action, $methods, $name, true);
202
	}
203
204
	private static function addRoutes_($pathArray, $controller, $action = 'index', $methods = null, $name = '', $isRest = false) {
205
		$controllerCache = self::getControllerCache($isRest);
206
		$postfix = 'default';
207
		if ($isRest) {
208
			$postfix = 'rest';
209
		}
210
		Router::addRoutesToRoutes($controllerCache, $pathArray, $controller, $action, $methods, $name);
211
		self::$cache->store('controllers/routes.' . $postfix, $controllerCache, 'controllers');
212
	}
213
214
	/**
215
	 * Preloads controllers.
216
	 * To use only with async servers (Swoole, Workerman)
217
	 *
218
	 * @param ?array $controllers
219
	 */
220
	public static function warmUpControllers(?array $controllers = null) {
221
		$controllers ??= self::getControllers();
222
		foreach ($controllers as $ctrl) {
223
			$controller = StartupAsync::getControllerInstance($ctrl);
224
			$binary = UIntrospection::implementsMethod($controller, 'isValid', Controller::class) ? 1 : 0;
225
			$binary += UIntrospection::implementsMethod($controller, 'initialize', Controller::class) ? 2 : 0;
226
			$binary += UIntrospection::implementsMethod($controller, 'finalize', Controller::class) ? 4 : 0;
227
			$controller->_binaryCalls = $binary;
228
		}
229
	}
230
}
231