Completed
Push — master ( e893f6...204e13 )
by Peter
20:17
created

MetaCache::setOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
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 32
	public function setComponent(AnnotatedInterface $component = null)
86
	{
87 32
		$this->component = $component;
88 32
	}
89
90 32
	public function setOptions(MetaOptions $options = null)
91
	{
92 32
		$this->nsCache->setOptions($options);
93 32
	}
94
95 32
	public function prepare()
96
	{
97 32
		if (!file_exists($this->path))
98 32
		{
99 2
			if (!file_exists(self::$runtimePath))
100 2
			{
101
102 1
				if (is_writable(dirname(self::$runtimePath)))
103 1
				{
104 1
					$this->mkdir(self::$runtimePath);
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));
109
				}
110 1
			}
111 2
			if (is_writable(self::$runtimePath))
112 2
			{
113 2
				$this->mkdir($this->path);
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 32
		if (!file_exists(dirname($this->getFilename())))
121 32
		{
122 2
			$this->mkdir(dirname($this->getFilename()));
123 2
		}
124 32
	}
125
126 32
	public function get()
127
	{
128 32
		$this->prepare();
129 32
		$filename = $this->getFilename();
130
131 32
		if (!$this->nsCache->valid())
132 32
		{
133 2
			$this->clearCurrent();
134 2
			return false;
135
		}
136
137 31
		if (isset(self::$cache[$filename]))
138 31
		{
139 4
			return self::$cache[$filename];
140
		}
141
142 27
		$data = SoftIncluder::includeFile($filename);
143
144 27
		if (empty($data))
145 27
		{
146 27
			return false;
147
		}
148
		self::$cache[$filename] = $data;
149
		return $data;
150
	}
151
152 21
	public function set(Meta $meta)
153
	{
154
155
156
157 21
		$filename = $this->getFilename();
158
159 21
		self::$cache[$filename] = $meta;
160
161 21
		file_put_contents($filename, PhpExporter::export($meta));
162 21
		chmod($filename, 0666);
163 21
		$this->nsCache->set();
164 21
		return $meta;
165
	}
166
167
	public function remove()
168
	{
169
		$filename = $this->getFilename();
170
		unset(self::$cache[$filename]);
171
		if (file_exists($filename))
172
		{
173
			return unlink($filename);
174
		}
175
		return false;
176
	}
177
178
	/**
179
	 * Clear entire cache
180
	 * @return boolean
181
	 */
182 3
	public function clear()
183
	{
184 3
		return $this->clearPath($this->path);
185
	}
186
187 2
	private function clearCurrent()
188
	{
189 2
		return $this->classToFile(dirname($this->getFilename()));
190
	}
191
192 3
	private function clearPath($path)
193
	{
194 3
		if (!file_exists($path))
195 3
		{
196 3
			return false;
197
		}
198 1
		foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $dir)
199
		{
200 1
			$dir->isDir() && !$dir->isLink() ? rmdir($dir->getPathname()) : unlink($dir->getPathname());
201 1
		}
202 1
		return rmdir($path);
203
	}
204
205 34
	private function getFilename()
206
	{
207 34
		return sprintf('%s/%s@%s/%s.php', $this->path, $this->classToFile($this->metaClass), $this->instanceId, str_replace('\\', '/', $this->classToFile(get_class($this->component))));
208
	}
209
210 34
	private function classToFile($className)
211
	{
212 34
		return str_replace('\\', '.', $className);
213
	}
214
215
	/**
216
	 * Recursively create dir with proper permissions.
217
	 * 
218
	 * @param string $path
219
	 */
220 2
	private function mkdir($path)
221
	{
222 2
		$mask = umask(0000);
223 2
		mkdir($path, 0777, true);
224 2
		umask($mask);
225 2
	}
226
227
}
228