Completed
Push — master ( 80871c...4b26f9 )
by Peter
15:19
created

MetaCache   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 86.96%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 29
c 2
b 0
f 0
lcom 1
cbo 6
dl 0
loc 186
ccs 80
cts 92
cp 0.8696
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 3
A setComponent() 0 4 1
A setOptions() 0 4 1
B get() 0 25 4
A set() 0 13 1
A remove() 0 10 2
A clear() 0 4 1
A _clearCurrent() 0 4 1
B _clear() 0 12 5
A _getFilename() 0 4 1
A _classToFile() 0 4 1
C prepare() 0 30 8
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL, Commercial license.
5
 *
6
 * @package maslosoft/addendum
7
 * @licence AGPL, Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]> (Meta container, further improvements, bugfixes)
9
 * @copyright Copyright (c) Maslosoft (Meta container, further improvements, bugfixes)
10
 * @copyright Copyright (c) Jan Suchal (Original version, builder, parser)
11
 * @link http://maslosoft.com/addendum/ - maslosoft addendum
12
 * @link https://code.google.com/p/addendum/ - original addendum project
13
 */
14
15
namespace Maslosoft\Addendum\Cache;
16
17
use FilesystemIterator;
18
use Maslosoft\Addendum\Addendum;
19
use Maslosoft\Addendum\Collections\Meta;
20
use Maslosoft\Addendum\Helpers\SoftIncluder;
21
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
22
use Maslosoft\Addendum\Options\MetaOptions;
23
use Maslosoft\Cli\Shared\ConfigDetector;
24
use Maslosoft\Cli\Shared\Helpers\PhpExporter;
25
use RecursiveDirectoryIterator;
26
use RecursiveIteratorIterator;
27
use RuntimeException;
28
29
class MetaCache
30
{
31
32
	private $_metaClass = null;
33
	private $_component = null;
34
35
	/**
36
	 * Options
37
	 * @var string
38
	 */
39
	private $_instanceId = null;
40
41
	/**
42
	 * Addendum runtime path
43
	 * @var string
44
	 */
45
	private $_path = '';
46
47
	/**
48
	 *
49
	 * @var NsCache
50
	 */
51
	private $_nsCache = null;
52
53
	/**
54
	 * Runtime path
55
	 * @var string
56
	 */
57
	private static $_runtimePath = null;
58
59
	/**
60
	 * Local cacheq
61
	 * @var type
62
	 */
63
	private static $_cache = [];
64
65 3
	public function __construct($metaClass = null, AnnotatedInterface $component = null, MetaOptions $options = null)
66
	{
67 3
		if (null === self::$_runtimePath)
68 3
		{
69 1
			self::$_runtimePath = (new ConfigDetector)->getRuntimePath();
70 1
		}
71 3
		$this->_path = self::$_runtimePath . '/addendum';
72 3
		$this->_metaClass = $metaClass;
73 3
		$this->_component = $component;
74 3
		if (empty($options))
75 3
		{
76 3
			$this->_instanceId = Addendum::DefaultInstanceId;
77 3
		}
78
		else
79
		{
80
			$this->_instanceId = $options->instanceId;
81
		}
82 3
		$this->_nsCache = new NsCache(dirname($this->_getFilename()), Addendum::fly($this->_instanceId));
83 3
	}
84
85 27
	public function setComponent(AnnotatedInterface $component = null)
86
	{
87 27
		$this->_component = $component;
88 27
	}
89
90 27
	public function setOptions(MetaOptions $options = null)
91
	{
92 27
		$this->_nsCache->setOptions($options);
93 27
	}
94
95 27
	public function prepare()
96
	{
97 27
		if (!file_exists($this->_path))
98 27
		{
99 2
			if (!file_exists(self::$_runtimePath))
100 2
			{
101
102 1
				if (is_writable(dirname(self::$_runtimePath)))
103 1
				{
104 1
					mkdir(self::$_runtimePath, 0777, true);
105 1
				}
106 1
				if (!is_writable(self::$_runtimePath))
107 1
				{
108
					throw new RuntimeException(sprintf("Runtime path `%s` must exists and be writable", self:: $_runtimePath));
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after double colon; 1 found

This check looks for references to static members where there are spaces between the name of the type and the actual member.

An example:

Certificate:: TRIPLEDES_CBC

will actually work, but is not very readable.

Loading history...
109
				}
110 1
			}
111 2
			if (is_writable(self::$_runtimePath))
112 2
			{
113 2
				mkdir($this->_path, 0777, true);
114 2
			}
115 2
			if (!is_writable($this->_path))
116 2
			{
117
				throw new RuntimeException(sprintf("Addendum runtime path `%s` must exists and be writable", $this->_path));
118
			}
119 2
		}
120 27
		if (!file_exists(dirname($this->_getFilename())))
121 27
		{
122 2
			mkdir(dirname($this->_getFilename()), 0777, true);
123 2
		}
124 27
	}
125
126 27
	public function get()
127
	{
128 27
		$this->prepare();
129 27
		$filename = $this->_getFilename();
130
131 27
		if (!$this->_nsCache->valid())
132 27
		{
133 2
			$this->_clearCurrent();
134 2
			return false;
135
		}
136
137 26
		if (isset(self::$_cache[$filename]))
138 26
		{
139 2
			return self::$_cache[$filename];
140
		}
141
142 24
		$data = SoftIncluder::includeFile($filename);
143
144 24
		if (empty($data))
145 24
		{
146 24
			return false;
147
		}
148
		self::$_cache[$filename] = $data;
149
		return $data;
150
	}
151
152 19
	public function set(Meta $meta)
153
	{
154
155
156
157 19
		$filename = $this->_getFilename();
158
159 19
		self::$_cache[$filename] = $meta;
160
161 19
		file_put_contents($filename, PhpExporter ::export($meta));
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces before double colon; 1 found

This check looks for references to static members where there are spaces between the name of the type and the actual member.

An example:

Certificate ::TRIPLEDES_CBC

will actually work, but is not very readable.

Loading history...
162 19
		$this->_nsCache->set();
163 19
		return $meta;
164
	}
165
166
	public function remove()
167
	{
168
		$filename = $this->_getFilename();
169
		unset(self::$_cache[$filename]);
170
		if (file_exists($filename))
171
		{
172
			return unlink($filename);
173
		}
174
		return false;
175
	}
176
177
	/**
178
	 * Clear entire cache
179
	 * @return boolean
180
	 */
181 3
	public function clear()
182
	{
183 3
		return $this->_clear($this->_path);
184
	}
185
186 2
	private function _clearCurrent()
187
	{
188 2
		return $this->_classToFile(dirname($this->_getFilename()));
189
	}
190
191 3
	private function _clear($path)
192
	{
193 3
		if (!file_exists($path))
194 3
		{
195 3
			return false;
196
		}
197 1
		foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $dir)
198
		{
199 1
			$dir->isDir() && !$dir->isLink() ? rmdir($dir->getPathname()) : unlink($dir->getPathname());
200 1
		}
201 1
		return rmdir($path);
202
	}
203
204 29
	private function _getFilename()
205
	{
206 29
		return sprintf('%s/%s@%s/%s.php', $this->_path, $this->_classToFile($this->_metaClass), $this->_instanceId, str_replace('\\', '/', $this->_classToFile(get_class($this->_component))));
207
	}
208
209 29
	private function _classToFile($className)
210
	{
211 29
		return str_replace('\\', '.', $className);
212
	}
213
214
}
215