Completed
Push — master ( 9b2045...1557b4 )
by Jean-Christophe
01:25
created

CacheManager::setKeyExpired()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
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
13
class CacheManager {
14
	public static $cache;
15
	private static $routes=[ ];
16
	private static $cacheDirectory;
17
	private static $expiredRoutes=[ ];
18
19
	public static function start(&$config) {
20
		self::$cacheDirectory=self::initialGetCacheDirectory($config);
21
		$cacheDirectory=ROOT . DS . self::$cacheDirectory;
22
		Annotations::$config['cache']=new AnnotationCache($cacheDirectory . '/annotations');
23
		self::register(Annotations::getManager());
24
		self::$cache=new ArrayCache($cacheDirectory, ".cache");
25
	}
26
27
	public static function startProd(&$config) {
28
		self::$cacheDirectory=self::initialGetCacheDirectory($config);
29
		$cacheDirectory=ROOT . DS . self::$cacheDirectory;
30
		self::$cache=new ArrayCache($cacheDirectory, ".cache");
31
	}
32
33
	public static function getControllerCache() {
34
		if (self::$cache->exists("controllers/routes"))
35
			return self::$cache->fetch("controllers/routes");
36
		return [ ];
37
	}
38
39
	public static function getRouteCache($routePath, $duration) {
40
		$key=self::getRouteKey($routePath);
41
42
		if (self::$cache->exists("controllers/" . $key) && !self::expired($key, $duration)) {
43
			$response=self::$cache->file_get_contents("controllers/" . $key);
44
			return $response;
45
		} else {
46
			$response=Startup::runAsString($routePath);
47
			return self::storeRouteResponse($key, $response);
48
		}
49
	}
50
51
	public static function expired($key, $duration) {
52
		return self::$cache->expired("controllers/" . $key, $duration) === true || \array_key_exists($key, self::$expiredRoutes);
53
	}
54
55
	public static function setExpired($routePath, $expired=true) {
56
		$key=self::getRouteKey($routePath);
57
		self::setKeyExpired($key, $expired);
58
	}
59
60
	private static function setKeyExpired($key, $expired=true) {
61
		if ($expired) {
62
			self::$expiredRoutes[$key]=true;
63
		} else {
64
			unset(self::$expiredRoutes[$key]);
65
		}
66
	}
67
68
	public static function setRouteCache($routePath) {
69
		$key=self::getRouteKey($routePath);
70
		$response=Startup::runAsString($routePath);
71
		return self::storeRouteResponse($key, $response);
72
	}
73
74
	private static function storeRouteResponse($key, $response) {
75
		self::setKeyExpired($key, false);
76
		self::$cache->store("controllers/" . $key, $response, false);
77
		return $response;
78
	}
79
80
	private static function getRouteKey($routePath) {
81
		return "path" . \md5(\implode("", $routePath));
82
	}
83
84
	private static function initialGetCacheDirectory(&$config) {
85
		$cacheDirectory=@$config["cacheDirectory"];
86
		if (!isset($cacheDirectory)) {
87
			$config["cacheDirectory"]="cache/";
88
			$cacheDirectory=$config["cacheDirectory"];
89
		}
90
		return $cacheDirectory;
91
	}
92
93
	public static function getCacheDirectory() {
94
		return self::$cacheDirectory;
95
	}
96
97
	public static function createOrmModelCache($className) {
98
		$key=\str_replace("\\", DIRECTORY_SEPARATOR, $className);
99
		if (!self::$cache->exists($key)) {
100
			$p=new ModelParser();
101
			$p->parse($className);
102
			self::$cache->store($key, $p->__toString());
103
		}
104
		return self::$cache->fetch($key);
105
	}
106
107
	private static function addControllerCache($classname) {
108
		$parser=new ControllerParser();
109
		try {
110
			$parser->parse($classname);
111
			self::$routes=\array_merge($parser->asArray(), self::$routes);
112
		} catch ( \Exception $e ) {
113
			// Nothing to do
114
		}
115
	}
116
117
	public static function checkCache(&$config) {
118
		$cacheDirectory=self::initialGetCacheDirectory($config);
119
		$modelsDir=str_replace("\\", DS, $config["mvcNS"]["models"]);
120
		$controllersDir=str_replace("\\", DS, $config["mvcNS"]["controllers"]);
121
		echo "cache directory is " . ROOT . DS . $cacheDirectory . "\n";
122
		$annotationCacheDir=ROOT . DS . $cacheDirectory . DS . "annotations";
123
		$modelsCacheDir=ROOT . DS . $cacheDirectory . DS . $modelsDir;
124
		$queriesCacheDir=ROOT . DS . $cacheDirectory . DS . "queries";
125
		$controllersCacheDir=ROOT . DS . $cacheDirectory . DS . $controllersDir;
126
		self::safeMkdir($annotationCacheDir);
127
		self::safeMkdir($modelsCacheDir);
128
		self::safeMkdir($controllersCacheDir);
129
		self::safeMkdir($queriesCacheDir);
130
		return [ "annotations" => $annotationCacheDir,"models" => $modelsCacheDir,"controllers" => $controllersCacheDir,"queries" => $queriesCacheDir ];
131
	}
132
133
	private static function safeMkdir($dir) {
134
		if (!is_dir($dir))
135
			return mkdir($dir, 0777, true);
136
	}
137
138
	private static function deleteAllFilesFromFolder($folder) {
139
		$files=glob($folder . '/*');
140
		foreach ( $files as $file ) {
141
			if (is_file($file))
142
				unlink($file);
143
		}
144
	}
145
146
	public static function clearCache(&$config, $type="all") {
147
		$cacheDirectories=self::checkCache($config);
148
		if ($type === "all") {
149
			self::deleteAllFilesFromFolder($cacheDirectories["annotations"]);
150
		}
151
		if ($type === "all" || $type === "controllers")
152
			self::deleteAllFilesFromFolder($cacheDirectories["controllers"]);
153
		if ($type === "all" || $type === "models")
154
			self::deleteAllFilesFromFolder($cacheDirectories["models"]);
155
		if ($type === "all" || $type === "queries")
156
			self::deleteAllFilesFromFolder($cacheDirectories["queries"]);
157
	}
158
159
	public static function initCache(&$config, $type="all") {
160
		self::checkCache($config);
161
		self::start($config);
162
		if ($type === "all" || $type === "models")
163
			self::initModelsCache($config);
164
		if ($type === "all" || $type === "controllers")
165
			self::initControllersCache($config);
166
	}
167
168
	private static function initModelsCache(&$config) {
169
		$modelsNS=$config["mvcNS"]["models"];
170
		$modelsDir=ROOT . DS . str_replace("\\", DS, $modelsNS);
171
		echo "Models directory is " . ROOT . $modelsNS . "\n";
172
		$files=self::glob_recursive($modelsDir . DS . '*');
173
		foreach ( $files as $file ) {
174
			if (is_file($file)) {
175
				$model=ClassUtils::getClassFullNameFromFile($file);
176
				new $model();
177
			}
178
		}
179
	}
180
181
	private static function initControllersCache(&$config) {
182
		$controllersNS=$config["mvcNS"]["controllers"];
183
		$controllersDir=ROOT . DS . str_replace("\\", DS, $controllersNS);
184
		echo "Controllers directory is " . ROOT . $controllersNS . "\n";
185
		$files=self::glob_recursive($controllersDir . DS . '*');
186
		foreach ( $files as $file ) {
187
			if (is_file($file)) {
188
				$controller=ClassUtils::getClassFullNameFromFile($file);
189
				self::addControllerCache($controller);
190
			}
191
		}
192
		if ($config["debug"])
193
			self::addAdminRoutes();
194
		self::$cache->store("controllers/routes", "return " . JArray::asPhpArray(self::$routes, "array") . ";");
195
	}
196
197
	private static function glob_recursive($pattern, $flags=0) {
198
		$files=glob($pattern, $flags);
199
		foreach ( glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir ) {
200
			$files=array_merge($files, self::glob_recursive($dir . '/' . basename($pattern), $flags));
201
		}
202
		return $files;
203
	}
204
205
	private static function register(AnnotationManager $annotationManager) {
206
		$annotationManager->registry=array_merge($annotationManager->registry, [ 'id' => 'micro\annotations\IdAnnotation','manyToOne' => 'micro\annotations\ManyToOneAnnotation','oneToMany' => 'micro\annotations\OneToManyAnnotation','manyToMany' => 'micro\annotations\ManyToManyAnnotation','joinColumn' => 'micro\annotations\JoinColumnAnnotation','table' => 'micro\annotations\TableAnnotation','transient' => 'micro\annotations\TransientAnnotation','column' => 'micro\annotations\ColumnAnnotation','joinTable' => 'micro\annotations\JoinTableAnnotation','route' => 'micro\annotations\router\RouteAnnotation' ]);
207
	}
208
209
	public static function addAdminRoutes() {
210
		self::addControllerCache("micro\controllers\Admin");
211
	}
212
213
	public static function getRoutes() {
214
		$result=self::getControllerCache();
215
		return $result;
216
	}
217
218
	public static function addRoute($path, $controller, $action="index", $methods=null, $name="") {
219
		$controllerCache=self::getControllerCache();
220
		Router::addRouteToRoutes($controllerCache, $path, $controller, $action, $methods, $name);
221
		self::$cache->store("controllers/routes", "return " . JArray::asPhpArray($controllerCache, "array") . ";");
222
	}
223
}
224