Passed
Pull Request — release-2.1 (#6262)
by Jeremy
04:04
created

sqlite_cache::setCachedir()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
c 0
b 0
f 0
nop 1
dl 0
loc 12
rs 9.6111
nc 3
1
<?php
2
3
/**
4
 * Simple Machines Forum (SMF)
5
 *
6
 * @package SMF
7
 * @author Simple Machines https://www.simplemachines.org
8
 * @copyright 2020 Simple Machines and individual contributors
9
 * @license https://www.simplemachines.org/about/smf/license.php BSD
10
 *
11
 * @version 2.1 RC3
12
 */
13
14
if (!defined('SMF'))
15
	die('Hacking attempt...');
16
17
/**
18
 * SQLite Cache API class
19
 *
20
 * @package cacheAPI
21
 */
22
class sqlite_cache extends cache_api
23
{
24
	/**
25
	 * @var string The path to the current $cachedir directory.
26
	 */
27
	private $cachedir = null;
28
29
	/**
30
	 * @var SQLite3
31
	 */
32
	private $cacheDB = null;
33
34
	public function __construct()
35
	{
36
		parent::__construct();
37
38
		// Set our default cachedir.
39
		$this->setCachedir();
40
	}
41
42
	/**
43
	 * {@inheritDoc}
44
	 */
45
	public function connect()
46
	{
47
		$database = $this->cachedir . '/' . 'SQLite3Cache.db3';
48
		$this->cacheDB = new SQLite3($database);
49
		$this->cacheDB->busyTimeout(1000);
50
		if (filesize($database) == 0)
51
		{
52
			$this->cacheDB->exec('CREATE TABLE cache (key text unique, value blob, ttl int);');
53
			$this->cacheDB->exec('CREATE INDEX ttls ON cache(ttl);');
54
		}
55
	}
56
57
	/**
58
	 * {@inheritDoc}
59
	 */
60
	public function isSupported($test = false)
61
	{
62
		$supported = class_exists("SQLite3") && is_writable($this->cachedir);
63
64
		if ($test)
65
			return $supported;
66
67
		return parent::isSupported() && $supported;
68
	}
69
70
	/**
71
	 * {@inheritDoc}
72
	 */
73
	public function getData($key, $ttl = null)
74
	{
75
		$query = 'SELECT value FROM cache WHERE key = \'' . $this->cacheDB->escapeString($key) . '\' AND ttl >= ' . time() . ' LIMIT 1';
76
		$result = $this->cacheDB->query($query);
77
78
		$value = null;
79
		while ($res = $result->fetchArray(SQLITE3_ASSOC))
80
			$value = $res['value'];
81
82
		return !empty($value) ? $value : null;
83
	}
84
85
	/**
86
	 * {@inheritDoc}
87
	 */
88
	public function putData($key, $value, $ttl = null)
89
	{
90
		$ttl = time() + (int) ($ttl !== null ? $ttl : $this->ttl);
91
		if ($value === null)
92
			$query = 'DELETE FROM cache WHERE key = \'' . $this->cacheDB->escapeString($key) . '\';';
93
		else
94
			$query = 'REPLACE INTO cache VALUES (\'' . $this->cacheDB->escapeString($key) . '\', \'' . $this->cacheDB->escapeString($value) . '\', ' . $ttl . ');';
95
		$result = $this->cacheDB->exec($query);
96
97
		return $result;
98
	}
99
100
	/**
101
	 * {@inheritDoc}
102
	 */
103
	public function cleanCache($type = '')
104
	{
105
		if ($type == 'expired')
106
			$query = 'DELETE FROM cache WHERE ttl >= ' . time() . ';';
107
		else
108
			$query = 'DELETE FROM cache;';
109
110
		$result = $this->cacheDB->exec($query);
111
112
		$query = 'VACUUM;';
113
		$this->cacheDB->exec($query);
114
115
		return $result;
116
	}
117
118
	/**
119
	 * {@inheritDoc}
120
	 */
121
	public function cacheSettings(array &$config_vars)
122
	{
123
		global $context, $txt;
124
125
		$config_vars[] = $txt['cache_sqlite_settings'];
126
		$config_vars[] = array('cachedir_sqlite', $txt['cachedir_sqlite'], 'file', 'text', 36, 'cache_sqlite_cachedir');
127
128
		if (!isset($context['settings_post_javascript']))
129
			$context['settings_post_javascript'] = '';
130
131
		$context['settings_post_javascript'] .= '
132
			$("#cache_accelerator").change(function (e) {
133
				var cache_type = e.currentTarget.value;
134
				$("#cachedir_sqlite").prop("disabled", cache_type != "sqlite");
135
			});';
136
	}
137
138
	/**
139
	 * Sets the $cachedir or uses the SMF default $cachedir..
140
	 *
141
	 * @access public
142
	 *
143
	 * @param string $dir A valid path
144
	 *
145
	 * @return boolean If this was successful or not.
146
	 */
147
	public function setCachedir($dir = null)
148
	{
149
		global $cachedir, $cachedir_sqlite;
150
151
		// If its invalid, use SMF's.
152
		if (is_null($dir) || !is_writable($dir))
153
			if (is_null($cachedir_sqlite) || !is_writable($cachedir_sqlite))
154
				$this->cachedir = $cachedir;
155
			else
156
				$this->cachedir = $cachedir_sqlite;
157
		else
158
			$this->cachedir = $dir;
159
	}
160
161
	/**
162
	 * {@inheritDoc}
163
	 */
164
	public function getVersion()
165
	{
166
		$temp = $this->cacheDB->version();
167
		return $temp['versionString'];
168
	}
169
170
	/**
171
	 * {@inheritDoc}
172
	 */
173
	public function housekeeping()
174
	{
175
		$this->cleanCache('expired');
176
	}
177
}
178
179
?>