Test Failed
Push — master ( 26590d...3034a5 )
by Jean-Christophe
14:48 queued 27s
created

RouterCacheTrait::addRoute()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2.1481

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 3
cp 0.6667
rs 10
cc 2
nc 1
nop 8
crap 2.1481

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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