AvocadoAmber/AvocadoEdition_Light/lib/Cache/FileCache.class.php

199 lines
4.2 KiB
PHP
Raw Normal View History

2024-09-27 17:11:41 +09:00
<?php
if (!defined('_GNUBOARD_'))
exit;
class FileCache
{
/**
* The root cache directory.
* @var string
*/
protected $_cache_path = '/tmp/cache';
/** @var string */
protected $file_extension = '';
/**
* Creates a FileCache object
*
* @param array $options
*/
public function __construct($options = array())
{
$available_options = array('_cache_path', 'file_extension');
foreach ($available_options as $name) {
if (isset($options[$name])) {
$this->$name = $options[$name];
}
}
}
/**
* Fetches an entry from the cache.
*
* @param string $id
*/
public function get($id, $expired_time = 0)
{
$data = $this->_get($id, $expired_time);
return is_array($data) ? $data['data'] : FALSE;
}
protected function get_cache_file_path($id)
{
$id = str_replace(DIRECTORY_SEPARATOR, '/', $id);
$add_separator = '';
$add_file_extension = '';
if (strpos('/', $id) !== 0) {
$add_separator = '/';
}
$ext = pathinfo($id, PATHINFO_EXTENSION);
if (!(isset($ext['extension']) && $ext['extension'])) {
$add_file_extension = $this->file_extension;
}
return $this->_cache_path . $add_separator . $id . $add_file_extension;
}
protected function _get($id, $expired_time = 0)
{
$cache_file_path = $this->get_cache_file_path($id);
if (!is_file($cache_file_path)) {
return FALSE;
}
$server_time = defined('G5_SERVER_TIME') ? G5_SERVER_TIME : time();
try {
$file_contents = file_get_contents($cache_file_path);
$file_ex = explode("\n\n", $file_contents);
$data = unserialize(base64_decode($file_ex[1]));
} catch (Exception $e) {
$data = array('ttl' => 1, 'time' => $server_time - 1000);
}
if ($data['ttl'] > 0 && $server_time > $data['time'] + $data['ttl']) {
unlink($cache_file_path);
return FALSE;
}
if ($data['time'] && $expired_time && $data['time'] < ($server_time - $expired_time)) {
unlink($cache_file_path);
return FALSE;
}
return $data;
}
public function write_file($path, $data, $mode = 'wb')
{
if (!$fp = @fopen($path, $mode)) {
return FALSE;
}
flock($fp, LOCK_EX);
for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result) {
if (($result = fwrite($fp, substr($data, $written))) === FALSE) {
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
return is_int($result);
}
/**
* Deletes a cache entry.
*
* @param string $id
*
* @return bool
*/
public function delete($id)
{
$cache_file_path = $this->get_cache_file_path($id);
return file_exists($cache_file_path) ? unlink($cache_file_path) : FALSE;
}
/**
* Puts data into the cache.
*
* @param string $id
* @param mixed $data
* @param int $lifetime
*
* @return bool
*/
public function save($id, $data, $ttl = 60, $raw = FALSE)
{
$cache_file_path = $this->get_cache_file_path($id);
$contents = array(
'time' => time(),
'ttl' => $ttl,
'data' => $data
);
$cache_content = "<?php if (!defined('_GNUBOARD_')) exit; ?>\n\n";
$cache_content .= base64_encode(serialize($contents));
if ($this->write_file($cache_file_path, $cache_content)) {
chmod($cache_file_path, G5_FILE_PERMISSION);
return TRUE;
}
return FALSE;
}
/**
* Fetches a base directory to store the cache data
*
* @return string
*/
protected function getCacheDirectory()
{
return $this->_cache_path;
}
/**
* Encodes some data to a string so it can be written to disk
*
* @param mixed $data
* @param int $ttl
* @return string
*/
public function encode($data, $ttl)
{
$expire = null;
if ($ttl !== null) {
$expire = time() + $ttl;
}
return base64_encode(serialize(array($data, $expire)));
}
/**
* Decodes a string encoded by {@see encode()}
*
* Must returns a tuple (data, expire). Expire
* can be null to signal no expiration.
*
* @param string $data
* @return array (data, expire)
*/
public function decode($data)
{
return unserialize(base64_decode($data));
}
}