Index: branches/5.1.x/core/kernel/utility/cache.php
===================================================================
--- branches/5.1.x/core/kernel/utility/cache.php	(revision 13170)
+++ branches/5.1.x/core/kernel/utility/cache.php	(revision 13171)
@@ -1,519 +1,520 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
 * the GNU General Public License, and as distributed it includes
 * or is derivative of works licensed under the GNU General Public License
 * or other free or open source software licenses.
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
 	defined('FULL_PATH') or die('restricted access!');
 
 	/**
 	 * Manager of all implemented caching handlers
 	 *
 	 */
 	class kCache extends kBase {
 
 		/**
 		 * Object of cache handler
 		 *
 		 * @var FakeCacheHandler
 		 */
 		var $_handler = null;
 
 		/**
 		 * Part of what we retrieve will be stored locally (per script run) not to bother memcache a lot
 		 *
 		 * @var Array
 		 */
 		var $_localStorage = Array ();
 
 		/**
 		 * What type of caching is being used
 		 *
 		 * @var int
 		 */
 		var $cachingType = CACHING_TYPE_NONE;
 
 		/**
 		 * Cache usage statistics (per script run)
 		 *
 		 * @var Array
 		 */
 		var $statistics = Array ();
 
 		/**
 		 * Debug cache usage
 		 *
 		 * @var bool
 		 */
 		var $debugCache = false;
 
 		/**
 		 * Displays cache usage statistics
 		 *
 		 * @var bool
 		 */
 		var $displayCacheStatistics = false;
 
 		function kCache()
 		{
 			parent::kBase();
 
 			// get cache handler class to use
 			if (array_key_exists('CacheHandler', $GLOBALS['vars']) && $GLOBALS['vars']['CacheHandler']) {
 				// for advanced users, who want to save one SQL on each page load
 				$handler_class = $GLOBALS['vars']['CacheHandler'] . 'CacheHandler';
 			}
 			else {
 				$handler_class = $this->Application->ConfigValue('CacheHandler') . 'CacheHandler';
 			}
 
 			// defined cache handler doen't exist -> use default
 			if (!class_exists($handler_class)) {
 				$handler_class = 'FakeCacheHandler';
 			}
 
 			$handler = new $handler_class();
 
 			if (!$handler->isWorking()) {
 				// defined cache handler is not working -> use default
 				trigger_error('Failed to initialize "<strong>' . $handler_class . '</strong>" caching handler.', E_USER_WARNING);
 
 				$handler = new FakeCacheHandler();
 			}
 			elseif ($this->Application->isDebugMode() && ($handler->cachingType == CACHING_TYPE_MEMORY)) {
 				$this->Application->Debugger->appendHTML('Memory Caching: "<strong>' . $handler_class . '</strong>"');
 			}
 
 			$this->_handler =& $handler;
 			$this->cachingType = $handler->cachingType;
 			$this->debugCache = $handler->cachingType == CACHING_TYPE_MEMORY && $this->Application->isDebugMode();
 			$this->displayCacheStatistics = defined('DBG_CACHE') && DBG_CACHE && $this->Application->isDebugMode();
 		}
 
 		/**
 		 * Returns caching type of current storage engine
 		 *
 		 * @return int
 		 */
 		function getCachingType()
 		{
 			return $this->cachingType;
 		}
 
 
 		/**
 		 * Stores value to cache
 		 *
 		 * @param string $name
 		 * @param mixed $value
 		 * @param int $expires cache record expiration time in seconds
 		 */
 		function setCache($name, $value, $expiration)
 		{
 			$name = $this->prepareKeyName($name);
 			$this->_localStorage[$name] = $value;
 
 			return $this->_handler->set($name, $value, $expiration);
 		}
 
 		/**
 		 * Returns value from cache
 		 *
 		 * @param string $name
 		 * @param bool $store_locally store data locally after retrieved
 		 * @param bool $replace_serials
 		 * @return mixed
 		 */
 		function getCache($name, $store_locally = true, $replace_serials = true)
 		{
 			$name = $this->prepareKeyName($name, $replace_serials);
 
 			if ($store_locally) {
 				if (array_key_exists($name, $this->_localStorage)) {
 					if ($this->displayCacheStatistics) {
 						$this->setStatistics($name, $this->_localStorage[$name]);
 					}
 
 					return $this->_localStorage[$name];
 				}
 			}
 
 			$res = $this->_handler->get($name);
 
 			if ($replace_serials && $this->debugCache) {
 				// don't display subsequent serial cache retrievals (ones, that are part of keys)
 				if (is_array($res)) {
 					$this->Application->Debugger->appendHTML('Restoring key "' . $name . '". Type: ' . gettype($res) . '.');
 				}
 				else {
 					$res_display = strip_tags($res);
 
 					if (strlen($res_display) > 200) {
 						$res_display = substr($res_display, 0, 50) . ' ...';
 					}
 
 					$this->Application->Debugger->appendHTML('Restoring key "' . $name . '" resulted [' . $res_display . ']');
 				}
 			}
 
 			if ($store_locally && ($res !== false)) {
 				$this->_localStorage[$name] = $res;
 
 				if ($this->displayCacheStatistics) {
 					$this->setStatistics($name, $res);
 				}
 			}
 
 			return $res;
 		}
 
 		/**
 		 * Deletes value from cache
 		 *
 		 * @param string $name
 		 * @return mixed
 		 */
 		function delete($name)
 		{
 			$name = $this->prepareKeyName($name);
 			unset($this->_localStorage[$name]);
 
 			return $this->_handler->delete($name);
 		}
 
 		/**
 		 * Reset's all memory cache at once
 		 */
 		function reset()
 		{
 			// don't check for enabled, because we maybe need to reset cache anyway
 			if ($this->cachingType == CACHING_TYPE_TEMPORARY) {
 				return ;
 			}
 
 			$site_key = $this->_cachePrefix(true);
 
 			$this->_handler->set($site_key, $this->_handler->get($site_key) + 1);
 		}
 
 		/**
 		 * Replaces serials and adds unique site prefix to cache variable name
 		 *
 		 * @param string $name
 		 * @param bool $replace_serials
 		 * @return string
 		 */
 		function prepareKeyName($name, $replace_serials = true)
 		{
 			if ($this->cachingType == CACHING_TYPE_TEMPORARY) {
 				return $name;
 			}
 
 			// replace serials in key name
 			if ($replace_serials && preg_match_all('/\[%(.*?)%\]/', $name, $regs)) {
 				// [%LangSerial%] - prefix-wide serial in case of any change in "lang" prefix
 				// [%LangIDSerial:5%] - one id-wide serial in case of data, associated with given id was changed
 				// [%CiIDSerial:ItemResourceId:5%] - foreign key-based serial in case of data, associated with given foreign key was changed
 				foreach ($regs[1] as $serial_name) {
 					$name = str_replace('[%' . $serial_name . '%]', '[' . $serial_name . '=' . $this->getCache($serial_name, true, false) . ']', $name);
 				}
 			}
 
 			// add site-wide prefix to key
 			return $this->_cachePrefix() . $name;
 		}
 
 		/**
 		 * Returns site-wide caching prefix
 		 *
 		 * @param bool $only_site_key_name
 		 * @return string
 		 */
 		function _cachePrefix($only_site_key_name = false)
 		{
 			// don't use SERVER_NAME here, because it may be cron, or command line request also
 			$site_key = 'site_serial:' . crc32(FULL_PATH);
 
 			if ($only_site_key_name) {
 				return $site_key;
 			}
 
 			$site_serial = $this->_handler->get($site_key);
 
 			if (!$site_serial) {
 				$site_serial = 1;
 				$this->_handler->set($site_key, $site_serial);
 			}
 
 			return "$site_key:$site_serial:";
 		}
 
 		function setStatistics($name, $found)
 		{
 			if (strpos($name, ']:') !== false) {
 				list ($cache_name, $name) = explode(']:', $name, 2);
 			}
 			else {
 				$cache_name = '-';
 			}
 
 			if (!array_key_exists($cache_name, $this->statistics)) {
 				$this->statistics[$cache_name] = Array ();
 			}
 
 			if (!array_key_exists($name, $this->statistics[$cache_name])) {
 				$this->statistics[$cache_name][$name] = Array ();
 			}
 
 			$status_key = $found ? 'found' : 'not_found';
 
 			if (!isset($this->statistics[$cache_name][$name][$status_key])) {
 				$this->statistics[$cache_name][$name][$status_key] = 0;
 			}
 
 			$this->statistics[$cache_name][$name][$status_key]++;
 		}
 
 		/**
 		 * Returns storage size in bytes
 		 *
 		 * @return int
 		 */
 		function getStorageSize()
 		{
 			return strlen( serialize($this->_localStorage) );
 		}
 
 		function printStatistics()
 		{
 			$cache_size = $this->getStorageSize();
 
 			$this->Application->Debugger->appendHTML('<strong>Cache Size:</strong> ' . formatSize($cache_size) . ' (' . $cache_size . ')');
 
 			foreach ($this->statistics as $cache_name => $cache_data) {
 				foreach ($cache_data as $key => $value) {
 					if (!array_key_exists('found', $value) || $value['found'] == 1) {
 						// remove cached records, that were used only 1 or 2 times
 						unset($this->statistics[$cache_name][$key]);
 					}
 				}
 			}
 
 			print_pre($this->statistics, 'Cache Statistics:');
 		}
 	}
 
 
 	class FakeCacheHandler {
 
 		var $cachingType = CACHING_TYPE_TEMPORARY;
 
 		function FakeCacheHandler()
 		{
 
 		}
 
 		/**
 		 * Retrieves value from cache
 		 *
 		 * @param string $name
 		 * @return mixed
 		 */
 		function get($name)
 		{
 			return false;
 		}
 
 		/**
 		 * Stores value in cache
 		 *
 		 * @param string $name
 		 * @param mixed $value
 		 * @param int $expiration
 		 * @return bool
 		 */
 		function set($name, $value, $expiration = 0)
 		{
 			return true;
 		}
 
 		/**
 		 * Deletes key from cach
 		 *
 		 * @param string $name
 		 * @return bool
 		 */
 		function delete($name)
 		{
 			return true;
 		}
 
 		/**
 		 * Determines, that cache storage is working fine
 		 *
 		 * @return bool
 		 */
 		function isWorking()
 		{
 			return true;
 		}
 	}
 
 
 	class MemcacheCacheHandler {
 
 		var $_enabled = false;
 
 		/**
 		 * Memcache connection
 		 *
 		 * @var Memcache
 		 */
 		var $_handler = null;
 
 		var $cachingType = CACHING_TYPE_MEMORY;
 
 		function MemcacheCacheHandler()
 		{
 			if (array_key_exists('MemcacheServers', $GLOBALS['vars'])) {
 				// for advanced users, who want to save one SQL on each page load
 				$memcached_servers = $GLOBALS['vars']['MemcacheServers'];
 			}
 			else {
-				$memcached_servers = $this->Application->ConfigValue('MemcacheServers');
+				$application =& kApplication::Instance();
+				$memcached_servers = $application->ConfigValue('MemcacheServers');
 			}
 
 			if ($memcached_servers && class_exists('Memcache')) {
 				$this->_enabled = true;
 				$this->_handler = new Memcache();
 				$servers = explode(';', $memcached_servers);
 
 			 	foreach ($servers as $server) {
 			 		list ($server, $port) = strpos($server, ':') !== false ? explode(':', $server, 2) : Array ($server, 11211);
 			 		$this->_handler->addServer($server, $port);
 			 	}
 
 			 	// verify, that memcache server is working
 			 	if (!$this->_handler->set('test', 1)) {
 					$this->_enabled = false;
 				}
 			}
 		}
 
 		/**
 		 * Retrieves value from cache
 		 *
 		 * @param string $name
 		 * @return mixed
 		 */
 		function get($name)
 		{
 			return $this->_handler->get($name);
 		}
 
 		/**
 		 * Stores value in cache
 		 *
 		 * @param string $name
 		 * @param mixed $value
 		 * @param int $expiration
 		 * @return bool
 		 */
 		function set($name, $value, $expiration = 0)
 		{
 			// 0 - don't use compression
 			return $this->_handler->set($name, $value, 0, $expiration);
 		}
 
 		/**
 		 * Deletes key from cache
 		 *
 		 * @param string $name
 		 * @return bool
 		 */
 		function delete($name)
 		{
 			return $this->_handler->delete($name);
 		}
 
 		/**
 		 * Determines, that cache storage is working fine
 		 *
 		 * @return bool
 		 */
 		function isWorking()
 		{
 			return $this->_enabled;
 		}
 	}
 
 
 	class ApcCacheHandler {
 
 		var $_enabled = false;
 
 		var $cachingType = CACHING_TYPE_MEMORY;
 
 		function ApcCacheHandler()
 		{
 			$this->_enabled = function_exists('apc_fetch');
 
 		 	// verify, that apc is working
 		 	if ($this->_enabled && !$this->set('test', 1)) {
 				$this->_enabled = false;
 			}
 		}
 
 		/**
 		 * Retrieves value from cache
 		 *
 		 * @param string $name
 		 * @return mixed
 		 */
 		function get($name)
 		{
 			return apc_fetch($name);
 		}
 
 		/**
 		 * Stores value in cache
 		 *
 		 * @param string $name
 		 * @param mixed $value
 		 * @param int $expiration
 		 * @return bool
 		 */
 		function set($name, $value, $expiration = 0)
 		{
 			return apc_store($name, $value, $expiration);
 		}
 
 		/**
 		 * Deletes key from cache
 		 *
 		 * @param string $name
 		 * @return bool
 		 */
 		function delete($name)
 		{
 			return apc_delete($name);
 		}
 
 		/**
 		 * Determines, that cache storage is working fine
 		 *
 		 * @return bool
 		 */
 		function isWorking()
 		{
 			return $this->_enabled;
 		}
 	}
\ No newline at end of file