sqlite_cache::putData()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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