From 7dfad00e55148032541d1dabc9ac49eaf96c0903 Mon Sep 17 00:00:00 2001
From: mattab <matthieu.aubry@gmail.com>
Date: Sun, 17 Feb 2013 23:04:33 +1300
Subject: [PATCH] Fixes #2830 Implementing Tracker Cache TTL (in config file,
 [Tracker]

---
 config/global.ini.php                        |   4 +
 core/ArchiveProcessing.php                   |   3 +-
 core/CacheFile.php                           |  30 ++-
 core/Common.php                              | 238 +------------------
 core/Piwik.php                               |   2 +-
 core/Tracker.php                             | 105 +++++++-
 core/Tracker/Action.php                      |   6 +-
 core/Tracker/Cache.php                       | 155 ++++++++++++
 core/Tracker/Config.php                      |   4 +
 core/Tracker/GoalManager.php                 |   2 +-
 core/Tracker/Visit.php                       |   6 +-
 core/Updates/0.2.34.php                      |   2 +-
 core/Updates/0.6.2.php                       |   2 +-
 libs/Smarty/Smarty_Compiler.class.php        |   9 +-
 plugins/Goals/API.php                        |   8 +-
 plugins/SitesManager/API.php                 |  18 +-
 plugins/UserCountry/Controller.php           |   2 +-
 plugins/UsersManager/API.php                 |   8 +-
 tests/PHPUnit/DatabaseTestCase.php           |   2 +-
 tests/PHPUnit/IntegrationTestCase.php        |   4 +-
 tests/PHPUnit/Plugins/PrivacyManagerTest.php |   2 +-
 tests/PHPUnit/proxy/index.php                |   2 +-
 tests/PHPUnit/proxy/piwik.php                |   2 +-
 23 files changed, 330 insertions(+), 286 deletions(-)
 create mode 100644 core/Tracker/Cache.php

diff --git a/config/global.ini.php b/config/global.ini.php
index 563867e870..afd6a7afb1 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -399,6 +399,10 @@ action_sitesearch_record_url = 0
 ; For IPv4 addresses, valid values are 0..4; for IPv6 addresses, valid values are 0..16
 ip_address_mask_length = 1
 
+; Tracker cache files are the simple caching layer for Tracking.
+; TTL: Time to live for cache files, in seconds. Default to 5 minutes.
+tracker_cache_file_ttl = 300
+
 ; DO NOT USE THIS SETTING ON PUBLICLY AVAILABLE PIWIK SERVER
 ; !!! Security risk: if set to 0, it would allow anyone to push data to Piwik with custom dates in the past/future and with fake IPs !!!
 ; When using the Tracking API, to override either the datetime and/or the visitor IP, 
diff --git a/core/ArchiveProcessing.php b/core/ArchiveProcessing.php
index c49d70f6a8..b16bc343e7 100644
--- a/core/ArchiveProcessing.php
+++ b/core/ArchiveProcessing.php
@@ -296,8 +296,9 @@ abstract class Piwik_ArchiveProcessing
 			throw new Exception('Browser trigger archiving must be set to true or false.');
 		}
 		Piwik_SetOption(self::OPTION_BROWSER_TRIGGER_ARCHIVING, (int)$enabled, $autoload = true);
-		Piwik_Common::clearCacheGeneral();
+		Piwik_Tracker_Cache::clearCacheGeneral();
 	}
+
 	static public function isBrowserTriggerArchivingEnabled()
 	{
 		$browserArchivingEnabled = Piwik_GetOption(self::OPTION_BROWSER_TRIGGER_ARCHIVING);
diff --git a/core/CacheFile.php b/core/CacheFile.php
index b4a0303cd3..2ee1d11176 100644
--- a/core/CacheFile.php
+++ b/core/CacheFile.php
@@ -30,12 +30,22 @@ class Piwik_CacheFile
 	 */
 	protected $cachePrefix;
 
+	/**
+	 * Minimum enforced TTL in seconds
+	 */
+	const MINIMUM_TTL = 60;
+
 	/**
 	 * @param string  $directory  directory to use
+	 * @param int TTL
 	 */
-	function __construct($directory)
+	function __construct($directory, $timeToLiveInSeconds = 300)
 	{
 		$this->cachePath = PIWIK_USER_PATH . '/tmp/cache/' . $directory . '/';
+		if($timeToLiveInSeconds < self::MINIMUM_TTL) {
+			$timeToLiveInSeconds = self::MINIMUM_TTL;
+		}
+		$this->ttl = $timeToLiveInSeconds;
 	}
 
 	/**
@@ -53,17 +63,28 @@ class Piwik_CacheFile
 
 		$cache_complete = false;
 		$content = '';
+		$expires_on = false;
 
 		// We are assuming that most of the time cache will exists
 		$ok = @include($this->cachePath . $id . '.php');
 
 		if ($ok && $cache_complete == true) {
+
+			if(empty($expires_on)
+				|| $expires_on < time()) {
+				return false;
+			}
 			return $content;
 		}
 
 		return false;
 	}
 
+	private function getExpiresTime()
+	{
+		return time() + $this->ttl;
+	}
+
 	protected function cleanupId($id)
 	{
 		if(!Piwik_Common::isValidFilename($id)) {
@@ -95,9 +116,10 @@ class Piwik_CacheFile
 	
 		$id = $this->cachePath . $id . '.php';
 
-		$cache_literal  = "<"."?php\n\n";
-		$cache_literal .= "$"."content   = ".var_export($content, true).";\n\n";
-		$cache_literal .= "$"."cache_complete   = true;\n\n";
+		$cache_literal  = "<"."?php\n";
+		$cache_literal .= "$"."content   = ".var_export($content, true).";\n";
+		$cache_literal .= "$"."expires_on   = ".$this->getExpiresTime().";\n";
+		$cache_literal .= "$"."cache_complete   = true;\n";
 		$cache_literal .= "?".">";
 
 		// Write cache to a temp file, then rename it, overwriting the old cache
diff --git a/core/Common.php b/core/Common.php
index 9e4164ecd3..88bef80f90 100644
--- a/core/Common.php
+++ b/core/Common.php
@@ -108,246 +108,10 @@ class Piwik_Common
 /*
  * Tracker
  */
-
-	static public $initTrackerMode = false;
-	static protected function initCorePiwikInTrackerMode()
-	{
-		if(!empty($GLOBALS['PIWIK_TRACKER_MODE'])
-			&& self::$initTrackerMode === false)
-		{
-			self::$initTrackerMode = true;
-			require_once PIWIK_INCLUDE_PATH . '/core/Loader.php';
-			require_once PIWIK_INCLUDE_PATH . '/core/Option.php';
-			try {
-				$access = Zend_Registry::get('access');
-			} catch (Exception $e) {
-				Piwik::createAccessObject();
-			}
-			try {
-				$config = Piwik_Config::getInstance();
-			} catch (Exception $e) {
-				Piwik::createConfigObject();
-			}
-			try {
-				$db = Zend_Registry::get('db');
-			} catch (Exception $e) {
-				Piwik::createDatabaseObject();
-			}
-
-			$pluginsManager = Piwik_PluginsManager::getInstance();
-			$pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins'];
-			$pluginsForcedNotToLoad = Piwik_Tracker::getPluginsNotToLoad();
-			$pluginsToLoad = array_diff($pluginsToLoad, $pluginsForcedNotToLoad);
-			$pluginsManager->loadPlugins( $pluginsToLoad );
-		}
-	}
-
 	static public function isGoalPluginEnabled()
 	{
 		return Piwik_PluginsManager::getInstance()->isPluginActivated('Goals');
 	}
-	
-/*
- * File-based Cache
- */
-
-	/**
-	 * @var Piwik_CacheFile
-	 */
-	static $trackerCache = null;
-	static protected function getTrackerCache()
-	{
-		if(is_null(self::$trackerCache))
-		{
-			self::$trackerCache = new Piwik_CacheFile('tracker');
-		}
-		return self::$trackerCache;
-	}
-
-	/**
-	 * Returns array containing data about the website: goals, URLs, etc.
-	 *
-	 * @param int  $idSite
-	 * @return array
-	 */
-	static function getCacheWebsiteAttributes( $idSite )
-	{
-		$idSite = (int)$idSite;
-		
-		$cache = self::getTrackerCache();
-		if(($cacheContent = $cache->get($idSite)) !== false)
-		{
-			return $cacheContent;
-		}
-
-		self::initCorePiwikInTrackerMode();
-
-		// save current user privilege and temporarily assume super user privilege
-		$isSuperUser = Piwik::isUserIsSuperUser();
-		Piwik::setUserIsSuperUser();
-
-		$content = array();
-		Piwik_PostEvent('Common.fetchWebsiteAttributes', $content, $idSite);
-
-		// restore original user privilege
-		Piwik::setUserIsSuperUser($isSuperUser);
-
-		// if nothing is returned from the plugins, we don't save the content
-		// this is not expected: all websites are expected to have at least one URL
-		if(!empty($content))
-		{
-			$cache->set($idSite, $content);
-		}
-		return $content;
-	}
-
-	/**
-	 * Clear general (global) cache
-	 */
-	static public function clearCacheGeneral()
-	{
-		self::getTrackerCache()->delete('general');
-	}
-
-	/**
-	 * Returns contents of general (global) cache.
-	 * If the cache file tmp/cache/tracker/general.php does not exist yet, create it
-	 *
-	 * @return array
-	 */
-	static protected function getCacheGeneral()
-	{
-		$cache = self::getTrackerCache();
-		$cacheId = 'general';
-		$expectedRows = 3;
-		if(($cacheContent = $cache->get($cacheId)) !== false
-			&& count($cacheContent) == $expectedRows)
-		{
-			return $cacheContent;
-		}
-
-		self::initCorePiwikInTrackerMode();
-		$cacheContent = array (
-			'isBrowserTriggerArchivingEnabled' => Piwik_ArchiveProcessing::isBrowserTriggerArchivingEnabled(),
-			'lastTrackerCronRun' => Piwik_GetOption('lastTrackerCronRun'),
-			'currentLocationProviderId' => Piwik_UserCountry_LocationProvider::getCurrentProviderId(),
-		);
-		Piwik_Common::setCacheGeneral( $cacheContent );
-		return $cacheContent;
-	}
-
-	/**
-	 * Store data in general (global cache)
-	 *
-	 * @param mixed  $value
-	 * @return bool
-	 */
-	static protected function setCacheGeneral($value)
-	{
-		$cache = self::getTrackerCache();
-		$cacheId = 'general';
-		$cache->set($cacheId, $value);
-		return true;
-	}
-	
-	/**
-	 * Regenerate Tracker cache files
-	 *
-	 * @param array  $idSites  Array of idSites to clear cache for
-	 */
-	static public function regenerateCacheWebsiteAttributes($idSites = array())
-	{
-		if(!is_array($idSites))
-		{
-			$idSites = array( $idSites );
-		}
-		foreach($idSites as $idSite) {
-			self::deleteCacheWebsiteAttributes($idSite);
-			self::getCacheWebsiteAttributes($idSite);
-		}
-	}
-
-	/**
-	 * Delete existing Tracker cache
-	 *
-	 * @param string  $idSite  (website ID of the site to clear cache for
-	 */
-	static public function deleteCacheWebsiteAttributes( $idSite )
-	{
-		$idSite = (int)$idSite;
-		$cache = new Piwik_CacheFile('tracker');
-		$cache->delete($idSite);
-	}
-
-	/**
-	 * Deletes all Tracker cache files
-	 */
-	static public function deleteTrackerCache()
-	{
-		$cache = new Piwik_CacheFile('tracker');
-		$cache->deleteAll();
-	}
-
-	/**
-	 * Tracker requests will automatically trigger the Scheduled tasks.
-	 * This is useful for users who don't setup the cron,
-	 * but still want daily/weekly/monthly PDF reports emailed automatically.
-	 *
-	 * This is similar to calling the API CoreAdminHome.runScheduledTasks (see misc/cron/archive.php)
-	 *
-	 * @param int  $now  Current timestamp
-	 */
-	public static function runScheduledTasks($now)
-	{
-		// Currently, there is no hourly tasks. When there are some,
-		// this could be too agressive minimum interval (some hours would be skipped in case of low traffic)
-		$minimumInterval = Piwik_Config::getInstance()->Tracker['scheduled_tasks_min_interval'];
-
-		// If the user disabled browser archiving, he has already setup a cron
-		// To avoid parallel requests triggering the Scheduled Tasks,
-		// Get last time tasks started executing
-		$cache = Piwik_Common::getCacheGeneral();
-		if($minimumInterval <= 0
-			|| empty($cache['isBrowserTriggerArchivingEnabled']))
-		{
-			printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled.");
-			return;
-		}
-		$nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval;
-		if(	(isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS'])
-			|| $cache['lastTrackerCronRun'] === false
-			|| $nextRunTime < $now )
-		{
-			$cache['lastTrackerCronRun'] = $now;
-			Piwik_Common::setCacheGeneral( $cache );
-			Piwik_Common::initCorePiwikInTrackerMode();
-			Piwik_SetOption('lastTrackerCronRun', $cache['lastTrackerCronRun']);
-			printDebug('-> Scheduled Tasks: Starting...');
-
-			// save current user privilege and temporarily assume super user privilege
-			$isSuperUser = Piwik::isUserIsSuperUser();
-
-			// Scheduled tasks assume Super User is running
-			Piwik::setUserIsSuperUser();
-
-			// While each plugins should ensure that necessary languages are loaded,
-			// we ensure English translations at least are loaded
-			Piwik_Translate::getInstance()->loadEnglishTranslation();
-
-			$resultTasks = Piwik_TaskScheduler::runTasks();
-
-			// restore original user privilege
-			Piwik::setUserIsSuperUser($isSuperUser);
-
-			printDebug($resultTasks);
-			printDebug('Finished Scheduled Tasks.');
-		}
-		else
-		{
-			printDebug("-> Scheduled tasks not triggered.");
-		}
-		printDebug("Next run will be from: ". date('Y-m-d H:i:s', $nextRunTime) .' UTC');
-	}
 
 /*
  * URLs
@@ -1914,7 +1678,7 @@ class Piwik_Common
 	 */
 	public static function getCurrentLocationProviderId()
 	{
-		$cache = self::getCacheGeneral();
+		$cache = Piwik_Tracker_Cache::getCacheGeneral();
 		return empty($cache['currentLocationProviderId'])
 			  ? Piwik_UserCountry_LocationProvider_Default::ID
 			  : $cache['currentLocationProviderId'];
diff --git a/core/Piwik.php b/core/Piwik.php
index d84dd72513..9ad4eee941 100644
--- a/core/Piwik.php
+++ b/core/Piwik.php
@@ -133,7 +133,7 @@ class Piwik
 	{
 		Piwik_AssetManager::removeMergedAssets();
 		Piwik_View::clearCompiledTemplates();
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 	}
 	
 	/**
diff --git a/core/Tracker.php b/core/Tracker.php
index a968c1876b..6c23b471ea 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -270,7 +270,7 @@ class Piwik_Tracker
 			if(!Piwik_Common::isPhpCliMode()
 				&& !$this->authenticated)
 			{
-				Piwik_Common::runScheduledTasks($now = $this->getCurrentTimestamp());
+				self::runScheduledTasks($now = $this->getCurrentTimestamp());
 			}
 		}
 		catch (Exception $e)
@@ -280,7 +280,106 @@ class Piwik_Tracker
 
 		$this->end();
 	}
-	
+
+	/**
+	 * Tracker requests will automatically trigger the Scheduled tasks.
+	 * This is useful for users who don't setup the cron,
+	 * but still want daily/weekly/monthly PDF reports emailed automatically.
+	 *
+	 * This is similar to calling the API CoreAdminHome.runScheduledTasks (see misc/cron/archive.php)
+	 *
+	 * @param int  $now  Current timestamp
+	 */
+	protected static function runScheduledTasks($now)
+	{
+		// Currently, there is no hourly tasks. When there are some,
+		// this could be too agressive minimum interval (some hours would be skipped in case of low traffic)
+		$minimumInterval = Piwik_Config::getInstance()->Tracker['scheduled_tasks_min_interval'];
+
+		// If the user disabled browser archiving, he has already setup a cron
+		// To avoid parallel requests triggering the Scheduled Tasks,
+		// Get last time tasks started executing
+		$cache = Piwik_Tracker_Cache::getCacheGeneral();
+		if($minimumInterval <= 0
+			|| empty($cache['isBrowserTriggerArchivingEnabled']))
+		{
+			printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled.");
+			return;
+		}
+		$nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval;
+		if(	(isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS'])
+			|| $cache['lastTrackerCronRun'] === false
+			|| $nextRunTime < $now )
+		{
+			$cache['lastTrackerCronRun'] = $now;
+			Piwik_Tracker_Cache::setCacheGeneral( $cache );
+			self::initCorePiwikInTrackerMode();
+			Piwik_SetOption('lastTrackerCronRun', $cache['lastTrackerCronRun']);
+			printDebug('-> Scheduled Tasks: Starting...');
+
+			// save current user privilege and temporarily assume super user privilege
+			$isSuperUser = Piwik::isUserIsSuperUser();
+
+			// Scheduled tasks assume Super User is running
+			Piwik::setUserIsSuperUser();
+
+			// While each plugins should ensure that necessary languages are loaded,
+			// we ensure English translations at least are loaded
+			Piwik_Translate::getInstance()->loadEnglishTranslation();
+
+			$resultTasks = Piwik_TaskScheduler::runTasks();
+
+			// restore original user privilege
+			Piwik::setUserIsSuperUser($isSuperUser);
+
+			printDebug($resultTasks);
+			printDebug('Finished Scheduled Tasks.');
+		}
+		else
+		{
+			printDebug("-> Scheduled tasks not triggered.");
+		}
+		printDebug("Next run will be from: ". date('Y-m-d H:i:s', $nextRunTime) .' UTC');
+	}
+
+	static public $initTrackerMode = false;
+
+	/*
+	 * Used to initialize core Piwik components on a piwik.php request
+	 * Eg. when cache is missed and we will be calling some APIs to generate cache
+	 */
+	static public function initCorePiwikInTrackerMode()
+	{
+		if(!empty($GLOBALS['PIWIK_TRACKER_MODE'])
+			&& self::$initTrackerMode === false)
+		{
+			self::$initTrackerMode = true;
+			require_once PIWIK_INCLUDE_PATH . '/core/Loader.php';
+			require_once PIWIK_INCLUDE_PATH . '/core/Option.php';
+			try {
+				$access = Zend_Registry::get('access');
+			} catch (Exception $e) {
+				Piwik::createAccessObject();
+			}
+			try {
+				$config = Piwik_Config::getInstance();
+			} catch (Exception $e) {
+				Piwik::createConfigObject();
+			}
+			try {
+				$db = Zend_Registry::get('db');
+			} catch (Exception $e) {
+				Piwik::createDatabaseObject();
+			}
+
+			$pluginsManager = Piwik_PluginsManager::getInstance();
+			$pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins'];
+			$pluginsForcedNotToLoad = Piwik_Tracker::getPluginsNotToLoad();
+			$pluginsToLoad = array_diff($pluginsToLoad, $pluginsForcedNotToLoad);
+			$pluginsManager->loadPlugins( $pluginsToLoad );
+		}
+	}
+
 	/**
 	 * Echos an error message & other information, then exits.
 	 * 
@@ -574,7 +673,7 @@ class Piwik_Tracker
 		if(!empty($idSite)
 			&& $idSite > 0)
 		{
-			$website = Piwik_Common::getCacheWebsiteAttributes( $idSite );
+			$website = Piwik_Tracker_Cache::getCacheWebsiteAttributes( $idSite );
 			$adminTokenAuth = $website['admin_token_auth'];
 			if(in_array($tokenAuth, $adminTokenAuth))
 			{
diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php
index fde033de76..f9da32f893 100644
--- a/core/Tracker/Action.php
+++ b/core/Tracker/Action.php
@@ -344,7 +344,7 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 	 */
 	public static function shouldRemoveURLFragmentFor( $idSite )
 	{
-		$websiteAttributes = Piwik_Common::getCacheWebsiteAttributes($idSite);
+		$websiteAttributes = Piwik_Tracker_Cache::getCacheWebsiteAttributes($idSite);
 		return !$websiteAttributes['keep_url_fragment'];
 	}
 
@@ -397,7 +397,7 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 			$campaignTrackingParameters[1] // campaign keyword parameters
 		);
 
-		$website = Piwik_Common::getCacheWebsiteAttributes($idSite);
+		$website = Piwik_Tracker_Cache::getCacheWebsiteAttributes($idSite);
 		$excludedParameters = isset($website['excluded_parameters'])
 			? $website['excluded_parameters']
 			: array();
@@ -863,7 +863,7 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 
 	protected function detectSiteSearch($originalUrl)
 	{
-		$website = Piwik_Common::getCacheWebsiteAttributes($this->idSite);
+		$website = Piwik_Tracker_Cache::getCacheWebsiteAttributes($this->idSite);
 		if(empty($website['sitesearch']))
 		{
 			printDebug("Internal 'Site Search' tracking is not enabled for this site. ");
diff --git a/core/Tracker/Cache.php b/core/Tracker/Cache.php
new file mode 100644
index 0000000000..01519a07e0
--- /dev/null
+++ b/core/Tracker/Cache.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+/**
+ * Simple cache mechanism used in Tracker to avoid requesting settings from mysql on every request
+ *
+ * @package Piwik
+ * @subpackage Piwik_Tracker
+ */
+class Piwik_Tracker_Cache
+{
+	/**
+	 * @var Piwik_CacheFile
+	 */
+	static $trackerCache = null;
+	static protected function getInstance()
+	{
+		if(is_null(self::$trackerCache)) {
+			$ttl = Piwik_Config::getInstance()->Tracker['tracker_cache_file_ttl'];
+			self::$trackerCache = new Piwik_CacheFile('tracker', $ttl);
+		}
+		return self::$trackerCache;
+	}
+
+	/**
+	 * Returns array containing data about the website: goals, URLs, etc.
+	 *
+	 * @param int  $idSite
+	 * @return array
+	 */
+	static function getCacheWebsiteAttributes( $idSite )
+	{
+		$idSite = (int)$idSite;
+
+		$cache = self::getInstance();
+		if(($cacheContent = $cache->get($idSite)) !== false)
+		{
+			return $cacheContent;
+		}
+
+		Piwik_Tracker::initCorePiwikInTrackerMode();
+
+		// save current user privilege and temporarily assume super user privilege
+		$isSuperUser = Piwik::isUserIsSuperUser();
+		Piwik::setUserIsSuperUser();
+
+		$content = array();
+		Piwik_PostEvent('Common.fetchWebsiteAttributes', $content, $idSite);
+
+		// restore original user privilege
+		Piwik::setUserIsSuperUser($isSuperUser);
+
+		// if nothing is returned from the plugins, we don't save the content
+		// this is not expected: all websites are expected to have at least one URL
+		if(!empty($content))
+		{
+			$cache->set($idSite, $content);
+		}
+		return $content;
+	}
+
+	/**
+	 * Clear general (global) cache
+	 */
+	static public function clearCacheGeneral()
+	{
+		self::getInstance()->delete('general');
+	}
+
+	/**
+	 * Returns contents of general (global) cache.
+	 * If the cache file tmp/cache/tracker/general.php does not exist yet, create it
+	 *
+	 * @return array
+	 */
+	static public function getCacheGeneral()
+	{
+		$cache = self::getInstance();
+		$cacheId = 'general';
+		$expectedRows = 3;
+		if(($cacheContent = $cache->get($cacheId)) !== false
+			&& count($cacheContent) == $expectedRows)
+		{
+			return $cacheContent;
+		}
+
+		Piwik_Tracker::initCorePiwikInTrackerMode();
+		$cacheContent = array (
+			'isBrowserTriggerArchivingEnabled' => Piwik_ArchiveProcessing::isBrowserTriggerArchivingEnabled(),
+			'lastTrackerCronRun' => Piwik_GetOption('lastTrackerCronRun'),
+			'currentLocationProviderId' => Piwik_UserCountry_LocationProvider::getCurrentProviderId(),
+		);
+		self::setCacheGeneral( $cacheContent );
+		return $cacheContent;
+	}
+
+	/**
+	 * Store data in general (global cache)
+	 *
+	 * @param mixed  $value
+	 * @return bool
+	 */
+	static public function setCacheGeneral($value)
+	{
+		$cache = self::getInstance();
+		$cacheId = 'general';
+		$cache->set($cacheId, $value);
+		return true;
+	}
+
+	/**
+	 * Regenerate Tracker cache files
+	 *
+	 * @param array  $idSites  Array of idSites to clear cache for
+	 */
+	static public function regenerateCacheWebsiteAttributes($idSites = array())
+	{
+		if(!is_array($idSites))
+		{
+			$idSites = array( $idSites );
+		}
+		foreach($idSites as $idSite) {
+			self::deleteCacheWebsiteAttributes($idSite);
+			self::getCacheWebsiteAttributes($idSite);
+		}
+	}
+
+	/**
+	 * Delete existing Tracker cache
+	 *
+	 * @param string  $idSite  (website ID of the site to clear cache for
+	 */
+	static public function deleteCacheWebsiteAttributes( $idSite )
+	{
+		$idSite = (int)$idSite;
+		self::getInstance()->delete($idSite);
+	}
+
+	/**
+	 * Deletes all Tracker cache files
+	 */
+	static public function deleteTrackerCache()
+	{
+		self::getInstance()->deleteAll();
+	}
+
+}
\ No newline at end of file
diff --git a/core/Tracker/Config.php b/core/Tracker/Config.php
index 71deb28ef8..90fe0e1f45 100644
--- a/core/Tracker/Config.php
+++ b/core/Tracker/Config.php
@@ -11,6 +11,10 @@
 
 /**
  * Backward compatibility layer
+ * DO NOT USE
+ *
+ * Use this notation to fetch a config file value:
+ * 	Piwik_Config::getInstance()->General['enable_browser_archiving_triggering']
  *
  * @todo remove this in 2.0
  * @since 1.7
diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php
index 482019219b..06fcf69374 100644
--- a/core/Tracker/GoalManager.php
+++ b/core/Tracker/GoalManager.php
@@ -79,7 +79,7 @@ class Piwik_Tracker_GoalManager
 	
 	static public function getGoalDefinitions( $idSite )
 	{
-		$websiteAttributes = Piwik_Common::getCacheWebsiteAttributes( $idSite );
+		$websiteAttributes = Piwik_Tracker_Cache::getCacheWebsiteAttributes( $idSite );
 		if(isset($websiteAttributes['goals']))
 		{
 			return $websiteAttributes['goals'];
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index c2a408cbc0..c32db56218 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -961,7 +961,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 	 */
 	protected function isVisitorIpExcluded($ip)
 	{
-		$websiteAttributes = Piwik_Common::getCacheWebsiteAttributes( $this->idsite );
+		$websiteAttributes = Piwik_Tracker_Cache::getCacheWebsiteAttributes( $this->idsite );
 		if(!empty($websiteAttributes['excluded_ips']))
 		{
 			if(Piwik_IP::isIpInRange($ip, $websiteAttributes['excluded_ips']))
@@ -984,7 +984,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 	 */
 	protected function isUserAgentExcluded( $ua )
 	{
-		$websiteAttributes = Piwik_Common::getCacheWebsiteAttributes($this->idsite);
+		$websiteAttributes = Piwik_Tracker_Cache::getCacheWebsiteAttributes($this->idsite);
 		if (!empty($websiteAttributes['excluded_user_agents']))
 		{
 			foreach ($websiteAttributes['excluded_user_agents'] as $excludedUserAgent)
@@ -1557,7 +1557,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 	// is the referer host any of the registered URLs for this website?
 	static public function isHostKnownAliasHost($urlHost, $idSite)
 	{
-		$websiteData = Piwik_Common::getCacheWebsiteAttributes($idSite);
+		$websiteData = Piwik_Tracker_Cache::getCacheWebsiteAttributes($idSite);
 		if(isset($websiteData['hosts']))
 		{
 			$canonicalHosts = array();
diff --git a/core/Updates/0.2.34.php b/core/Updates/0.2.34.php
index 2acd85ba80..3da37d68d6 100644
--- a/core/Updates/0.2.34.php
+++ b/core/Updates/0.2.34.php
@@ -19,6 +19,6 @@ class Piwik_Updates_0_2_34 extends Piwik_Updates
 		// force regeneration of cache files following #648
 		Piwik::setUserIsSuperUser();
 		$allSiteIds = Piwik_SitesManager_API::getInstance()->getAllSitesId();
-		Piwik_Common::regenerateCacheWebsiteAttributes($allSiteIds);
+		Piwik_Tracker_Cache::regenerateCacheWebsiteAttributes($allSiteIds);
 	}
 }
diff --git a/core/Updates/0.6.2.php b/core/Updates/0.6.2.php
index 1ea94d6197..0e0e88c27a 100644
--- a/core/Updates/0.6.2.php
+++ b/core/Updates/0.6.2.php
@@ -41,6 +41,6 @@ class Piwik_Updates_0_6_2 extends Piwik_Updates
 		// force regeneration of cache files
 		Piwik::setUserIsSuperUser();
 		$allSiteIds = Piwik_SitesManager_API::getInstance()->getAllSitesId();
-		Piwik_Common::regenerateCacheWebsiteAttributes($allSiteIds);
+		Piwik_Tracker_Cache::regenerateCacheWebsiteAttributes($allSiteIds);
 	}
 }
diff --git a/libs/Smarty/Smarty_Compiler.class.php b/libs/Smarty/Smarty_Compiler.class.php
index d0e0dad96d..88cb862c19 100644
--- a/libs/Smarty/Smarty_Compiler.class.php
+++ b/libs/Smarty/Smarty_Compiler.class.php
@@ -262,15 +262,10 @@ class Smarty_Compiler extends Smarty {
         reset($this->_folded_blocks);
 
         /* replace special blocks by "{php}"
-        Piwik Hack: commented out as this does not work on php 5.5 and we don't seem to use this "feature"
-        ---
-        $source_content = preg_replace($search.'e', "'"
-                                       . $this->_quote_replace($this->left_delimiter) . 'php'
-                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+        PIWIK HACKED for 5.5 compat */
+        $source_content = preg_replace($search, $this->_quote_replace($this->left_delimiter) . 'php'
                                        . $this->_quote_replace($this->right_delimiter)
-                                       . "'"
                                        , $source_content);
-		*/
 
         /* Gather all template tags. */
         preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
diff --git a/plugins/Goals/API.php b/plugins/Goals/API.php
index 563b26aca4..474d24baca 100644
--- a/plugins/Goals/API.php
+++ b/plugins/Goals/API.php
@@ -120,7 +120,7 @@ class Piwik_Goals_API
 						'revenue' => (float)$revenue,
 						'deleted' => 0,
 					));
-		Piwik_Common::regenerateCacheWebsiteAttributes($idSite);
+		Piwik_Tracker_Cache::regenerateCacheWebsiteAttributes($idSite);
 		return $idGoal;
 	}
 
@@ -157,8 +157,8 @@ class Piwik_Goals_API
 						'revenue' => (float)$revenue,
 						),
 					"idsite = '$idSite' AND idgoal = '$idGoal'"
-			);	
-		Piwik_Common::regenerateCacheWebsiteAttributes($idSite);
+			);
+		Piwik_Tracker_Cache::regenerateCacheWebsiteAttributes($idSite);
 	}
 
 	private function checkPatternIsValid($patternType, $pattern)
@@ -197,7 +197,7 @@ class Piwik_Goals_API
 											AND idgoal = ?",
 									array($idSite, $idGoal));
 		Piwik_DeleteAllRows(Piwik_Common::prefixTable("log_conversion"), "WHERE idgoal = ?", 100000, array($idGoal));
-		Piwik_Common::regenerateCacheWebsiteAttributes($idSite);
+		Piwik_Tracker_Cache::regenerateCacheWebsiteAttributes($idSite);
 	}
 	
 	/**
diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php
index 667dfb065c..17add71358 100644
--- a/plugins/SitesManager/API.php
+++ b/plugins/SitesManager/API.php
@@ -547,7 +547,7 @@ class Piwik_SitesManager_API
 	private function postUpdateWebsite($idSite)
 	{
 		Piwik_Site::clearCache();
-		Piwik_Common::regenerateCacheWebsiteAttributes($idSite);
+		Piwik_Tracker_Cache::regenerateCacheWebsiteAttributes($idSite);
 	}
 
 	/**
@@ -584,7 +584,8 @@ class Piwik_SitesManager_API
 		$db->query("DELETE FROM ".Piwik_Common::prefixTable("access")." 
 					WHERE idsite = ?", $idSite);
 
-		Piwik_Common::deleteCacheWebsiteAttributes($idSite);
+		// we do not delete logs here on purpose (you can run these queries on the log_ tables to delete all data)
+		Piwik_Tracker_Cache::deleteCacheWebsiteAttributes($idSite);
 
 		Piwik_PostEvent('SitesManager.deleteSite', $idSite);
 	}
@@ -708,11 +709,10 @@ class Piwik_SitesManager_API
 		Piwik::checkUserIsSuperUser();
 		$excludedIps = $this->checkAndReturnExcludedIps($excludedIps);
 		Piwik_SetOption(self::OPTION_EXCLUDED_IPS_GLOBAL, $excludedIps);
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 		return true;
 	}
 
-
 	/**
 	 * Sets Site Search keyword/category parameter names, to be used on websites which have not specified these values
 	 * Expects Comma separated list of query params names
@@ -726,7 +726,7 @@ class Piwik_SitesManager_API
 		Piwik::checkUserIsSuperUser();
 		Piwik_SetOption(self::OPTION_SEARCH_KEYWORD_QUERY_PARAMETERS_GLOBAL, $searchKeywordParameters);
 		Piwik_SetOption(self::OPTION_SEARCH_CATEGORY_QUERY_PARAMETERS_GLOBAL, $searchCategoryParameters);
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 		return true;
 	}
 
@@ -795,7 +795,7 @@ class Piwik_SitesManager_API
 		Piwik_SetOption(self::OPTION_EXCLUDED_USER_AGENTS_GLOBAL, $excludedUserAgents);
 		
 		// make sure tracker cache will reflect change
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 	}
 	
 	/**
@@ -824,7 +824,7 @@ class Piwik_SitesManager_API
 		Piwik_SetOption(self::OPTION_SITE_SPECIFIC_USER_AGENT_EXCLUDE_ENABLE, $enabled);
 		
 		// make sure tracker cache will reflect change
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 	}
 	
 	/**
@@ -855,7 +855,7 @@ class Piwik_SitesManager_API
 		Piwik_SetOption(self::OPTION_KEEP_URL_FRAGMENTS_GLOBAL, $enabled);
 		
 		// make sure tracker cache will reflect change
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 	}
 	
 	/**
@@ -870,7 +870,7 @@ class Piwik_SitesManager_API
 		Piwik::checkUserIsSuperUser();
 		$excludedQueryParameters = $this->checkAndReturnCommaSeparatedStringList($excludedQueryParameters);
 		Piwik_SetOption(self::OPTION_EXCLUDED_QUERY_PARAMETERS_GLOBAL, $excludedQueryParameters);
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 		return true;
 	}
 	
diff --git a/plugins/UserCountry/Controller.php b/plugins/UserCountry/Controller.php
index 6ddad37567..f34aa33efb 100644
--- a/plugins/UserCountry/Controller.php
+++ b/plugins/UserCountry/Controller.php
@@ -302,7 +302,7 @@ class Piwik_UserCountry_Controller extends Piwik_Controller_Admin
 			}
 			
 			// make sure the tracker will use the new location provider
-			Piwik_Common::clearCacheGeneral();
+			Piwik_Tracker_Cache::clearCacheGeneral();
 		}
 	}
 	
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index f7de67302e..a5e58a703e 100644
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -381,7 +381,7 @@ class Piwik_UsersManager_API
 		
 		// we reload the access list which doesn't yet take in consideration this new user
 		Zend_Registry::get('access')->reloadAccess();
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 
 		Piwik_PostEvent('UsersManager.addUser', $userLogin);
 	}
@@ -445,7 +445,7 @@ class Piwik_UsersManager_API
 						),
 					"login = '$userLogin'"
 			);		
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 
 		Piwik_PostEvent('UsersManager.updateUser', $userLogin);
 	}
@@ -471,7 +471,7 @@ class Piwik_UsersManager_API
 		
 		$this->deleteUserOnly( $userLogin );
 		$this->deleteUserAccess( $userLogin );
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 	}
 	
 	/**
@@ -572,7 +572,7 @@ class Piwik_UsersManager_API
 		
 		// we reload the access list which doesn't yet take in consideration this new user access
 		Zend_Registry::get('access')->reloadAccess();
-		Piwik_Common::deleteTrackerCache();
+		Piwik_Tracker_Cache::deleteTrackerCache();
 	}
 	
 	/**
diff --git a/tests/PHPUnit/DatabaseTestCase.php b/tests/PHPUnit/DatabaseTestCase.php
index 0f55912ee7..760962e1d5 100644
--- a/tests/PHPUnit/DatabaseTestCase.php
+++ b/tests/PHPUnit/DatabaseTestCase.php
@@ -70,7 +70,7 @@ class DatabaseTestCase extends PHPUnit_Framework_TestCase
         Piwik_Option::getInstance()->clearCache();
         Piwik_PDFReports_API::$cache = array();
         Piwik_Site::clearCache();
-        Piwik_Common::deleteTrackerCache();
+        Piwik_Tracker_Cache::deleteTrackerCache();
         Piwik_Config::getInstance()->clear();
         Piwik_TablePartitioning::$tablesAlreadyInstalled = null;
         Zend_Registry::_unsetInstance();
diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php
index 882e197e9a..8ec4e43ccc 100755
--- a/tests/PHPUnit/IntegrationTestCase.php
+++ b/tests/PHPUnit/IntegrationTestCase.php
@@ -98,7 +98,7 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
 
         // We need to be SU to create websites for tests
         Piwik::setUserIsSuperUser();
-	    Piwik_Common::deleteTrackerCache();
+	    Piwik_Tracker_Cache::deleteTrackerCache();
 
         // Load and install plugins
         $pluginsManager = Piwik_PluginsManager::getInstance();
@@ -149,7 +149,7 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
         Piwik_DataTable_Manager::getInstance()->deleteAll();
         Piwik_Option::getInstance()->clearCache();
         Piwik_Site::clearCache();
-        Piwik_Common::deleteTrackerCache();
+        Piwik_Tracker_Cache::deleteTrackerCache();
         Piwik_Config::getInstance()->clear();
         Piwik_TablePartitioning::$tablesAlreadyInstalled = null;
         Piwik_PDFReports_API::$cache = array();
diff --git a/tests/PHPUnit/Plugins/PrivacyManagerTest.php b/tests/PHPUnit/Plugins/PrivacyManagerTest.php
index 5b69b77a6b..820dfeacf6 100755
--- a/tests/PHPUnit/Plugins/PrivacyManagerTest.php
+++ b/tests/PHPUnit/Plugins/PrivacyManagerTest.php
@@ -105,7 +105,7 @@ class PrivacyManagerTest extends IntegrationTestCase
         Piwik_DataTable_Manager::getInstance()->deleteAll();
         Piwik_Option::getInstance()->clearCache();
         Piwik_Site::clearCache();
-        Piwik_Common::deleteTrackerCache();
+        Piwik_Tracker_Cache::deleteTrackerCache();
         Piwik_TablePartitioning::$tablesAlreadyInstalled = null;
         
         $tempTableName = Piwik_Common::prefixTable(Piwik_PrivacyManager_LogDataPurger::TEMP_TABLE_NAME);
diff --git a/tests/PHPUnit/proxy/index.php b/tests/PHPUnit/proxy/index.php
index acbbc176d3..e3034ccb1c 100644
--- a/tests/PHPUnit/proxy/index.php
+++ b/tests/PHPUnit/proxy/index.php
@@ -17,7 +17,7 @@ require_once PIWIK_INCLUDE_PATH .'/libs/upgradephp/upgrade.php';
 require_once PIWIK_INCLUDE_PATH .'/core/Loader.php';
 
 Piwik_Tracker::setTestEnvironment();
-Piwik_Common::deleteTrackerCache();
+Piwik_Tracker_Cache::deleteTrackerCache();
 
 class Piwik_FrontController_Test extends Piwik_FrontController 
 {
diff --git a/tests/PHPUnit/proxy/piwik.php b/tests/PHPUnit/proxy/piwik.php
index e7b0efac73..b79fbc24b3 100755
--- a/tests/PHPUnit/proxy/piwik.php
+++ b/tests/PHPUnit/proxy/piwik.php
@@ -31,7 +31,7 @@ Piwik_Tracker::setTestEnvironment();
 Piwik_DataTable_Manager::getInstance()->deleteAll();
 Piwik_Option::getInstance()->clearCache();
 Piwik_Site::clearCache();
-Piwik_Common::deleteTrackerCache();
+Piwik_Tracker_Cache::deleteTrackerCache();
 
 include PIWIK_INCLUDE_PATH . '/piwik.php';
 ob_end_flush();
-- 
GitLab