Completed
Push — master ( 707e60...bec0f5 )
by Jean-Christophe
01:22
created

CacheManager::_getFiles()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 6

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 6
nc 2
nop 3
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
14
class CacheManager {
15
	public static $cache;
16
	private static $routes=[ ];
17
	private static $cacheDirectory;
18
	private static $expiredRoutes=[ ];
19
20
	public static function start(&$config) {
21
		self::$cacheDirectory=self::initialGetCacheDirectory($config);
22
		$cacheDirectory=ROOT . DS . self::$cacheDirectory;
23
		Annotations::$config['cache']=new AnnotationCache($cacheDirectory . '/annotations');
24
		self::register(Annotations::getManager());
25
		self::$cache=new ArrayCache($cacheDirectory, ".cache");
26
	}
27
28
	public static function startProd(&$config) {
29
		self::$cacheDirectory=self::initialGetCacheDirectory($config);
30
		$cacheDirectory=ROOT . DS . self::$cacheDirectory;
31
		self::$cache=new ArrayCache($cacheDirectory, ".cache");
32
	}
33
34
	public static function getControllerCache() {
35
		if (self::$cache->exists("controllers/routes"))
36
			return self::$cache->fetch("controllers/routes");
37
		return [ ];
38
	}
39
40
	public static function getRouteCache($routePath, $duration) {
41
		$key=self::getRouteKey($routePath);
42
43
		if (self::$cache->exists("controllers/" . $key) && !self::expired($key, $duration)) {
44
			$response=self::$cache->file_get_contents("controllers/" . $key);
45
			return $response;
46
		} else {
47
			$response=Startup::runAsString($routePath);
48
			return self::storeRouteResponse($key, $response);
49
		}
50
	}
51
52
	public static function expired($key, $duration) {
53
		return self::$cache->expired("controllers/" . $key, $duration) === true || \array_key_exists($key, self::$expiredRoutes);
54
	}
55
56
	public static function isExpired($path,$duration){
57
		$route=Router::getRoute($path,false);
58
		if($route!==false && \is_array($route)){
59
			return self::expired(self::getRouteKey($route), $duration);
60
		}
61
		return true;
62
	}
63
64
	public static function setExpired($routePath, $expired=true) {
65
		$key=self::getRouteKey($routePath);
66
		self::setKeyExpired($key, $expired);
67
	}
68
69
	private static function setKeyExpired($key, $expired=true) {
70
		if ($expired) {
71
			self::$expiredRoutes[$key]=true;
72
		} else {
73
			unset(self::$expiredRoutes[$key]);
74
		}
75
	}
76
77
	public static function setRouteCache($routePath) {
78
		$key=self::getRouteKey($routePath);
79
		$response=Startup::runAsString($routePath);
80
		return self::storeRouteResponse($key, $response);
81
	}
82
83
	private static function storeRouteResponse($key, $response) {
84
		self::setKeyExpired($key, false);
85
		self::$cache->store("controllers/" . $key, $response, false);
86
		return $response;
87
	}
88
89
	private static function getRouteKey($routePath) {
90
		return "path" . \md5(\implode("", $routePath));
91
	}
92
93
	private static function initialGetCacheDirectory(&$config) {
94
		$cacheDirectory=@$config["cacheDirectory"];
95
		if (!isset($cacheDirectory)) {
96
			$config["cacheDirectory"]="cache/";
97
			$cacheDirectory=$config["cacheDirectory"];
98
		}
99
		return $cacheDirectory;
100
	}
101
102
	public static function getCacheDirectory() {
103
		return self::$cacheDirectory;
104
	}
105
106
	public static function createOrmModelCache($classname) {
107
		$key=self::getModelCacheKey($classname);
108
		if(isset(self::$cache)){
109
			if (!self::$cache->exists($key)) {
110
				$p=new ModelParser();
111
				$p->parse($classname);
112
				self::$cache->store($key, $p->__toString());
113
			}
114
			return self::$cache->fetch($key);
115
		}
116
	}
117
118
	public static function getModelCacheKey($classname){
119
		return \str_replace("\\", DIRECTORY_SEPARATOR, $classname);
120
	}
121
122
	public static function modelCacheExists($classname){
123
		$key=self::getModelCacheKey($classname);
124
		if(isset(self::$cache))
125
			return self::$cache->exists($key);
126
		return false;
127
	}
128
129
	private static function addControllerCache($classname) {
130
		$parser=new ControllerParser();
131
		try {
132
			$parser->parse($classname);
133
			self::$routes=\array_merge($parser->asArray(), self::$routes);
134
		} catch ( \Exception $e ) {
135
			// Nothing to do
136
		}
137
	}
138
139
	public static function checkCache(&$config,$silent=false) {
140
		$dirs=self::getCacheDirectories($config,$silent);
141
		foreach ($dirs as $dir){
142
			self::safeMkdir($dir);
143
		}
144
		return $dirs;
145
	}
146
147
	public static function getCacheDirectories(&$config,$silent=false){
148
		$cacheDirectory=self::initialGetCacheDirectory($config);
149
		if(!$silent){
150
			echo "cache directory is " . ROOT . DS . $cacheDirectory . "\n";
151
		}
152
		$modelsDir=str_replace("\\", DS, $config["mvcNS"]["models"]);
153
		$controllersDir=str_replace("\\", DS, $config["mvcNS"]["controllers"]);
154
		$annotationCacheDir=ROOT . DS . $cacheDirectory . DS . "annotations";
155
		$modelsCacheDir=ROOT . DS . $cacheDirectory . DS . $modelsDir;
156
		$queriesCacheDir=ROOT . DS . $cacheDirectory . DS . "queries";
157
		$controllersCacheDir=ROOT . DS . $cacheDirectory . DS . $controllersDir;
158
		$viewsCacheDir=ROOT . DS . $cacheDirectory . DS . "views";
159
		return [ "annotations" => $annotationCacheDir,"models" => $modelsCacheDir,"controllers" => $controllersCacheDir,"queries" => $queriesCacheDir ,"views"=>$viewsCacheDir];
160
	}
161
162
	private static function safeMkdir($dir) {
163
		if (!is_dir($dir))
164
			return mkdir($dir, 0777, true);
165
	}
166
167
	public static function clearCache(&$config, $type="all") {
168
		$cacheDirectories=self::checkCache($config);
169
		$cacheDirs=["annotations","controllers","models","queries","views"];
170
		foreach ($cacheDirs as $typeRef){
171
			self::_clearCache($cacheDirectories, $type, $typeRef);
172
		}
173
	}
174
175
	private static function _clearCache($cacheDirectories,$type,$typeRef){
176
		if ($type === "all" || $type === $typeRef)
177
			FsUtils::deleteAllFilesFromFolder($cacheDirectories[$typeRef]);
178
	}
179
180
	public static function initCache(&$config, $type="all") {
181
		self::checkCache($config,$type);
0 ignored issues
show
Documentation introduced by
$type is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
182
		self::start($config);
183
		if ($type === "all" || $type === "models")
184
			self::initModelsCache($config);
185
		if ($type === "all" || $type === "controllers")
186
			self::initControllersCache($config);
187
	}
188
189
	public static function initModelsCache(&$config,$forChecking=false,$silent=false) {
190
		$files=self::getModelsFiles($config, "models",$silent);
0 ignored issues
show
Documentation introduced by
'models' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to CacheManager::getModelsFiles() has too many arguments starting with $silent.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
191
		foreach ( $files as $file ) {
192
			if (is_file($file)) {
193
				$model=ClassUtils::getClassFullNameFromFile($file);
194
				if(!$forChecking){
195
					new $model();
196
				}
197
			}
198
		}
199
	}
200
201
	public static function getModelsFiles(&$config,$silent=false){
202
		return self::_getFiles($config, "models",$silent);
203
	}
204
205
	public static function getControllersFiles(&$config,$silent=false){
206
		return self::_getFiles($config, "controllers",$silent);
207
	}
208
209
	private static function _getFiles(&$config,$type,$silent=false){
210
		$typeNS=$config["mvcNS"][$type];
211
		$typeDir=ROOT . DS . str_replace("\\", DS, $typeNS);
212
		if(!$silent)
213
			echo \ucfirst($type)." directory is " . ROOT . $typeNS . "\n";
214
		return FsUtils::glob_recursive($typeDir . DS . '*');
215
	}
216
217
	private static function initControllersCache(&$config) {
218
		$files=self::getControllersFiles($config);
219
		foreach ( $files as $file ) {
220
			if (is_file($file)) {
221
				$controller=ClassUtils::getClassFullNameFromFile($file);
222
				self::addControllerCache($controller);
223
			}
224
		}
225
		if ($config["debug"])
226
			self::addAdminRoutes();
227
		self::$cache->store("controllers/routes", "return " . JArray::asPhpArray(self::$routes, "array") . ";");
228
	}
229
230
	private static function register(AnnotationManager $annotationManager) {
231
		$annotationManager->registry=array_merge($annotationManager->registry, [
232
				'id' => 'micro\annotations\IdAnnotation',
233
				'manyToOne' => 'micro\annotations\ManyToOneAnnotation',
234
				'oneToMany' => 'micro\annotations\OneToManyAnnotation',
235
				'manyToMany' => 'micro\annotations\ManyToManyAnnotation',
236
				'joinColumn' => 'micro\annotations\JoinColumnAnnotation',
237
				'table' => 'micro\annotations\TableAnnotation',
238
				'transient' => 'micro\annotations\TransientAnnotation',
239
				'column' => 'micro\annotations\ColumnAnnotation',
240
				'joinTable' => 'micro\annotations\JoinTableAnnotation',
241
				'route' => 'micro\annotations\router\RouteAnnotation',
242
				'var' => 'mindplay\annotations\standard\VarAnnotation'
243
		]);
244
	}
245
246
	public static function addAdminRoutes() {
247
		self::addControllerCache("micro\controllers\Admin");
248
	}
249
250
	public static function getRoutes() {
251
		$result=self::getControllerCache();
252
		return $result;
253
	}
254
255
	public static function addRoute($path, $controller, $action="index", $methods=null, $name="") {
256
		$controllerCache=self::getControllerCache();
257
		Router::addRouteToRoutes($controllerCache, $path, $controller, $action, $methods, $name);
258
		self::$cache->store("controllers/routes", "return " . JArray::asPhpArray($controllerCache, "array") . ";");
259
	}
260
}
261