replace constants with class constants.
[phpbb.git] / phpBB / includes / acm / acm_file.php
blob23183d1865904797de3b4e78cb5a99911cc80f9a
1 <?php
2 /**
4 * @package acm
5 * @version $Id$
6 * @copyright (c) 2005 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9 */
11 /**
12 * @ignore
14 if (!defined('IN_PHPBB'))
16 exit;
19 /**
20 * ACM File Based Caching
21 * @package acm
23 class acm
25 private $vars = array();
26 private $var_expires = array();
27 private $is_modified = false;
29 public $sql_rowset = array();
30 public $cache_dir = '';
32 /**
33 * Set cache path
35 function __construct()
37 $this->cache_dir = PHPBB_ROOT_PATH . 'cache/';
40 /**
41 * Load global cache
43 private function load()
45 // grab the global cache
46 if (file_exists($this->cache_dir . 'data_global.' . PHP_EXT))
48 @include($this->cache_dir . 'data_global.' . PHP_EXT);
49 return true;
52 return false;
55 /**
56 * Unload cache object
58 public function unload()
60 $this->save();
61 unset($this->vars);
62 unset($this->var_expires);
63 unset($this->sql_rowset);
65 $this->vars = array();
66 $this->var_expires = array();
67 $this->sql_rowset = array();
70 /**
71 * Save modified objects
73 private function save()
75 if (!$this->is_modified)
77 return;
80 if ($fp = @fopen($this->cache_dir . 'data_global.' . PHP_EXT, 'wb'))
82 @flock($fp, LOCK_EX);
83 fwrite($fp, "<?php\n\$this->vars = unserialize(" . var_export(serialize($this->vars), true) . ");\n\$this->var_expires = unserialize(" . var_export(serialize($this->var_expires), true) . ");");
84 @flock($fp, LOCK_UN);
85 fclose($fp);
87 if (!function_exists('phpbb_chmod'))
89 include(PHPBB_ROOT_PATH . 'includes/functions.' . PHP_EXT);
92 phpbb_chmod($this->cache_dir . 'data_global.' . PHP_EXT, phpbb::CHMOD_WRITE);
94 else
96 // Now, this occurred how often? ... phew, just tell the user then...
97 if (!@is_writable($this->cache_dir))
99 trigger_error($this->cache_dir . ' is NOT writable.', E_USER_ERROR);
102 trigger_error('Not able to open ' . $this->cache_dir . 'data_global.' . PHP_EXT, E_USER_ERROR);
105 $this->is_modified = false;
109 * Tidy cache
111 public function tidy()
113 $dir = @opendir($this->cache_dir);
115 if (!$dir)
117 return;
120 while (($entry = readdir($dir)) !== false)
122 if (!preg_match('/^(sql_|data_(?!global))/', $entry))
124 continue;
127 $expired = true;
128 @include($this->cache_dir . $entry);
129 if ($expired)
131 $this->remove_file($this->cache_dir . $entry);
134 closedir($dir);
136 if (file_exists($this->cache_dir . 'data_global.' . PHP_EXT))
138 if (!sizeof($this->vars))
140 $this->load();
143 foreach ($this->var_expires as $var_name => $expires)
145 if (time() > $expires)
147 $this->destroy($var_name);
152 set_config('cache_last_gc', time(), true);
156 * Get saved cache object
158 public function get($var_name)
160 if ($var_name[0] === '_')
162 if (!$this->_exists($var_name))
164 return false;
167 @include($this->cache_dir . "data{$var_name}." . PHP_EXT);
168 return (isset($data)) ? $data : false;
170 else
172 return ($this->_exists($var_name)) ? $this->vars[$var_name] : false;
177 * Put data into cache
179 function put($var_name, $var, $ttl = 31536000)
181 if ($var_name[0] === '_')
183 if ($fp = @fopen($this->cache_dir . "data{$var_name}." . PHP_EXT, 'wb'))
185 @flock($fp, LOCK_EX);
186 fwrite($fp, "<?php\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n\$data = " . (sizeof($var) ? "unserialize(" . var_export(serialize($var), true) . ");" : 'array();'));
187 @flock($fp, LOCK_UN);
188 fclose($fp);
190 if (!function_exists('phpbb_chmod'))
192 include(PHPBB_ROOT_PATH . 'includes/functions.' . PHP_EXT);
195 phpbb_chmod($this->cache_dir . "data{$var_name}." . PHP_EXT, phpbb::CHMOD_WRITE);
198 else
200 $this->vars[$var_name] = $var;
201 $this->var_expires[$var_name] = time() + $ttl;
202 $this->is_modified = true;
207 * Purge cache data
209 public function purge()
211 // Purge all phpbb cache files
212 $dir = @opendir($this->cache_dir);
214 if (!$dir)
216 return;
219 while (($entry = readdir($dir)) !== false)
221 if (strpos($entry, 'sql_') !== 0 && strpos($entry, 'data_') !== 0 && strpos($entry, 'ctpl_') !== 0 && strpos($entry, 'tpl_') !== 0)
223 continue;
226 $this->remove_file($this->cache_dir . $entry);
228 closedir($dir);
230 unset($this->vars);
231 unset($this->var_expires);
232 unset($this->sql_rowset);
234 $this->vars = array();
235 $this->var_expires = array();
236 $this->sql_rowset = array();
238 $this->is_modified = false;
242 * Destroy cache data
244 public function destroy($var_name, $table = '')
246 if ($var_name === 'sql' && !empty($table))
248 if (!is_array($table))
250 $table = array($table);
253 $dir = @opendir($this->cache_dir);
255 if (!$dir)
257 return;
260 while (($entry = readdir($dir)) !== false)
262 if (strpos($entry, 'sql_') !== 0)
264 continue;
267 // The following method is more failproof than simply assuming the query is on line 3 (which it should be)
268 $check_line = @file_get_contents($this->cache_dir . $entry);
270 if (empty($check_line))
272 continue;
275 // Now get the contents between /* and */
276 $check_line = substr($check_line, strpos($check_line, '/* ') + 3, strpos($check_line, ' */') - strpos($check_line, '/* ') - 3);
278 $found = false;
279 foreach ($table as $check_table)
281 // Better catch partial table names than no table names. ;)
282 if (strpos($check_line, $check_table) !== false)
284 $found = true;
285 break;
289 if ($found)
291 $this->remove_file($this->cache_dir . $entry);
294 closedir($dir);
296 return;
299 if (!$this->_exists($var_name))
301 return;
304 if ($var_name[0] === '_')
306 $this->remove_file($this->cache_dir . 'data' . $var_name . '.' . PHP_EXT, true);
308 else if (isset($this->vars[$var_name]))
310 $this->is_modified = true;
311 unset($this->vars[$var_name]);
312 unset($this->var_expires[$var_name]);
314 // We save here to let the following cache hits succeed
315 $this->save();
320 * Check if a given cache entry exist
322 private function _exists($var_name)
324 if ($var_name[0] === '_')
326 return file_exists($this->cache_dir . 'data' . $var_name . '.' . PHP_EXT);
328 else
330 if (!sizeof($this->vars))
332 $this->load();
335 if (!isset($this->var_expires[$var_name]))
337 return false;
340 return (time() > $this->var_expires[$var_name]) ? false : isset($this->vars[$var_name]);
345 * Load cached sql query
347 public function sql_load($query)
349 // Remove extra spaces and tabs
350 $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
351 $query_id = sizeof($this->sql_rowset);
353 if (!file_exists($this->cache_dir . 'sql_' . md5($query) . '.' . PHP_EXT))
355 return false;
358 @include($this->cache_dir . 'sql_' . md5($query) . '.' . PHP_EXT);
360 if (!isset($expired))
362 return false;
364 else if ($expired)
366 $this->remove_file($this->cache_dir . 'sql_' . md5($query) . '.' . PHP_EXT, true);
367 return false;
371 return $query_id;
375 * Save sql query
377 public function sql_save($query, &$query_result, $ttl)
379 global $db;
381 // Remove extra spaces and tabs
382 $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
383 $filename = $this->cache_dir . 'sql_' . md5($query) . '.' . PHP_EXT;
385 if ($fp = @fopen($filename, 'wb'))
387 @flock($fp, LOCK_EX);
389 $query_id = sizeof($this->sql_rowset);
390 $this->sql_rowset[$query_id] = array();
392 while ($row = $db->sql_fetchrow($query_result))
394 $this->sql_rowset[$query_id][] = $row;
396 $db->sql_freeresult($query_result);
398 $file = "<?php\n/* " . str_replace('*/', '*\/', $query) . " */";
399 $file .= "\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n";
401 fwrite($fp, $file . "\$this->sql_rowset[\$query_id] = " . (sizeof($this->sql_rowset[$query_id]) ? "unserialize(" . var_export(serialize($this->sql_rowset[$query_id]), true) . ");" : 'array();'));
402 @flock($fp, LOCK_UN);
403 fclose($fp);
405 if (!function_exists('phpbb_chmod'))
407 include(PHPBB_ROOT_PATH . 'includes/functions.' . PHP_EXT);
410 phpbb_chmod($filename, phpbb::CHMOD_WRITE);
412 $query_result = $query_id;
417 * Fetch row from cache (database)
419 public function sql_fetchrow($query_id)
421 list(, $row) = each($this->sql_rowset[$query_id]);
423 return ($row !== NULL) ? $row : false;
427 * Fetch a field from the current row of a cached database result (database)
429 public function sql_fetchfield($query_id, $field)
431 $row = current($this->sql_rowset[$query_id]);
433 return ($row !== false && isset($row[$field])) ? $row[$field] : false;
437 * Free memory used for a cached database result (database)
439 public function sql_freeresult($query_id)
441 if (!isset($this->sql_rowset[$query_id]))
443 return false;
446 unset($this->sql_rowset[$query_id]);
448 return true;
452 * Removes/unlinks file
454 private function remove_file($filename, $check = false)
456 if ($check && !@is_writable($this->cache_dir))
458 // E_USER_ERROR - not using language entry - intended.
459 trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
462 return @unlink($filename);