Completed
Push — master ( f4afa6...28cdc3 )
by Jean-Christophe
01:27
created

CacheManager::addAdminRoutes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace micro\cache;
4
5
use mindplay\annotations\Annotations;
6
use mindplay\annotations\AnnotationCache;
7
use mindplay\annotations\AnnotationManager;
8
use micro\orm\parser\ModelParser;
9
use micro\utils\JArray;
10
use micro\controllers\Router;
11
use micro\controllers\Startup;
12
use micro\utils\FsUtils;
13
use micro\cache\parser\ControllerParser;
14
use micro\cache\parser\RestControllerParser;
15
16
class CacheManager {
17
	public static $cache;
18
	private static $routes=[ ];
0 ignored issues
show
Unused Code introduced by
The property $routes is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
19
	private static $cacheDirectory;
20
	private static $expiredRoutes=[ ];
21
22
	public static function start(&$config) {
23
		self::$cacheDirectory=self::initialGetCacheDirectory($config);
24
		$cacheDirectory=ROOT . DS . self::$cacheDirectory;
25
		Annotations::$config['cache']=new AnnotationCache($cacheDirectory . '/annotations');
26
		self::register(Annotations::getManager());
27
		self::$cache=new ArrayCache($cacheDirectory, ".cache");
28
	}
29
30
	public static function startProd(&$config) {
31
		self::$cacheDirectory=self::initialGetCacheDirectory($config);
32
		$cacheDirectory=ROOT . DS . self::$cacheDirectory;
33
		self::$cache=new ArrayCache($cacheDirectory, ".cache");
34
	}
35
36
	public static function getControllerCache($isRest=false) {
37
		$key=($isRest)?"rest":"default";
38
		if (self::$cache->exists("controllers/routes.".$key))
39
			return self::$cache->fetch("controllers/routes.".$key);
40
		return [ ];
41
	}
42
43
	public static function getRestCache() {
44
		if (self::$cache->exists("controllers/rest"))
45
			return self::$cache->fetch("controllers/rest");
46
		return [ ];
47
	}
48
49
	public static function getRouteCache($routePath, $duration) {
50
		$key=self::getRouteKey($routePath);
51
52
		if (self::$cache->exists("controllers/" . $key) && !self::expired($key, $duration)) {
53
			$response=self::$cache->file_get_contents("controllers/" . $key);
54
			return $response;
55
		} else {
56
			$response=Startup::runAsString($routePath);
57
			return self::storeRouteResponse($key, $response);
58
		}
59
	}
60
61
	public static function expired($key, $duration) {
62
		return self::$cache->expired("controllers/" . $key, $duration) === true || \array_key_exists($key, self::$expiredRoutes);
63
	}
64
65
	public static function isExpired($path,$duration){
66
		$route=Router::getRoute($path,false);
67
		if($route!==false && \is_array($route)){
68
			return self::expired(self::getRouteKey($route), $duration);
69
		}
70
		return true;
71
	}
72
73
	public static function setExpired($routePath, $expired=true) {
74
		$key=self::getRouteKey($routePath);
75
		self::setKeyExpired($key, $expired);
76
	}
77
78
	private static function setKeyExpired($key, $expired=true) {
79
		if ($expired) {
80
			self::$expiredRoutes[$key]=true;
81
		} else {
82
			unset(self::$expiredRoutes[$key]);
83
		}
84
	}
85
86
	public static function setRouteCache($routePath) {
87
		$key=self::getRouteKey($routePath);
88
		$response=Startup::runAsString($routePath);
89
		return self::storeRouteResponse($key, $response);
90
	}
91
92
	private static function storeRouteResponse($key, $response) {
93
		self::setKeyExpired($key, false);
94
		self::$cache->store("controllers/" . $key, $response, false);
95
		return $response;
96
	}
97
98
	private static function getRouteKey($routePath) {
99
		return "path" . \md5(\implode("", $routePath));
100
	}
101
102
	private static function initialGetCacheDirectory(&$config) {
103
		$cacheDirectory=@$config["cacheDirectory"];
104
		if (!isset($cacheDirectory)) {
105
			$config["cacheDirectory"]="cache/";
106
			$cacheDirectory=$config["cacheDirectory"];
107
		}
108
		return $cacheDirectory;
109
	}
110
111
	public static function getCacheDirectory() {
112
		return self::$cacheDirectory;
113
	}
114
115
	public static function createOrmModelCache($classname) {
116
		$key=self::getModelCacheKey($classname);
117
		if(isset(self::$cache)){
118
			if (!self::$cache->exists($key)) {
119
				$p=new ModelParser();
120
				$p->parse($classname);
121
				self::$cache->store($key, $p->__toString());
122
			}
123
			return self::$cache->fetch($key);
124
		}
125
	}
126
127
	public static function getModelCacheKey($classname){
128
		return \str_replace("\\", DIRECTORY_SEPARATOR, $classname);
129
	}
130
131
	public static function modelCacheExists($classname){
132
		$key=self::getModelCacheKey($classname);
133
		if(isset(self::$cache))
134
			return self::$cache->exists($key);
135
		return false;
136
	}
137
138
	private static function addControllerCache($classname) {
139
		$parser=new ControllerParser();
140
		try {
141
			$parser->parse($classname);
142
			return $parser->asArray();
143
		} catch ( \Exception $e ) {
144
			// Nothing to do
145
		}
146
		return [];
147
	}
148
149
	public static function checkCache(&$config,$silent=false) {
150
		$dirs=self::getCacheDirectories($config,$silent);
151
		foreach ($dirs as $dir){
152
			self::safeMkdir($dir);
153
		}
154
		return $dirs;
155
	}
156
157
	public static function getCacheDirectories(&$config,$silent=false){
158
		$cacheDirectory=self::initialGetCacheDirectory($config);
159
		if(!$silent){
160
			echo "cache directory is " . FsUtils::cleanPathname(ROOT . DS . $cacheDirectory) . "\n";
161
		}
162
		$modelsDir=str_replace("\\", DS, $config["mvcNS"]["models"]);
163
		$controllersDir=str_replace("\\", DS, $config["mvcNS"]["controllers"]);
164
		$annotationCacheDir=ROOT . DS . $cacheDirectory . DS . "annotations";
165
		$modelsCacheDir=ROOT . DS . $cacheDirectory . DS . $modelsDir;
166
		$queriesCacheDir=ROOT . DS . $cacheDirectory . DS . "queries";
167
		$controllersCacheDir=ROOT . DS . $cacheDirectory . DS . $controllersDir;
168
		$viewsCacheDir=ROOT . DS . $cacheDirectory . DS . "views";
169
		return [ "annotations" => $annotationCacheDir,"models" => $modelsCacheDir,"controllers" => $controllersCacheDir,"queries" => $queriesCacheDir ,"views"=>$viewsCacheDir];
170
	}
171
172
	private static function safeMkdir($dir) {
173
		if (!is_dir($dir))
174
			return mkdir($dir, 0777, true);
175
	}
176
177
	public static function clearCache(&$config, $type="all") {
178
		$cacheDirectories=self::checkCache($config);
179
		$cacheDirs=["annotations","controllers","models","queries","views"];
180
		foreach ($cacheDirs as $typeRef){
181
			self::_clearCache($cacheDirectories, $type, $typeRef);
182
		}
183
	}
184
185
	private static function _clearCache($cacheDirectories,$type,$typeRef){
186
		if ($type === "all" || $type === $typeRef)
187
			FsUtils::deleteAllFilesFromFolder($cacheDirectories[$typeRef]);
188
	}
189
190
	public static function initCache(&$config, $type="all",$silent=false) {
191
		self::checkCache($config,$silent);
192
		self::start($config);
193
		if ($type === "all" || $type === "models")
194
			self::initModelsCache($config,false,$silent);
195
		if ($type === "all" || $type === "controllers")
196
			self::initRouterCache($config,$silent);
197
		if ($type === "all" || $type === "rest")
198
			self::initRestCache($config,$silent);
199
	}
200
201
	public static function initModelsCache(&$config,$forChecking=false,$silent=false) {
202
		$files=self::getModelsFiles($config,$silent);
203
		foreach ( $files as $file ) {
204
			if (is_file($file)) {
205
				$model=ClassUtils::getClassFullNameFromFile($file);
206
				if(!$forChecking){
207
					new $model();
208
				}
209
			}
210
		}
211
		if(!$silent){
212
			echo "Models cache reset\n";
213
		}
214
	}
215
216
	public static function getModelsFiles(&$config,$silent=false){
217
		return self::_getFiles($config, "models",$silent);
218
	}
219
220
	public static function getModels(&$config,$silent=false){
221
		$result=[];
222
		$files=self::getModelsFiles($config,$silent);
223
		foreach ($files as $file){
224
			$result[]=ClassUtils::getClassFullNameFromFile($file);
225
		}
226
		return $result;
227
	}
228
229
	public static function getControllersFiles(&$config,$silent=false){
230
		return self::_getFiles($config, "controllers",$silent);
231
	}
232
233
	private static function _getFiles(&$config,$type,$silent=false){
234
		$typeNS=$config["mvcNS"][$type];
235
		$typeDir=ROOT . DS . str_replace("\\", DS, $typeNS);
236
		if(!$silent)
237
			echo \ucfirst($type)." directory is " . ROOT . $typeNS . "\n";
238
		return FsUtils::glob_recursive($typeDir . DS . '*');
239
	}
240
241
	private static function initRouterCache(&$config,$silent=false) {
242
		$routes=["rest"=>[],"default"=>[]];
243
		$files=self::getControllersFiles($config);
244
		foreach ( $files as $file ) {
245
			if (is_file($file)) {
246
				$controller=ClassUtils::getClassFullNameFromFile($file);
247
				$parser=new ControllerParser();
248
				try {
249
					$parser->parse($controller);
250
					$ret= $parser->asArray();
251
					$key=($parser->isRest())?"rest":"default";
252
					$routes[$key]=\array_merge($routes[$key], $ret);
253
				} catch ( \Exception $e ) {
254
					// Nothing to do
255
				}
256
257
			}
258
		}
259
		self::$cache->store("controllers/routes.default", "return " . JArray::asPhpArray($routes["default"], "array") . ";");
260
		self::$cache->store("controllers/routes.rest", "return " . JArray::asPhpArray($routes["rest"], "array") . ";");
261
		if(!$silent){
262
			echo "Router cache reset\n";
263
		}
264
	}
265
266
	private static function initRestCache(&$config,$silent=false) {
267
		$restCache=[];
268
		$files=self::getControllersFiles($config);
269
		foreach ( $files as $file ) {
270
			if (is_file($file)) {
271
				$controller=ClassUtils::getClassFullNameFromFile($file);
272
				$parser=new RestControllerParser();
273
				$parser->parse($controller,$config);
274
				if($parser->isRest())
275
					$restCache=\array_merge($restCache,$parser->asArray());
276
			}
277
		}
278
		self::$cache->store("controllers/rest", "return " . JArray::asPhpArray($restCache, "array") . ";");
279
		if(!$silent){
280
			echo "Rest cache reset\n";
281
		}
282
	}
283
284
	private static function register(AnnotationManager $annotationManager) {
285
		$annotationManager->registry=array_merge($annotationManager->registry, [
286
				'id' => 'micro\annotations\IdAnnotation',
287
				'manyToOne' => 'micro\annotations\ManyToOneAnnotation',
288
				'oneToMany' => 'micro\annotations\OneToManyAnnotation',
289
				'manyToMany' => 'micro\annotations\ManyToManyAnnotation',
290
				'joinColumn' => 'micro\annotations\JoinColumnAnnotation',
291
				'table' => 'micro\annotations\TableAnnotation',
292
				'transient' => 'micro\annotations\TransientAnnotation',
293
				'column' => 'micro\annotations\ColumnAnnotation',
294
				'joinTable' => 'micro\annotations\JoinTableAnnotation',
295
				'route' => 'micro\annotations\router\RouteAnnotation',
296
				'var' => 'mindplay\annotations\standard\VarAnnotation',
297
				'yuml' => 'micro\annotations\YumlAnnotation',
298
				'rest' => 'micro\annotations\rest\RestAnnotation',
299
				'authorization' => 'micro\annotations\rest\AuthorizationAnnotation'
300
		]);
301
	}
302
303
	public static function addAdminRoutes() {
304
		self::addControllerCache("micro\controllers\Admin");
305
	}
306
307
	public static function getRoutes() {
308
		$result=self::getControllerCache();
309
		return $result;
310
	}
311
312
	public static function getRestRoutes() {
313
		$result=[];
314
		$restCache=self::getRestCache();
315
		foreach ($restCache as $controllerClass=>$restAttributes){
316
			if(isset($restCache[$controllerClass])){
317
				$result[$controllerClass]=["restAttributes"=>$restAttributes,"routes"=>self::getControllerRoutes($controllerClass,true)];
318
			}
319
		}
320
		return $result;
321
	}
322
323
	public static function getControllerRoutes($controllerClass,$isRest=false){
324
		$result=[];
325
		$ctrlCache=self::getControllerCache($isRest);
326
		foreach ($ctrlCache as $path=>$routeAttributes){
327
			if(isset($routeAttributes["controller"])){
328
				if($routeAttributes["controller"]===$controllerClass){
329
					$result[$path]=$routeAttributes;
330
				}
331
			}else{
332
				$firstValue=reset($routeAttributes);
333
				if(isset($firstValue)&&isset($firstValue["controller"])){
334
					if($firstValue["controller"]===$controllerClass){
335
						$result[$path]=$routeAttributes;
336
					}
337
				}
338
			}
339
		}
340
		return $result;
341
	}
342
343 View Code Duplication
	public static function getRestResource($controllerClass){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
344
		$cache=self::getRestCache();
345
		if(isset($cache[$controllerClass])){
346
			return $cache[$controllerClass]["resource"];
347
		}
348
		return null;
349
	}
350
351 View Code Duplication
	public static function getRestCacheController($controllerClass){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
352
		$cache=self::getRestCache();
353
		if(isset($cache[$controllerClass])){
354
			return $cache[$controllerClass];
355
		}
356
		return null;
357
	}
358
359
360
	public static function addRoute($path, $controller, $action="index", $methods=null, $name="") {
361
		$controllerCache=self::getControllerCache();
362
		Router::addRouteToRoutes($controllerCache, $path, $controller, $action, $methods, $name);
363
		self::$cache->store("controllers/routes", "return " . JArray::asPhpArray($controllerCache, "array") . ";");
364
	}
365
}
366