Completed
Pull Request — patch_1-1-4 (#3188)
by Spuds
09:56
created

Filebased::get()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4.0879

Importance

Changes 0
Metric Value
cc 4
eloc 15
nc 3
nop 2
dl 0
loc 30
ccs 14
cts 17
cp 0.8235
crap 4.0879
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file contains functions that deal with getting and setting cache values.
5
 *
6
 * @name      ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
9
 *
10
 * @version 1.1.4
11
 *
12
 */
13
14
namespace ElkArte\sources\subs\CacheMethod;
15
16
use FilesystemIterator;
17
use UnexpectedValueException;
18
19
/**
20
 * Filebased caching is the fallback if nothing else is available, it simply
21
 * uses the filesystem to store queries results in order to try to reduce the
22
 * number of queries per time period.
23
 *
24
 * The performance gain may or may not exist depending on many factors.
25
 *
26
 * It requires the CACHEDIR constant to be defined and pointing to a
27
 * writable directory.
28
 */
29
class Filebased extends Cache_Method_Abstract
30
{
31
	/**
32
	 * {@inheritdoc}
33
	 */
34
	protected $title = 'File-based caching';
35
36
	/**
37
	 * {@inheritdoc}
38
	 */
39
	protected $prefix = 'data_';
40
41
	/**
42
	 * File extension.
43
	 *
44
	 * @var string
45
	 */
46
	protected $ext = 'php';
47
48
	/**
49
	 * Obtain from the parent class the variables necessary
50
	 * to help the tests stay running smoothly.
51
	 *
52
	 * @param string $key
53
	 *
54
	 * @return string
55
	 */
56 2
	public function getFileName($key)
57
	{
58 2
		return $this->prefix . '_' . $key . '.' . $this->ext;
59
	}
60
61
	/**
62
	 * {@inheritdoc}
63
	 */
64 1
	public function exists($key)
65
	{
66 1
		return file_exists(CACHEDIR . '/' . $this->getFileName($key));
67
	}
68
69
	/**
70
	 * {@inheritdoc}
71
	 */
72 2
	public function put($key, $value, $ttl = 120)
73
	{
74 2
		$fName = $this->getFileName($key);
75
76
		// Clearing this data
77 2
		if ($value === null)
78 2
		{
79 1
			@unlink(CACHEDIR . '/' . $fName);
80 1
		}
81
		// Or stashing it away
82
		else
83
		{
84 2
			$cache_data = "<?php '" . json_encode(array('expiration' => time() + $ttl, 'data' => $value)) . "';";
85
86
			// Write out the cache file, check that the cache write was successful; all the data must be written
87
			// If it fails due to low diskspace, or other, remove the cache file
88 2
			if (@file_put_contents(CACHEDIR . '/' . $fName, $cache_data, LOCK_EX) !== strlen($cache_data))
89 2
			{
90
				@unlink(CACHEDIR . '/' . $fName);
91
			}
92
		}
93 2
	}
94
95
	/**
96
	 * {@inheritdoc}
97
	 */
98 2
	public function get($key, $ttl = 120)
99
	{
100 2
		$return = null;
101 2
		$fName = $this->getFileName($key);
102
103 2
		if (file_exists(CACHEDIR . '/' . $fName))
104 2
		{
105
			// Even though it exists, we may not be able to access the file so we use @ here
106 2
			$value = json_decode(substr(@file_get_contents(CACHEDIR . '/' . $fName), 7, -2));
107
108 2
			if ($value === null || $value->expiration < time())
109 2
			{
110
				@unlink(CACHEDIR . '/' . $fName);
111
				$return = null;
112
			}
113
			else
114
			{
115 2
				$return = $value->data;
116
			}
117
118 2
			unset($value);
119 2
			$this->is_miss = $return === null;
120
121 2
			return $return;
122
		}
123
124 2
		$this->is_miss = true;
125
126 2
		return $return;
127
	}
128
129
	/**
130
	 * {@inheritdoc}
131
	 */
132 1
	public function clean($type = '')
133
	{
134
		try
135
		{
136 1
			$files = new FilesystemIterator(CACHEDIR, FilesystemIterator::SKIP_DOTS);
137
138 1
			foreach ($files as $file)
139
			{
140 1
				if ($file->getFileName() !== 'index.php' && $file->getFileName() !== '.htaccess' && $file->getExtension() === $this->ext)
141 1
				{
142 1
					@unlink($file->getPathname());
143 1
				}
144 1
			}
145
		}
146 1
		catch (UnexpectedValueException $e)
147
		{
148
			// @todo
149
		}
150 1
	}
151
152
	/**
153
	 * {@inheritdoc}
154
	 */
155 1
	public function fixkey($key)
156
	{
157 1
		return strtr($key, ':/', '-_');
158
	}
159
160
	/**
161
	 * {@inheritdoc}
162
	 */
163 1
	public function isAvailable()
164
	{
165 1
		return @is_dir(CACHEDIR) && @is_writable(CACHEDIR);
166
	}
167
168
	/**
169
	 * {@inheritdoc}
170
	 */
171
	public function details()
172
	{
173
		return array('title' => $this->title, 'version' => 'N/A');
174
	}
175
176
	/**
177
	 * Adds the settings to the settings page.
178
	 *
179
	 * Used by integrate_modify_cache_settings added in the title method
180
	 *
181
	 * @param array $config_vars
182
	 */
183 1
	public function settings(&$config_vars)
184
	{
185 1
		global $txt;
186
187 1
		$config_vars[] = array('cachedir', $txt['cachedir'], 'file', 'text', 36, 'cache_cachedir', 'force_div_id' => 'filebased_cachedir');
188 1
	}
189
}
190