diff --git a/classes/cache/Cache.php b/classes/cache/Cache.php new file mode 100755 index 000000000..c1da488b7 --- /dev/null +++ b/classes/cache/Cache.php @@ -0,0 +1,80 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 6844 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +abstract class CacheCore +{ + /** @var Cache */ + protected static $_instance; + protected $_keysCached = array(); + protected $_tablesCached = array(); + protected $_blackList = array('cart', + 'cart_discount', + 'cart_product', + 'connections', + 'connections_source', + 'connections_page', + 'customer', + 'customer_group', + 'customized_data', + 'guest', + 'pagenotfound', + 'page_viewed'); + + /** + * @return Cache + */ + public static function getInstance() + { + if(!isset(self::$_instance)) + { + $caching_system = _PS_CACHING_SYSTEM_; + self::$_instance = new $caching_system(); + + } + return self::$_instance; + } + + protected function __construct() + { + } + + protected function isBlacklist($query) + { + foreach ($this->_blackList AS $find) + if (strpos($query, $find)) + return true; + return false; + } + + abstract public function get($key); + abstract public function delete($key, $timeout = 0); + abstract public function set($key, $value, $expire = 0); + abstract public function flush(); + abstract public function setQuery($query, $result); + abstract public function deleteQuery($query); + +} diff --git a/classes/cache/CacheFS.php b/classes/cache/CacheFS.php new file mode 100755 index 000000000..79cf66001 --- /dev/null +++ b/classes/cache/CacheFS.php @@ -0,0 +1,181 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 6844 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +class CacheFSCore extends Cache { + + protected $_depth; + + protected function __construct() + { + parent::__construct(); + $this->_init(); + } + + protected function _init() + { + $this->_depth = Db::getInstance()->getValue('SELECT value FROM '._DB_PREFIX_.'configuration WHERE name=\'PS_CACHEFS_DIRECTORY_DEPTH\'', false); + return $this->_setKeys(); + } + + public function set($key, $value, $expire = 0) + { + $path = $this->getPath(); + for ($i = 0; $i < $this->_depth; $i++) + $path .= $key[$i].'/'; + if (@file_put_contents($path.$key, serialize($value))) + { + $this->_keysCached[$key] = true; + return $key; + } + return false; + } + + public function setNumRows($key, $value, $expire = 0) + { + return $this->set($key.'_nrows', $value, $expire); + } + + public function getNumRows($key) + { + return $this->get($key.'_nrows'); + } + + public function get($key) + { + if (!isset($this->_keysCached[$key])) + return false; + $path = $this->getPath(); + for ($i = 0; $i < $this->_depth; $i++) + $path .= $key[$i].'/'; + if (!file_exists($path.$key)) + { + unset($this->_keysCached[$key]); + return false; + } + $file = file_get_contents($path.$key); + return unserialize($file); + } + + protected function _setKeys() + { + if (file_exists($this->getPath().'keysCached')) + { + $file = file_get_contents($this->getPath().'keysCached'); + $this->_keysCached = unserialize($file); + } + if (file_exists($this->getPath().'tablesCached')) + { + $file = file_get_contents($this->getPath().'tablesCached'); + $this->_tablesCached = unserialize($file); + } + return true; + } + + public function setQuery($query, $result) + { + $md5_query = md5($query); + if ($this->isBlacklist($query)) + return true; + $this->_setKeys(); + if (isset($this->_keysCached[$md5_query])) + return true; + $key = $this->set($md5_query, $result); + if (preg_match_all('/('._DB_PREFIX_.'[a-z_-]*)`?.*/i', $query, $res)) + foreach($res[1] AS $table) + if(!isset($this->_tablesCached[$table][$key])) + $this->_tablesCached[$table][$key] = true; + $this->_writeKeys(); + } + + public function delete($key, $timeout = 0) + { + $path = $this->getPath(); + if (!isset($this->_keysCached[$key])) + return; + for ($i = 0; $i < $this->_depth; $i++) + $path.=$key[$i].'/'; + if (!file_exists($path.$key)) + return true; + if (!unlink($path.$key)) + return false; + unset($this->_keysCached[$key]); + return true; + } + + public function deleteQuery($query) + { + $this->_setKeys(); + if (preg_match_all('/('._DB_PREFIX_.'[a-z_-]*)`?.*/i', $query, $res)) + foreach ($res[1] AS $table) + if (isset($this->_tablesCached[$table])) + { + foreach (array_keys($this->_tablesCached[$table]) AS $fsKey) + { + $this->delete($fsKey); + $this->delete($fsKey.'_nrows'); + } + unset($this->_tablesCached[$table]); + } + $this->_writeKeys(); + } + + public function flush() + { + } + + private function _writeKeys() + { + + @file_put_contents($this->getPath().'keysCached', serialize($this->_keysCached)); + @file_put_contents($this->getPath().'tablesCached', serialize($this->_tablesCached)); + } + + public static function deleteCacheDirectory() + { + Tools::deleteDirectory($this->getPath(), false); + } + + public static function createCacheDirectories($level_depth, $directory = false) + { + if (!$directory) + $directory = $this->getPath(); + $chars = '0123456789abcdefghijklmnopqrstuvwxyz'; + for ($i = 0; $i < strlen($chars); $i++) + { + $new_dir = $directory.$chars[$i].'/'; + if (mkdir($new_dir)) + if (chmod($new_dir, 0777)) + if ($level_depth - 1 > 0) + self::createCacheDirectories($level_depth - 1, $new_dir); + } + } + + protected function getPath() + { + return (defined('_PS_CACHEFS_DIRECTORY_') ? _PS_CACHEFS_DIRECTORY_ : dirname(__FILE__).'/../cache/cachefs/'); + } +} diff --git a/classes/cache/CacheMemcache.php b/classes/cache/CacheMemcache.php new file mode 100755 index 000000000..e3b98e343 --- /dev/null +++ b/classes/cache/CacheMemcache.php @@ -0,0 +1,174 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 6844 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +class CacheMemcacheCore extends Cache +{ + protected $_memcacheObj; + protected $_isConnected = false; + + protected function __construct() + { + parent::__construct(); + $this->connect(); + } + + public function connect() + { + $this->_memcacheObj = new Memcache(); + $servers = self::getMemcachedServers(); + if (!$servers) + return false; + foreach ($servers AS $server) + $this->_memcacheObj->addServer($server['ip'], $server['port'], $server['weight']); + + $this->_isConnected = true; + return $this->_setKeys(); + } + + public function set($key, $value, $expire = 0) + { + if (!$this->_isConnected) + return false; + if ($this->_memcacheObj->set($key, $value, 0, $expire)) + { + $this->_keysCached[$key] = true; + return $key; + } + } + + public function setNumRows($key, $value, $expire = 0) + { + return $this->set($key.'_nrows', $value, $expire); + } + + public function getNumRows($key) + { + return $this->get($key.'_nrows'); + } + + public function get($key) + { + if (!isset($this->_keysCached[$key])) + return false; + return $this->_memcacheObj->get($key); + } + + protected function _setKeys() + { + if (!$this->_isConnected) + return false; + $this->_keysCached = $this->_memcacheObj->get('keysCached'); + $this->_tablesCached = $this->_memcacheObj->get('tablesCached'); + + return true; + } + + public function setQuery($query, $result) + { + if (!$this->_isConnected) + return false; + if ($this->isBlacklist($query)) + return true; + $md5_query = md5($query); + $this->_setKeys(); + if (isset($this->_keysCached[$md5_query])) + return true; + $key = $this->set($md5_query, $result); + if(preg_match_all('/('._DB_PREFIX_.'[a-z_-]*)`?.*/i', $query, $res)) + foreach($res[1] AS $table) + if(!isset($this->_tablesCached[$table][$key])) + $this->_tablesCached[$table][$key] = true; + $this->_writeKeys(); + } + + public function delete($key, $timeout = 0) + { + if (!$this->_isConnected) + return false; + if (!empty($key) AND $this->_memcacheObj->delete($key, $timeout)) + unset($this->_keysCached[$key]); + } + + public function deleteQuery($query) + { + if (!$this->_isConnected) + return false; + $this->_setKeys(); + if (preg_match_all('/('._DB_PREFIX_.'[a-z_-]*)`?.*/i', $query, $res)) + foreach ($res[1] AS $table) + if (isset($this->_tablesCached[$table])) + { + foreach ($this->_tablesCached[$table] AS $memcachedKey => $foo) + { + $this->delete($memcachedKey); + $this->delete($memcachedKey.'_nrows'); + } + unset($this->_tablesCached[$table]); + } + $this->_writeKeys(); + } + + protected function close() + { + if (!$this->_isConnected) + return false; + return $this->_memcacheObj->close(); + } + + public function flush() + { + if(!$this->_isConnected) + return false; + if ($this->_memcacheObj->flush()) + return $this->_setKeys(); + return false; + } + + private function _writeKeys() + { + if (!$this->_isConnected) + return false; + $this->_memcacheObj->set('keysCached', $this->_keysCached, 0, 0); + $this->_memcacheObj->set('tablesCached', $this->_tablesCached, 0, 0); + $this->close(); + } + + public static function addServer($ip, $port, $weight) + { + return Db::getInstance()->Execute('INSERT INTO '._DB_PREFIX_.'memcached_servers (ip, port, weight) VALUES(\''.pSQL($ip).'\', '.(int)$port.', '.(int)$weight.')', false); + } + + public static function getMemcachedServers() + { + return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('SELECT * FROM '._DB_PREFIX_.'memcached_servers', true, false); + } + + public static function deleteServer($id_server) + { + return Db::getInstance()->Execute('DELETE FROM '._DB_PREFIX_.'memcached_servers WHERE id_memcached_server='.(int)$id_server); + } +}