initial commit

This commit is contained in:
Chris Sewell
2012-11-28 03:55:08 -05:00
parent 7adb399b2e
commit cf140a2e97
3247 changed files with 492437 additions and 0 deletions

118
lib/symfony/cache/sfCache.class.php vendored Executable file
View File

@ -0,0 +1,118 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfCache is an abstract class for all cache classes in symfony.
*
* @package symfony
* @subpackage cache
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Fabien Marty <fab@php.net>
* @version SVN: $Id: sfCache.class.php 3198 2007-01-08 20:36:20Z fabien $
*/
abstract class sfCache
{
/**
* Cache lifetime (in seconds)
*
* @var int $lifeTime
*/
protected $lifeTime = 86400;
/**
* Timestamp of the last valid cache
*
* @var int $refreshTime
*/
protected $refreshTime;
/**
* Gets the cache content for a given id and namespace.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param boolean If set to true, the cache validity won't be tested
*
* @return string The data of the cache (or null if no cache available)
*/
abstract public function get($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false);
/**
* Returns true if there is a cache for the given id and namespace.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param boolean If set to true, the cache validity won't be tested
*
* @return boolean true if the cache exists, false otherwise
*/
abstract public function has($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false);
/**
* Saves some data in the cache.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param string The data to put in cache
*
* @return boolean true if no problem
*/
abstract public function set($id, $namespace = self::DEFAULT_NAMESPACE, $data);
/**
* Removes a content from the cache.
*
* @param string The cache id
* @param string The name of the cache namespace
*
* @return boolean true if no problem
*/
abstract public function remove($id, $namespace = self::DEFAULT_NAMESPACE);
/**
* Cleans the cache.
*
* If no namespace is specified all cache content will be destroyed
* else only cache contents of the specified namespace will be destroyed.
*
* @param string The name of the cache namespace
*
* @return boolean true if no problem
*/
abstract public function clean($namespace = null, $mode = 'all');
/**
* Sets a new life time.
*
* @param int The new life time (in seconds)
*/
public function setLifeTime($newLifeTime)
{
$this->lifeTime = $newLifeTime;
$this->refreshTime = time() - $newLifeTime;
}
/**
* Returns the current life time.
*
* @return int The current life time (in seconds)
*/
public function getLifeTime()
{
return $this->lifeTime;
}
/**
* Returns the cache last modification time.
*
* @return int The last modification time
*/
abstract public function lastModified($id, $namespace = self::DEFAULT_NAMESPACE);
}

601
lib/symfony/cache/sfFileCache.class.php vendored Executable file
View File

@ -0,0 +1,601 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Cache class that stores content in files.
*
* This class is based on the PEAR_Cache_Lite class.
* All cache files are stored in files in the [sf_root_dir].'/cache/'.[sf_app].'/template' directory.
* To disable all caching, you can set to false [sf_cache] setting.
*
* @package symfony
* @subpackage cache
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Fabien Marty <fab@php.net>
* @version SVN: $Id: sfFileCache.class.php 5308 2007-09-29 06:51:43Z fabien $
*/
class sfFileCache extends sfCache
{
const DEFAULT_NAMESPACE = '';
/**
* Directory where to put the cache files
*/
protected $cacheDir = '';
/**
* Enable / disable fileLocking (can avoid cache corruption under bad circumstances)
* @var boolean $fileLocking
*/
protected $fileLocking = true;
/**
* Enable / disable write control (the cache is read just after writing to detect corrupt entries)
*
* Enable write control will lightly slow the cache writing but not the cache reading
* Write control can detect some corrupt cache files but maybe it's not a perfect control
*/
protected $writeControl = false;
/**
* Enable / disable read control
*
* If enabled, a control key is embeded in cache file and this key is compared with the one calculated after the reading.
*/
protected $readControl = false;
/**
* File Name protection
*
* if set to true, you can use any cache id or namespace name
* if set to false, it can be faster but cache ids and namespace names
* will be used directly in cache file names so be carefull with
* special characters...
*/
protected $fileNameProtection = false;
/**
* Disable / Tune the automatic cleaning process
*
* The automatic cleaning process destroy too old (for the given life time)
* cache files when a new cache file is written.
* 0 => no automatic cache cleaning
* 1 => systematic cache cleaning
* x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
*/
protected $automaticCleaningFactor = 500;
/**
* Nested directory level
*/
protected $hashedDirectoryLevel = 0;
/**
* Cache suffix
*/
protected
$suffix = '.cache';
/**
* Constructor.
*
* @param string The cache root directory
*/
public function __construct($cacheDir = null)
{
$this->setCacheDir($cacheDir);
}
/**
* Initializes the cache.
*
* @param array An array of options
* Available options:
* - cacheDir: cache root directory
* - fileLocking: enable / disable file locking (boolean)
* - writeControl: enable / disable write control (boolean)
* - readControl: enable / disable read control (boolean)
* - fileNameProtection: enable / disable automatic file name protection (boolean)
* - automaticCleaningFactor: disable / tune automatic cleaning process (int)
* - hashedDirectoryLevel: level of the hashed directory system (int)
* - lifeTime: default life time
*
*/
public function initialize($options = array())
{
if (isset($options['cacheDir']))
{
$this->setCacheDir($options['cacheDir']);
unset($options['cacheDir']);
}
$availableOptions = array('fileLocking', 'writeControl', 'readControl', 'fileNameProtection', 'automaticCleaningFactor', 'hashedDirectoryLevel', 'lifeTime');
foreach ($options as $key => $value)
{
if (!in_array($key, $availableOptions) && sfConfig::get('sf_logging_enabled'))
{
sfLogger::getInstance()->err(sprintf('sfFileCache cannot take "%s" as an option', $key));
}
$this->$key = $value;
}
}
/**
* Sets the suffix for cache files.
*
* @param string The suffix name (with the leading .)
*/
public function setSuffix($suffix)
{
$this->suffix = $suffix;
}
/**
* Enables / disables write control.
*
* @param boolean
*/
public function setWriteControl($boolean)
{
$this->writeControl = $boolean;
}
/**
* Gets the value of the writeControl option.
*
* @return boolean
*/
public function getWriteControl()
{
return $this->writeControl;
}
/**
* Enables / disables file locking.
*
* @param boolean
*/
public function setFileLocking($boolean)
{
$this->fileLocking = $boolean;
}
/**
* Gets the value of the fileLocking option.
*
* @return boolean
*/
public function getFileLocking()
{
return $this->fileLocking;
}
/**
* Sets the cache root directory.
*
* @param string The directory where to put the cache files
*/
public function setCacheDir($cacheDir)
{
// remove last DIRECTORY_SEPARATOR
if (DIRECTORY_SEPARATOR == substr($cacheDir, -1))
{
$cacheDir = substr($cacheDir, 0, -1);
}
// create cache dir if needed
if (!is_dir($cacheDir))
{
$current_umask = umask(0000);
@mkdir($cacheDir, 0777, true);
umask($current_umask);
}
$this->cacheDir = $cacheDir;
}
public function getCacheDir()
{
return $this->cacheDir;
}
/**
* Tests if a cache is available and (if yes) returns it.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param boolean If set to true, the cache validity won't be tested
*
* @return string Data of the cache (or null if no cache available)
*
* @see sfCache
*/
public function get($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false)
{
$data = null;
list($path, $file) = $this->getFileName($id, $namespace);
if ($doNotTestCacheValidity)
{
if (file_exists($path.$file))
{
$data = $this->read($path, $file);
}
}
else
{
if ((file_exists($path.$file)) && (@filemtime($path.$file) > $this->refreshTime))
{
$data = $this->read($path, $file);
}
}
return $data ? $data : null;
}
/**
* Returns true if there is a cache for the given id and namespace.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param boolean If set to true, the cache validity won't be tested
*
* @return boolean true if the cache exists, false otherwise
*
* @see sfCache
*/
public function has($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false)
{
list($path, $file) = $this->getFileName($id, $namespace);
if ($doNotTestCacheValidity)
{
if (file_exists($path.$file))
{
return true;
}
}
else
{
if ((file_exists($path.$file)) && (@filemtime($path.$file) > $this->refreshTime))
{
return true;
}
}
return false;
}
/**
* Saves some data in a cache file.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param string The data to put in cache
*
* @return boolean true if no problem
*
* @see sfCache
*/
public function set($id, $namespace = self::DEFAULT_NAMESPACE, $data)
{
list($path, $file) = $this->getFileName($id, $namespace);
if ($this->automaticCleaningFactor > 0)
{
$rand = rand(1, $this->automaticCleaningFactor);
if ($rand == 1)
{
$this->clean(false, 'old');
}
}
if ($this->writeControl)
{
return $this->writeAndControl($path, $file, $data);
}
else
{
return $this->write($path, $file, $data);
}
}
/**
* Removes a cache file.
*
* @param string The cache id
* @param string The name of the cache namespace
*
* @return boolean true if no problem
*/
public function remove($id, $namespace = self::DEFAULT_NAMESPACE)
{
list($path, $file) = $this->getFileName($id, $namespace);
return $this->unlink($path.$file);
}
/**
* Cleans the cache.
*
* If no namespace is specified all cache files will be destroyed
* else only cache files of the specified namespace will be destroyed.
*
* @param string The name of the cache namespace
*
* @return boolean true if no problem
*/
public function clean($namespace = null, $mode = 'all')
{
$namespace = str_replace('/', DIRECTORY_SEPARATOR, $namespace);
$dir = $this->cacheDir.DIRECTORY_SEPARATOR.$namespace;
if (!file_exists($dir))
{
return true;
}
return $this->cleanDir($dir, $mode);
}
/**
* Returns the cache last modification time.
*
* @return int The last modification time
*/
public function lastModified($id, $namespace = self::DEFAULT_NAMESPACE)
{
list($path, $file) = $this->getFileName($id, $namespace);
return (file_exists($path.$file) ? filemtime($path.$file) : 0);
}
/**
* Makes a file name (with path).
*
* @param string The cache id
* @param string The name of the namespace
*
* @return array An array containing the path and the file name
*/
protected function getFileName($id, $namespace)
{
$file = ($this->fileNameProtection) ? md5($id).$this->suffix : $id.$this->suffix;
if ($namespace)
{
$namespace = str_replace('/', DIRECTORY_SEPARATOR, $namespace);
$path = $this->cacheDir.DIRECTORY_SEPARATOR.$namespace.DIRECTORY_SEPARATOR;
}
else
{
$path = $this->cacheDir.DIRECTORY_SEPARATOR;
}
if ($this->hashedDirectoryLevel > 0)
{
$hash = md5($file);
for ($i = 0; $i < $this->hashedDirectoryLevel; $i++)
{
$path = $path.substr($hash, 0, $i + 1).DIRECTORY_SEPARATOR;
}
}
return array($path, $file);
}
/**
* Removes a file.
*
* @param string The complete file path and name
*
* @return boolean true if no problem
*/
protected function unlink($file)
{
return @unlink($file) ? true : false;
}
/**
* Recursive function for cleaning cache file in the given directory.
*
* @param string The directory complete path
* @param string The name of the cache namespace
* @param string The flush cache mode : 'old', 'all'
*
* @return boolean true if no problem
*
* @throws sfCacheException
*/
protected function cleanDir($dir, $mode)
{
if (!($dh = opendir($dir)))
{
throw new sfCacheException('Unable to open cache directory "'.$dir.'"');
}
$result = true;
while ($file = readdir($dh))
{
if (($file != '.') && ($file != '..'))
{
$file2 = $dir.DIRECTORY_SEPARATOR.$file;
if (is_file($file2))
{
$unlink = 1;
if ($mode == 'old')
{
// files older than lifeTime get deleted from cache
if ((time() - filemtime($file2)) < $this->lifeTime)
{
$unlink = 0;
}
}
if ($unlink)
{
$result = ($result and ($this->unlink($file2)));
}
}
else if (is_dir($file2))
{
$result = ($result and ($this->cleanDir($file2.DIRECTORY_SEPARATOR, $mode)));
}
}
}
return $result;
}
/**
* Reads the cache file and returns the content.
*
* @param string The file path
* @param string The file name
*
* @return string The content of the cache file.
*
* @throws sfCacheException
*/
protected function read($path, $file)
{
$fp = @fopen($path.$file, "rb");
if ($this->fileLocking)
{
@flock($fp, LOCK_SH);
}
if ($fp)
{
clearstatcache(); // because the filesize can be cached by PHP itself...
$length = @filesize($path.$file);
$mqr = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
if ($this->readControl)
{
$hashControl = @fread($fp, 32);
$length = $length - 32;
}
$data = ($length) ? @fread($fp, $length) : '';
set_magic_quotes_runtime($mqr);
if ($this->fileLocking)
{
@flock($fp, LOCK_UN);
}
@fclose($fp);
if ($this->readControl)
{
$hashData = $this->hash($data);
if ($hashData != $hashControl)
{
@touch($path.$file, time() - 2 * abs($this->lifeTime));
return false;
}
}
return $data;
}
throw new sfCacheException('Unable to read cache file "'.$path.$file.'"');
}
/**
* Writes the given data in the cache file.
*
* @param string The file path
* @param string The file name
* @param string The data to put in cache
*
* @return boolean true if ok
*
* @throws sfCacheException
*/
protected function write($path, $file, $data)
{
$try = 1;
while ($try <= 2)
{
$fp = @fopen($path.$file, 'wb');
if ($fp)
{
if ($this->fileLocking)
{
@flock($fp, LOCK_EX);
}
if ($this->readControl)
{
@fwrite($fp, $this->hash($data), 32);
}
@fwrite($fp, $data);
if ($this->fileLocking)
{
@flock($fp, LOCK_UN);
}
@fclose($fp);
// change file mode
$current_umask = umask();
umask(0000);
chmod($path.$file, 0666);
umask($current_umask);
return true;
}
else
{
if ($try == 1 && !is_dir($path))
{
// create directory structure if needed
$current_umask = umask(0000);
mkdir($path, 0777, true);
umask($current_umask);
$try = 2;
}
else
{
$try = 999;
}
}
}
throw new sfCacheException('Unable to write cache file "'.$path.$file.'"');
}
/**
* Writes the given data in the cache file and controls it just after to avoid corrupted cache entries.
*
* @param string The file path
* @param string The file name
* @param string The data to put in cache
*
* @return boolean true if the test is ok
*/
protected function writeAndControl($path, $file, $data)
{
$this->write($path, $file, $data);
$dataRead = $this->read($path, $file);
return ($dataRead == $data);
}
/**
* Makes a control key with the string containing datas.
*
* @param string $data data
*
* @return string control key
*/
protected function hash($data)
{
return sprintf('% 32d', crc32($data));
}
}

102
lib/symfony/cache/sfFunctionCache.class.php vendored Executable file
View File

@ -0,0 +1,102 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* This class can be used to cache the result and output of functions/methods.
*
* This class is based on the PEAR_Cache_Lite class.
* All cache files are stored in files in the [sf_root_dir].'/cache/'.[sf_app].'/function' directory.
* To disable all caching, you can set to false [sf_cache] constant.
*
* @package symfony
* @subpackage cache
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Fabien Marty <fab@php.net>
* @version SVN: $Id: sfFunctionCache.class.php 3452 2007-02-14 15:03:08Z francois $
*/
class sfFunctionCache extends sfFileCache
{
/**
* Calls a cacheable function or method (or not if there is already a cache for it).
*
* Arguments of this method are read with func_get_args. So it doesn't appear in the function definition. Synopsis :
* call('functionName', $arg1, $arg2, ...)
* (arg1, arg2... are arguments of 'functionName')
*
* @return mixed The result of the function/method
*/
public function call()
{
$arguments = func_get_args();
// Generate a cache id
$id = md5(serialize($arguments));
$data = $this->get($id);
if ($data !== null)
{
$array = unserialize($data);
$output = $array['output'];
$result = $array['result'];
}
else
{
$target = array_shift($arguments);
ob_start();
ob_implicit_flush(false);
if (is_string($target) && strstr($target, '::'))
{
// classname::staticMethod
list($class, $method) = explode('::', $target);
try
{
$result = call_user_func_array(array($class, $method), $arguments);
}
catch (Exception $e)
{
ob_end_clean();
throw $e;
}
}
else if (is_string($target) && strstr($target, '->'))
{
// object->method
// use a stupid name ($objet_123456789 because) of problems when the object
// name is the same as this var name
list($object_123456789, $method) = explode('->', $target);
global $$object_123456789;
try
{
$result = call_user_func_array(array($$object_123456789, $method), $arguments);
}
catch (Exception $e)
{
ob_end_clean();
throw $e;
}
}
else
{
// function
$result = call_user_func_array($target, $arguments);
}
$output = ob_get_contents();
ob_end_clean();
$array['output'] = $output;
$array['result'] = $result;
$this->set($id, '', serialize($array));
}
echo($output);
return $result;
}
}

171
lib/symfony/cache/sfProcessCache.class.php vendored Executable file
View File

@ -0,0 +1,171 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfProcessCache stores content in memory if you run a PHP accelerator.
*
* Current PHP accelerator supported: APC, XCache and Eaccelerator.
*
* @package symfony
* @subpackage cache
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id$
*/
class sfProcessCache
{
/**
* Gets the cache engine name or false if no PHP accelerator is enabled.
*
* @return string The cache engine name
*/
public static function cacher()
{
static $cacher = null;
if (null === $cacher)
{
if (!sfConfig::get('sf_use_process_cache'))
{
$cacher = false;
}
elseif (function_exists('apc_store'))
{
$cacher = 'apc';
}
elseif (function_exists('xcache_set'))
{
$cacher = 'xcache';
}
elseif (function_exists('ecacher_put'))
{
$cacher = 'eaccelerator';
}
else
{
$cacher = false;
}
}
return $cacher;
}
/**
* Gets the prefix to use for all key name.
*
* @return string The prefix string
*/
public static function getPrefix()
{
static $prefix = null;
if (!$prefix)
{
$prefix = md5(sfConfig::get('sf_app_dir')).'_';
}
return $prefix;
}
/**
* Sets a value in the cache for the specified key.
*
* @param string The key name
* @param string The content to put in cache
* @param int The life time to keep the content in the cache
*
* @return boolean true if ok
*/
public static function set($key, $value, $lifeTime = 0)
{
switch (self::cacher())
{
case 'apc':
return apc_store(self::getPrefix().$key, $value, $lifeTime);
case 'xcache':
return xcache_set(self::getPrefix().$key, $value, $lifeTime);
case 'eaccelerator':
return eaccelerator_put(self::getPrefix().$key, serialize($value), $lifeTime);
}
return false;
}
/**
* Gets a value in the cache for the specified key.
*
* @param string The key name
*
* @return mixed The content associated with the key or null if the key does not exist
*/
public static function get($key)
{
switch (self::cacher())
{
case 'apc':
$value = apc_fetch(self::getPrefix().$key);
return false === $value ? null : $value;
case 'xcache':
return xcache_isset(self::getPrefix().$key) ? xcache_get(self::getPrefix().$key) : null;
case 'eaccelerator':
return unserialize(eaccelerator_get(self::getPrefix().$key));
}
return null;
}
/**
* Returns true if a given key exists in the cache, false otherwise.
*
* @param string The key name
*
* @return boolean true if the key exists, false otherwise
*/
public static function has($key)
{
switch (self::cacher())
{
case 'apc':
return false === apc_fetch(self::getPrefix().$key) ? false : true;
case 'xcache':
return xcache_isset(self::getPrefix().$key);
case 'eaccelerator':
return null === eaccelerator_get(self::getPrefix().$key) ? false : true;
}
return false;
}
/**
* Clears the cache.
*
* @return boolean true if ok, false otherwise
*/
public static function clear()
{
switch (self::cacher())
{
case 'apc':
return apc_clear_cache('user');
case 'xcache':
for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++)
{
if (!xcache_clear_cache(XC_TYPE_VAR, $i))
{
return false;
}
}
return true;
case 'eaccelerator':
eaccelerator_clean();
}
return false;
}
}

317
lib/symfony/cache/sfSQLiteCache.class.php vendored Executable file
View File

@ -0,0 +1,317 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Cache class that stores content in a sqlite database.
*
* @package symfony
* @subpackage cache
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfSQLiteCache.class.php 3935 2007-05-06 10:07:08Z fabien $
*/
class sfSQLiteCache extends sfCache
{
const DEFAULT_NAMESPACE = '';
protected $conn = null;
/**
* File where to put the cache database (or :memory: to store cache in memory)
*/
protected $database = '';
/**
* Disable / Tune the automatic cleaning process
*
* The automatic cleaning process destroy too old (for the given life time)
* cache files when a new cache file is written.
* 0 => no automatic cache cleaning
* 1 => systematic cache cleaning
* x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
*/
protected $automaticCleaningFactor = 500;
/**
* Constructor.
*
* @param string The database name
*/
public function __construct($database = null)
{
if (!extension_loaded('sqlite'))
{
throw new sfConfigurationException('sfSQLiteCache class needs "sqlite" extension');
}
$this->setDatabase($database);
}
/**
* Initializes the cache.
*
* @param array An array of options
* Available options:
* - database: database name
* - automaticCleaningFactor: disable / tune automatic cleaning process (int)
*
*/
public function initialize($options = array())
{
if (isset($options['database']))
{
$this->setDatabase($options['database']);
unset($options['database']);
}
$availableOptions = array('automaticCleaningFactor');
foreach ($options as $key => $value)
{
if (!in_array($key, $availableOptions) && sfConfig::get('sf_logging_enabled'))
{
sfLogger::getInstance()->err(sprintf('sfSQLiteCache cannot take "%s" as an option', $key));
}
$this->$key = $value;
}
}
/**
* Sets the database name.
*
* @param string The database name where to store the cache
*/
public function setDatabase($database)
{
if (!$database)
{
return;
}
$this->database = $database;
$new = false;
if (':memory:' == $database)
{
$new = true;
}
elseif (!is_file($database))
{
$new = true;
// create cache dir if needed
$dir = dirname($database);
$current_umask = umask(0000);
if (!is_dir($dir))
{
@mkdir($dir, 0777, true);
}
touch($database);
umask($current_umask);
}
if (!($this->conn = @sqlite_open($this->database, 0644, $errmsg)))
{
throw new sfException(sprintf("Unable to connect to SQLite database: %s", $errmsg));
}
if ($new)
{
$this->createSchema();
}
}
/**
* Creates the database schema.
*
* @throws sfException
*/
protected function createSchema()
{
$statements = array(
"CREATE TABLE [cache] (
[id] VARCHAR(255),
[namespace] VARCHAR(255),
[data] LONGVARCHAR,
[created_at] TIMESTAMP
)",
"CREATE UNIQUE INDEX [cache_unique] ON [cache] ([namespace], [id])",
);
foreach ($statements as $statement)
{
if (!sqlite_query($statement, $this->conn))
{
throw new sfException(sqlite_error_string(sqlite_last_error($this->database)));
}
}
}
/**
* Destructor.
*/
public function __destruct()
{
sqlite_close($this->conn);
}
/**
* Gets the database name.
*
* @return string The database name
*/
public function getDatabase()
{
return $this->database;
}
/**
* Tests if a cache is available and (if yes) returns it.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param boolean If set to true, the cache validity won't be tested
*
* @return string The data in the cache (or null if no cache available)
*
* @see sfCache
*/
public function get($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false)
{
$statement = sprintf("SELECT data FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace));
if (!$doNotTestCacheValidity)
{
$statement .= sprintf(" AND created_at > '%s'", sqlite_escape_string($this->refreshTime));
}
$rs = sqlite_query($statement, $this->conn);
return sqlite_num_rows($rs) ? sqlite_fetch_single($rs) : null;
}
/**
* Returns true if there is a cache for the given id and namespace.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param boolean If set to true, the cache validity won't be tested
*
* @return boolean true if the cache exists, false otherwise
*
* @see sfCache
*/
public function has($id, $namespace = self::DEFAULT_NAMESPACE, $doNotTestCacheValidity = false)
{
$statement = sprintf("SELECT id FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace));
if (!$doNotTestCacheValidity)
{
$statement .= sprintf(" AND created_at > '%s'", sqlite_escape_string($this->refreshTime));
}
return sqlite_num_rows(sqlite_query($statement, $this->conn)) ? true : false;
}
/**
* Saves some data in the cache.
*
* @param string The cache id
* @param string The name of the cache namespace
* @param string The data to put in cache
*
* @return boolean true if no problem
*
* @see sfCache
*/
public function set($id, $namespace = self::DEFAULT_NAMESPACE, $data)
{
if ($this->automaticCleaningFactor > 0)
{
$rand = rand(1, $this->automaticCleaningFactor);
if ($rand == 1)
{
$this->clean(false, 'old');
}
}
if (!$this->has($id, $namespace, true))
{
$statement = sprintf("INSERT INTO cache (id, namespace, data, created_at) VALUES ('%s', '%s', '%s', %d)", sqlite_escape_string($id), sqlite_escape_string($namespace), sqlite_escape_string($data), time());
}
else
{
$statement = sprintf("UPDATE cache SET data = '%s', created_at = %s WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($data), time(), sqlite_escape_string($id), sqlite_escape_string($namespace));
}
if (sqlite_query($statement, $this->conn))
{
return true;
}
return false;
}
/**
* Removes an element from the cache.
*
* @param string The cache id
* @param string The name of the cache namespace
*
* @return boolean true if no problem
*
* @see sfCache
*/
public function remove($id, $namespace = self::DEFAULT_NAMESPACE)
{
$statement = sprintf("DELETE FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace));
if (sqlite_query($statement, $this->conn))
{
return true;
}
return false;
}
/**
* Cleans the cache.
*
* If no namespace is specified all cache files will be destroyed
* else only cache files of the specified namespace will be destroyed.
*
* @param string The name of the cache namespace
*
* @return boolean true if no problem
*/
public function clean($namespace = null, $mode = 'all')
{
if (!$namespace)
{
$statement = "DELETE FROM cache";
}
else
{
$statement = sprintf("DELETE FROM cache WHERE namespace LIKE '%s%%'", $namespace);
}
if ('old' == $mode)
{
$statement .= sprintf(" %s created_at < '%s'", $namespace ? 'AND' : 'WHERE', sqlite_escape_string($this->refreshTime));
}
return sqlite_num_rows(sqlite_query($statement, $this->conn)) ? true : false;
}
public function lastModified($id, $namespace = self::DEFAULT_NAMESPACE)
{
$statement = sprintf("SELECT created_at FROM cache WHERE id = '%s' AND namespace = '%s'", sqlite_escape_string($id), sqlite_escape_string($namespace));
$rs = sqlite_query($statement, $this->conn);
return sqlite_num_rows($rs) ? intval(sqlite_fetch_single($rs)) : 0;
}
}