Failed Conditions
Branch release-2.1 (4e22cf)
by Rick
06:39
created

Sources/CacheAPI-smf.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Simple Machines Forum (SMF)
5
 *
6
 * @package SMF
7
 * @author Simple Machines http://www.simplemachines.org
8
 * @copyright 2017 Simple Machines and individual contributors
9
 * @license http://www.simplemachines.org/about/smf/license.php BSD
10
 *
11
 * @version 2.1 Beta 4
12
 */
13
14
if (!defined('SMF'))
15
	die('Hacking attempt...');
16
17
/**
18
 * Our Cache API class
19
 * @package cacheAPI
20
 */
21
class smf_cache extends cache_api
22
{
23
	/**
24
	 * @var string The path to the current $cachedir directory.
25
	 */
26
	private $cachedir = null;
27
28
	/**
29
	 * {@inheritDoc}
30
	 */
31
	public function __construct()
32
	{
33
		parent::__construct();
34
35
		// Set our default cachedir.
36
		$this->setCachedir();
37
	}
38
39
	/**
40
	 * {@inheritDoc}
41
	 */
42 View Code Duplication
	public function isSupported($test = false)
43
	{
44
		$supported = is_writable($this->cachedir);
45
46
		if ($test)
47
			return $supported;
48
		return parent::isSupported() && $supported;
49
	}
50
51
	/**
52
	 * {@inheritDoc}
53
	 */
54
	public function getData($key, $ttl = null)
55
	{
56
		$key = $this->prefix . strtr($key, ':/', '-_');
57
		$cachedir = $this->cachedir;
58
59
		// SMF Data returns $value and $expired.  $expired has a unix timestamp of when this expires.
60
		if (file_exists($cachedir . '/data_' . $key . '.php') && filesize($cachedir . '/data_' . $key . '.php') > 10)
61
		{
62
			// Work around Zend's opcode caching (PHP 5.5+), they would cache older files for a couple of seconds
63
			// causing newer files to take effect a while later.
64
			if (function_exists('opcache_invalidate'))
65
				opcache_invalidate($cachedir . '/data_' . $key . '.php', true);
66
67
			if (function_exists('apc_delete_file'))
68
				@apc_delete_file($cachedir . '/data_' . $key . '.php');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
69
70
			// php will cache file_exists et all, we can't 100% depend on its results so proceed with caution
71
			@include($cachedir . '/data_' . $key . '.php');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
72
			if (!empty($expired) && isset($value))
0 ignored issues
show
The variable $expired seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
The variable $value seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
73
			{
74
				@unlink($cachedir . '/data_' . $key . '.php');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
75
				unset($value);
76
			}
77
		}
78
79
		return !empty($value) ? $value : null;
80
	}
81
82
	/**
83
	 * {@inheritDoc}
84
	 */
85
	public function putData($key, $value, $ttl = null)
86
	{
87
		$key = $this->prefix . strtr($key, ':/', '-_');
88
		$cachedir = $this->cachedir;
89
90
		// Work around Zend's opcode caching (PHP 5.5+), they would cache older files for a couple of seconds
91
		// causing newer files to take effect a while later.
92
		if (function_exists('opcache_invalidate'))
93
			opcache_invalidate($cachedir . '/data_' . $key . '.php', true);
94
95
		if (function_exists('apc_delete_file'))
96
			@apc_delete_file($cachedir . '/data_' . $key . '.php');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
97
98
		// Otherwise custom cache?
99
		if ($value === null)
100
			@unlink($cachedir . '/data_' . $key . '.php');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
101
		else
102
		{
103
			$cache_data = '<' . '?' . 'php if (!defined(\'SMF\')) die; if (' . (time() + $ttl) . ' < time()) $expired = true; else{$expired = false; $value = \'' . addcslashes($value, '\\\'') . '\';}' . '?' . '>';
104
105
			// Write out the cache file, check that the cache write was successful; all the data must be written
106
			// If it fails due to low diskspace, or other, remove the cache file
107
			$fileSize = file_put_contents($cachedir . '/data_' . $key . '.php', $cache_data, LOCK_EX);
108
			if ($fileSize !== strlen($cache_data))
109
			{
110
				@unlink($cachedir . '/data_' . $key . '.php');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
111
				return false;
112
			}
113
			else
114
				return true;
115
		}
116
	}
117
118
	/**
119
	 * {@inheritDoc}
120
	 */
121
	public function cleanCache($type = '')
122
	{
123
		$cachedir = $this->cachedir;
124
125
		// No directory = no game.
126
		if (!is_dir($cachedir))
127
			return;
128
129
		// Remove the files in SMF's own disk cache, if any
130
		$dh = opendir($cachedir);
131
		while ($file = readdir($dh))
132
		{
133
			if ($file != '.' && $file != '..' && $file != 'index.php' && $file != '.htaccess' && (!$type || substr($file, 0, strlen($type)) == $type))
134
				@unlink($cachedir . '/' . $file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
135
		}
136
		closedir($dh);
137
138
		// Make this invalid.
139
		$this->invalidateCache();
140
141
		return true;
142
	}
143
144
	/**
145
	 * {@inheritDoc}
146
	 */
147
	public function invalidateCache()
148
	{
149
		// We don't worry about $cachedir here, since the key is based on the real $cachedir.
150
		parent::invalidateCache();
151
152
		// Since SMF is file based, be sure to clear the statcache.
153
		clearstatcache();
154
155
		return true;
156
	}
157
158
	/**
159
	 * {@inheritDoc}
160
	 */
161 View Code Duplication
	public function cacheSettings(array &$config_vars)
162
	{
163
		global $context, $txt;
164
165
		$config_vars[] = $txt['cache_smf_settings'];
166
		$config_vars[] = array('cachedir', $txt['cachedir'], 'file', 'text', 36, 'cache_cachedir');
167
168
		if (!isset($context['settings_post_javascript']))
169
			$context['settings_post_javascript'] = '';
170
171
		$context['settings_post_javascript'] .= '
172
			$("#cache_accelerator").change(function (e) {
173
				var cache_type = e.currentTarget.value;
174
				$("#cachedir").prop("disabled", cache_type != "smf");
175
			});';
176
	}
177
178
	/**
179
	 * Sets the $cachedir or uses the SMF default $cachedir..
180
	 *
181
	 * @access public
182
	 * @param string $dir A valid path
183
	 * @return boolean If this was successful or not.
184
	 */
185 View Code Duplication
	public function setCachedir($dir = null)
186
	{
187
		global $cachedir;
188
189
		// If its invalid, use SMF's.
190
		if (is_null($dir) || !is_writable($dir))
191
			$this->cachedir = $cachedir;
192
		else
193
			$this->cachedir = $dir;
194
	}
195
196
	/**
197
	 * Gets the current $cachedir.
198
	 *
199
	 * @access public
200
	 * @return string the value of $ttl.
201
	 */
202
	public function getCachedir()
203
	{
204
		return $this->cachedir;
205
	}
206
}
207
208
?>