Passed
Pull Request — master (#178)
by
unknown
02:54
created

ViewCache::set()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 10
rs 10
1
<?php
2
3
namespace Quantum\Libraries\ResourceCache;
4
5
use Quantum\Libraries\Storage\FileSystem;
6
use Quantum\Exceptions\DiException;
7
use ReflectionException;
8
use voku\helper\HtmlMin;
9
use Quantum\Di\Di;
10
use Exception;
11
12
class ViewCache
13
{
14
	/**
15
	 * @var string
16
	 */
17
	private $cacheDir;
18
19
	/**
20
	 * @var string
21
	 */
22
	private $mimeType = '.tmp';
23
24
	/**
25
	 * @var object
26
	 */
27
	private $fs;
28
29
	/**
30
	 * @var ViewCache
31
	 */
32
	private static $instance = null;
33
34
	public static function getInstance(): ViewCache
35
	{
36
		if (self::$instance === null) {
37
			self::$instance = new self();
38
		}
39
40
		return self::$instance;
41
	}
42
43
	/**
44
	 * @throws ConfigException
45
	 * @throws DiException
46
	 * @throws ReflectionException
47
	 * @throws Exception
48
	 */
49
	public function __construct()
50
	{
51
		$this->fs = Di::get(FileSystem::class);
52
53
		if (!config()->has('view_cache')) {
54
			throw new Exception('The config "view_cache" does not exists.');
55
		}
56
57
		$this->cacheDir = self::getCacheDir();
58
59
		if (!$this->fs->isDirectory($this->cacheDir)) {
60
			mkdir($this->cacheDir, 0777, true);
61
		}
62
	}
63
64
	/**
65
	 * @param string $key
66
	 * @param string $content
67
	 * @param string $sessionId
68
	 * @return ViewCache
69
	 */
70
	public function set(string $key, string $content, string $sessionId): ViewCache
71
	{
72
		if (config()->has('view_cache.minify')) {
73
			$content = $this->minify($content);
74
		}
75
76
		$cacheFile = $this->getCacheFile($key, $sessionId);
77
		$this->fs->put($cacheFile, $content);
78
79
		return $this;
80
	}
81
82
	/**
83
	 * @param string $key
84
	 * @param string $sessionId
85
	 * @param int $ttl
86
	 * @return mixed|null
87
	 */
88
	public function get(string $key, string $sessionId, int $ttl): ?string
89
	{
90
		$cacheFile = $this->getCacheFile($key, $sessionId);
91
		if (!$this->fs->exists($cacheFile)) {
92
			return null;
93
		}
94
95
		$data = $this->fs->get($cacheFile);
96
		if (time() > ($this->fs->lastModified($cacheFile) + $ttl)) {
97
			$this->fs->remove($cacheFile);
98
			return null;
99
		}
100
101
		return $data;
102
	}
103
104
	/**
105
	 * @param string $key
106
	 * @param string $sessionId
107
	 * @return void
108
	 */
109
	public function delete(string $key, string $sessionId): void
110
	{
111
		$cacheFile = $this->getCacheFile($key, $sessionId);
112
		if ($this->fs->exists($cacheFile)) {
113
			$this->fs->remove($cacheFile);
114
		}
115
	}
116
117
	/**
118
	 * @param string $key
119
	 * @param string $sessionId
120
	 * @param int $ttl
121
	 * @return bool
122
	 */
123
	public function exists(string $key, string $sessionId, int $ttl): bool
124
	{
125
		$cacheFile = $this->getCacheFile($key, $sessionId);
126
127
		if (!$this->fs->exists($cacheFile)) {
128
			return false;
129
		}
130
131
		if (time() > ($this->fs->lastModified($cacheFile) + $ttl)) {
132
			$this->fs->remove($cacheFile);
133
			return false;
134
		}
135
136
		return true;
137
	}
138
139
	private static function getCacheDir(): string
140
	{
141
		$configCacheDir = config()->get('view_cache.cache_dir', 'cache');
142
143
		$cacheDir = base_dir() . DS . $configCacheDir . DS . 'views' . DS;
144
145
		if ($module = current_module()) {
146
			$cacheDir = base_dir() . DS . $configCacheDir . DS . 'views' . DS . strtolower($module) . DS;
147
		}
148
149
		return $cacheDir;
150
	}
151
152
	/**
153
	 * @param string $key
154
	 * @param string $sessionId
155
	 * @return string
156
	 */
157
	private function getCacheFile(string $key, string $sessionId): string
158
	{
159
		return $this->cacheDir . md5($key . $sessionId) . $this->mimeType;
160
	}
161
162
	/**
163
	 * @param string $content
164
	 * @return string
165
	 */
166
	private function minify(string $content): string
167
	{
168
		return (new HtmlMin())->minify($content);
169
	}
170
}