diff --git a/composer.json b/composer.json index d4d94cf177f1080ec83b2c6d042446c498a4527f..9bab20ec4450df68d12c50b7377d3d4d47394e2d 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,8 @@ "piwik/device-detector": "~2.0", "piwik/decompress": "~0.1.1", "piwik/network": "~0.1.0", - "mnapoli/php-di": "5.0.x-dev" + "mnapoli/php-di": "5.0.x-dev", + "piwik/cache": "~0.2" }, "require-dev": { "aws/aws-sdk-php": "2.7.1", diff --git a/composer.lock b/composer.lock index fdddc728f8c39eacad888d88c7da51c704215cbe..f4fbd7f67ed184e31afa95eae12de8569fb3c2dc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "92499fc432a629fefcd5c1b912e44d9c", + "hash": "993a7439f15dd4d11b2684f6e35b944d", "packages": [ { "name": "container-interop/container-interop", @@ -432,6 +432,53 @@ ], "time": "2013-11-11 18:29:08" }, + { + "name": "piwik/cache", + "version": "0.2.1", + "source": { + "type": "git", + "url": "https://github.com/piwik/component-cache.git", + "reference": "1cbe0012f703b5462e87520ebcf76bdca89026e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/piwik/component-cache/zipball/1cbe0012f703b5462e87520ebcf76bdca89026e8", + "reference": "1cbe0012f703b5462e87520ebcf76bdca89026e8", + "shasum": "" + }, + "require": { + "doctrine/cache": "~1.3", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Piwik\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "The Piwik Team", + "email": "hello@piwik.org", + "homepage": "http://piwik.org/the-piwik-team/" + } + ], + "description": "PHP caching library based on Doctrine cache", + "keywords": [ + "array", + "cache", + "file", + "redis" + ], + "time": "2014-12-16 01:47:11" + }, { "name": "piwik/decompress", "version": "0.1.1", diff --git a/config/global.ini.php b/config/global.ini.php index 559ba5987ef725289a3a98f849299e80f02e176c..0692f8b9b8485b487b6917ec6a2088be567e08b4 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -78,6 +78,31 @@ log_only_when_debug_parameter = 0 ; if configured to log in a file, log entries will be made to this file logger_file_path = tmp/logs/piwik.log +[Cache] +; available backends are 'file', 'array', 'null', 'redis', 'chained' +; 'array' will cache data only during one request +; 'null' will not cache anything at all +; 'file' will cache on the filesystem +; 'redis' will cache on a Redis server, use this if you are running Piwik with multiple servers. Further configuration in [RedisCache] is needed +; 'chained' will chain multiple cache backends. Further configuration in [ChainedCache] is needed +backend = chained + +[ChainedCache] +; The chained cache will always try to read from the fastest backend first (the first listed one) to avoid requesting +; the same cache entry from the slowest backend multiple times in one request. +backends[] = array +backends[] = file + +[RedisCache] +; Redis server configuration. +host = "127.0.0.1" +port = 6379 +timeout = 0.0 +password = "" +database = 14 +; In case you are using queued tracking: Make sure to configure a different database! Otherwise queued requests might +; be flushed + [Debug] ; if set to 1, the archiving process will always be triggered, even if the archive has already been computed ; this is useful when making changes to the archiving code so we can force the archiving process diff --git a/config/global.php b/config/global.php index 7dc6daa18fb84369d196c05d4497c50df4b2b234..29559349b763bbfedb845687917330d27aa8f5d4 100644 --- a/config/global.php +++ b/config/global.php @@ -1,6 +1,8 @@ <?php use Interop\Container\ContainerInterface; +use Piwik\Cache\Eager; +use Piwik\SettingsServer; return array( @@ -20,4 +22,56 @@ return array( return $root . '/tmp' . $instanceId; }), + 'path.cache' => DI\factory(function (ContainerInterface $c) { + $root = $c->get('path.tmp'); + + return $root . '/cache/tracker/'; + }), + + 'cache.backend' => DI\factory(function (ContainerInterface $c) { + if (defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE) { // todo replace this with isTest() instead of isCli() + $backend = 'file'; + } elseif (\Piwik\Development::isEnabled()) { + $backend = 'null'; + } else { + $backend = $c->get('old_config.Cache.backend'); + } + + return $backend; + }), + 'Piwik\Cache\Lazy' => DI\object(), + 'Piwik\Cache\Transient' => DI\object(), + 'Piwik\Cache\Eager' => DI\factory(function (ContainerInterface $c) { + + $backend = $c->get('Piwik\Cache\Backend'); + + if (defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE) { + $cacheId = 'eagercache-test-'; + } else { + $cacheId = 'eagercache-' . str_replace(array('.', '-'), '', \Piwik\Version::VERSION) . '-'; + } + + if (SettingsServer::isTrackerApiRequest()) { + $eventToPersist = 'Tracker.end'; + $cacheId .= 'tracker'; + } else { + $eventToPersist = 'Request.dispatch.end'; + $cacheId .= 'ui'; + } + + $cache = new Eager($backend, $cacheId); + \Piwik\Piwik::addAction($eventToPersist, function () use ($cache) { + $cache->persistCacheIfNeeded(43200); + }); + + return $cache; + }), + 'Piwik\Cache\Backend' => DI\factory(function (ContainerInterface $c) { + + $type = $c->get('cache.backend'); + $backend = \Piwik\Cache::buildBackend($type); + + return $backend; + }), + ); diff --git a/core/Cache.php b/core/Cache.php new file mode 100644 index 0000000000000000000000000000000000000000..b90be8d27b9021acf4a57f5f98ed0db51ffa6c1e --- /dev/null +++ b/core/Cache.php @@ -0,0 +1,117 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik; + +use Piwik\Cache\Backend; +use Piwik\Container\StaticContainer; + +class Cache +{ + + /** + * This can be considered as the default cache to use in case you don't know which one to pick. It does not support + * the caching of any objects though. Only boolean, numbers, strings and arrays are supported. Whenever you request + * an entry from the cache it will fetch the entry. Cache entries might be persisted but not necessarily. It + * depends on the configured backend. + * + * @return Cache\Lazy + */ + public static function getLazyCache() + { + return StaticContainer::getContainer()->get('Piwik\Cache\Lazy'); + } + + /** + * This class is used to cache any data during one request. It won't be persisted between requests and it can + * cache all kind of data, even objects or resources. This cache is very fast. + * + * @return Cache\Transient + */ + public static function getTransientCache() + { + return StaticContainer::getContainer()->get('Piwik\Cache\Transient'); + } + + /** + * This cache stores all its cache entries under one "cache" entry in a configurable backend. + * + * This comes handy for things that you need very often, nearly in every request. For example plugin metadata, the + * list of tracker plugins, the list of available languages, ... + * Instead of having to read eg. a hundred cache entries from files (or any other backend) it only loads one cache + * entry which contains the hundred keys. Should be used only for things that you need very often and only for + * cache entries that are not too large to keep loading and parsing the single cache entry fast. + * All cache entries it contains have the same life time. For fast performance it won't validate any cache ids. + * It is not possible to cache any objects using this cache. + * + * @return Cache\Eager + */ + public static function getEagerCache() + { + return StaticContainer::getContainer()->get('Piwik\Cache\Eager'); + } + + public static function flushAll() + { + self::getLazyCache()->flushAll(); + self::getTransientCache()->flushAll(); + self::getEagerCache()->flushAll(); + } + + /** + * @param $type + * @return Cache\Backend + */ + public static function buildBackend($type) + { + $factory = new Cache\Backend\Factory(); + $options = self::getOptions($type); + + $backend = $factory->buildBackend($type, $options); + + return $backend; + } + + private static function getOptions($type) + { + $options = self::getBackendOptions($type); + + switch ($type) { + case 'file': + + $options = array('directory' => StaticContainer::getContainer()->get('path.cache')); + break; + + case 'chained': + + foreach ($options['backends'] as $backend) { + $options[$backend] = self::getOptions($backend); + } + + break; + + case 'redis': + + if (!empty($options['timeout'])) { + $options['timeout'] = (float)Common::forceDotAsSeparatorForDecimalPoint($options['timeout']); + } + + break; + } + + return $options; + } + + private static function getBackendOptions($backend) + { + $key = ucfirst($backend) . 'Cache'; + $options = Config::getInstance()->$key; + + return $options; + } +} diff --git a/core/Cache/CacheDecorator.php b/core/Cache/CacheDecorator.php deleted file mode 100644 index f35154ba727f977858bbb9d7247c3f6dc70ee189..0000000000000000000000000000000000000000 --- a/core/Cache/CacheDecorator.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Cache; - -use Piwik\Tracker; -use Piwik\Translate; - -/** - * Caching class used for static caching. - */ -class CacheDecorator implements CacheInterface -{ - /** - * @var StaticCache - */ - protected $staticCache; - - public function __construct(CacheInterface $cache) - { - $this->staticCache = $cache; - } - - public function get() - { - return $this->staticCache->get(); - } - - public function has() - { - return $this->staticCache->has(); - } - - public function setCacheKey($cacheKey) - { - $this->staticCache->setCacheKey($cacheKey); - } - - public function getCacheKey() - { - return $this->staticCache->getCacheKey(); - } - - public function set($content) - { - $this->staticCache->set($content); - } - -} diff --git a/core/Cache/CacheInterface.php b/core/Cache/CacheInterface.php deleted file mode 100644 index 65039e5436f2b7197e56f022910e843bdc2d9e25..0000000000000000000000000000000000000000 --- a/core/Cache/CacheInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Cache; - -use Piwik\Tracker; -use Piwik\Translate; - -/** - * Caching class used for static caching. - */ -interface CacheInterface -{ - public function get(); - - public function has(); - - public function setCacheKey($cacheKey); - - public function getCacheKey(); - - public function set($content); - -} diff --git a/core/Cache/LanguageAwareStaticCache.php b/core/Cache/LanguageAwareStaticCache.php deleted file mode 100644 index 62b4773282b0a086b61696af063ea3d5bc73f006..0000000000000000000000000000000000000000 --- a/core/Cache/LanguageAwareStaticCache.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Cache; - -use Piwik\Translate; - -/** - * Caching class used for static caching which is language aware. It'll cache the given content depending on the - * current loaded language. This prevents you from having to invalidate the cache during tests in case the loaded - * language changes etc. - * - * TODO convert this to a decorator... see {@link StaticCache} - */ -class LanguageAwareStaticCache extends StaticCache -{ - protected function completeKey($cacheKey) - { - return $cacheKey . Translate::getLanguageLoaded(); - } -} diff --git a/core/Cache/PersistentCache.php b/core/Cache/PersistentCache.php deleted file mode 100644 index 5a98621a4c651110dde7c18dc95c73590bb305ae..0000000000000000000000000000000000000000 --- a/core/Cache/PersistentCache.php +++ /dev/null @@ -1,159 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Cache; - -use Piwik\CacheFile; -use Piwik\Development; -use Piwik\Piwik; -use Piwik\SettingsServer; -use Piwik\Version; - -/** - * Caching class that persists all cached values between requests. Meaning whatever you cache will be stored on the - * file system. It differs from other caches such as {@link CacheFile} that it does not create a file for each cacheKey. - * Reading and writing new values does not cause multiple reads / writes on the file system and is therefore faster. - * The cache won't be invalidated after any time by default but when the tracker cache is cleared. This is usually the - * case when a new plugin is installed or an existing plugin or the core is updated. - * You should be careful when caching any data since we won't modify the cache key. So if your data depends on which - * plugins are activated or should not be available to each user than make sure to include unique names in the cache - * key such as the names of all loaded plugin names. - * If development mode is enabled in the config this cache acts as a {@link StaticCache}. Meaning it won't persist any - * data between requests. - */ -class PersistentCache -{ - /** - * @var CacheFile - */ - private static $storage = null; - private static $content = null; - private static $isDirty = false; - - private $cacheKey; - - /** - * Initializes the cache. - * @param string $cacheKey - */ - public function __construct($cacheKey) - { - $this->cacheKey = $cacheKey; - - if (is_null(self::$content)) { - self::$content = array(); - self::populateCache(); - } - } - - /** - * Overwrites a previously set cache key. Useful if you want to reuse the same instance for different cache keys - * for performance reasons. - * @param string $cacheKey - */ - public function setCacheKey($cacheKey) - { - $this->cacheKey = $cacheKey; - } - - /** - * Get the content related to the current cache key. Make sure to call the method {@link has()} to verify whether - * there is actually any content set under this cache key. - * @return mixed - */ - public function get() - { - return self::$content[$this->cacheKey]; - } - - /** - * Check whether any content was actually stored for the current cache key. - * @return bool - */ - public function has() - { - return array_key_exists($this->cacheKey, self::$content); - } - - /** - * Set (overwrite) any content related to the current set cache key. - * @param $content - */ - public function set($content) - { - self::$content[$this->cacheKey] = $content; - self::$isDirty = true; - } - - private static function populateCache() - { - if (Development::isEnabled()) { - return; - } - - if (SettingsServer::isTrackerApiRequest()) { - $eventToPersist = 'Tracker.end'; - $mode = '-tracker'; - } else { - $eventToPersist = 'Request.dispatch.end'; - $mode = '-ui'; - } - - $cache = self::getStorage()->get(self::getCacheFilename() . $mode); - - if (is_array($cache)) { - self::$content = $cache; - } - - Piwik::addAction($eventToPersist, array(__CLASS__, 'persistCache')); - } - - private static function getCacheFilename() - { - return 'StaticCache-' . str_replace(array('.', '-'), '', Version::VERSION); - } - - /** - * @ignore - */ - public static function persistCache() - { - if (self::$isDirty) { - if (SettingsServer::isTrackerApiRequest()) { - $mode = '-tracker'; - } else { - $mode = '-ui'; - } - - self::getStorage()->set(self::getCacheFilename() . $mode, self::$content); - } - } - - /** - * @ignore - */ - public static function _reset() - { - self::$content = array(); - } - - /** - * @return CacheFile - */ - private static function getStorage() - { - if (is_null(self::$storage)) { - self::$storage = new CacheFile('tracker', 43200); - self::$storage->addOnDeleteCallback(function () { - PersistentCache::_reset(); - }); - } - - return self::$storage; - } -} diff --git a/core/Cache/PluginAwareStaticCache.php b/core/Cache/PluginAwareStaticCache.php deleted file mode 100644 index 1bc3a25bd5159ac042f0dde135cffff0928de571..0000000000000000000000000000000000000000 --- a/core/Cache/PluginAwareStaticCache.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Cache; - -use Piwik\Plugin\Manager as PluginManager; -use Piwik\Translate; - -/** - * Caching class used for static caching which is plugin aware. It'll cache the given content depending on the plugins - * that are installed. This prevents you from having to invalidate the cache during tests in case the loaded plugins - * changes etc. The key is language aware as well. - * - * TODO convert this to a decorator... see {@link StaticCache} - */ -class PluginAwareStaticCache extends StaticCache -{ - protected function completeKey($cacheKey) - { - $pluginManager = PluginManager::getInstance(); - $pluginNames = $pluginManager->getLoadedPluginsName(); - $cacheKey = $cacheKey . md5(implode('', $pluginNames)) . Translate::getLanguageLoaded(); - - return $cacheKey; - } -} diff --git a/core/Cache/StaticCache.php b/core/Cache/StaticCache.php deleted file mode 100644 index 0c102e18d39143312dd3c56150d5af8827b47f7e..0000000000000000000000000000000000000000 --- a/core/Cache/StaticCache.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Cache; - -/** - * Caching class used for static caching. Any content that is set here won't be cached between requests. If you do want - * to persist any content between requests have a look at {@link PersistentCache} - * - * TODO the default static cache should actually not be language aware. Especially since we would end up in classes like - * LanguageAwareStaticCache, PluginAwareStaticCache, PluginAwareLanguageAwareStaticCache, PluginAwareXYZStaticCache,... - * once we have dependency injection we should "build" all the caches we need removing duplicated code and extend the - * static cache by using decorators which "enrich" the cache key depending on their awareness. - */ -class StaticCache -{ - protected static $staticCache = array(); - - private $cacheKey; - - /** - * Initializes the cache. - * @param string $cacheKey - */ - public function __construct($cacheKey) - { - $this->setCacheKey($cacheKey); - } - - /** - * Overwrites a previously set cache key. Useful if you want to reuse the same instance for different cache keys - * for performance reasons. - * @param string $cacheKey - */ - public function setCacheKey($cacheKey) - { - $this->cacheKey = $this->completeKey($cacheKey); - } - - /** - * Get the content related to the current cache key. Make sure to call the method {@link has()} to verify whether - * there is actually any content set under this cache key. - * @return mixed - */ - public function get() - { - return self::$staticCache[$this->cacheKey]; - } - - /** - * Check whether any content was actually stored for the current cache key. - * @return bool - */ - public function has() - { - return array_key_exists($this->cacheKey, self::$staticCache); - } - - /** - * Reset the stored content of the current cache key. - */ - public function clear() - { - unset(self::$staticCache[$this->cacheKey]); - } - - /** - * Reset the stored content of the current cache key. - * @ignore - */ - public static function clearAll() - { - self::$staticCache = array(); - } - - /** - * Set (overwrite) any content related to the current set cache key. - * @param $content - */ - public function set($content) - { - self::$staticCache[$this->cacheKey] = $content; - } - - protected function completeKey($cacheKey) - { - return $cacheKey; - } -} \ No newline at end of file diff --git a/core/CacheFile.php b/core/CacheFile.php deleted file mode 100644 index b8ec14c57560d78122a76889a422da4717cd02d5..0000000000000000000000000000000000000000 --- a/core/CacheFile.php +++ /dev/null @@ -1,237 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik; - -use Exception; -use Piwik\Container\StaticContainer; - -/** - * This class is used to cache data on the filesystem. - * - * It is for example used by the Tracker process to cache various settings and websites attributes in tmp/cache/tracker/* - * - */ -class CacheFile -{ - // for testing purposes since tests run on both CLI/FPM (changes in CLI can't invalidate - // opcache in FPM, so we have to invalidate before reading) - public static $invalidateOpCacheBeforeRead = false; - - /** - * @var string - */ - private $cachePath; - - /** - * Minimum enforced TTL in seconds - */ - const MINIMUM_TTL = 60; - - /** - * @var \Callable[] - */ - private static $onDeleteCallback = array(); - - /** - * @param string $directory directory to use - * @param int $timeToLiveInSeconds TTL - */ - public function __construct($directory, $timeToLiveInSeconds = 300) - { - $this->cachePath = StaticContainer::getContainer()->get('path.tmp') . '/cache/' . $directory . '/'; - - if ($timeToLiveInSeconds < self::MINIMUM_TTL) { - $timeToLiveInSeconds = self::MINIMUM_TTL; - } - $this->ttl = $timeToLiveInSeconds; - } - - /** - * Function to fetch a cache entry - * - * @param string $id The cache entry ID - * @return array|bool False on error, or array the cache content - */ - public function get($id) - { - if (empty($id)) { - return false; - } - - $id = $this->cleanupId($id); - - $cache_complete = false; - $content = ''; - $expires_on = false; - - // We are assuming that most of the time cache will exists - $cacheFilePath = $this->cachePath . $id . '.php'; - if (self::$invalidateOpCacheBeforeRead) { - $this->opCacheInvalidate($cacheFilePath); - } - - $ok = @include($cacheFilePath); - - 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 (!Filesystem::isValidFilename($id)) { - throw new Exception("Invalid cache ID request $id"); - } - - return $id; - } - - /** - * A function to store content a cache entry. - * - * @param string $id The cache entry ID - * @param array $content The cache content - * @throws \Exception - * @return bool True if the entry was succesfully stored - */ - public function set($id, $content) - { - if (empty($id)) { - return false; - } - - if (!is_dir($this->cachePath)) { - Filesystem::mkdir($this->cachePath); - } - - if (!is_writable($this->cachePath)) { - return false; - } - - $id = $this->cleanupId($id); - $id = $this->cachePath . $id . '.php'; - - if (is_object($content)) { - throw new \Exception('You cannot use the CacheFile to cache an object, only arrays, strings and numbers.'); - } - - $cache_literal = $this->buildCacheLiteral($content); - - // Write cache to a temp file, then rename it, overwriting the old cache - // On *nix systems this should guarantee atomicity - $tmp_filename = tempnam($this->cachePath, 'tmp_'); - @chmod($tmp_filename, 0640); - if ($fp = @fopen($tmp_filename, 'wb')) { - @fwrite($fp, $cache_literal, strlen($cache_literal)); - @fclose($fp); - - if (!@rename($tmp_filename, $id)) { - // On some systems rename() doesn't overwrite destination - @unlink($id); - if (!@rename($tmp_filename, $id)) { - // Make sure that no temporary file is left over - // if the destination is not writable - @unlink($tmp_filename); - } - } - - $this->opCacheInvalidate($id); - - return true; - } - - return false; - } - - /** - * A function to delete a single cache entry - * - * @param string $id The cache entry ID - * @return bool True if the entry was succesfully deleted - */ - public function delete($id) - { - if (empty($id)) { - return false; - } - - $id = $this->cleanupId($id); - - $filename = $this->cachePath . $id . '.php'; - - if (file_exists($filename)) { - $this->opCacheInvalidate($filename); - @unlink($filename); - return true; - } - - return false; - } - - public function addOnDeleteCallback($onDeleteCallback) - { - self::$onDeleteCallback[] = $onDeleteCallback; - } - - /** - * A function to delete all cache entries in the directory - */ - public function deleteAll() - { - $self = $this; - $beforeUnlink = function ($path) use ($self) { - $self->opCacheInvalidate($path); - }; - - Filesystem::unlinkRecursive($this->cachePath, $deleteRootToo = false, $beforeUnlink); - - if (!empty(self::$onDeleteCallback)) { - foreach (self::$onDeleteCallback as $callback) { - $callback(); - } - } - } - - public function opCacheInvalidate($filepath) - { - if (is_file($filepath)) { - if (function_exists('opcache_invalidate')) { - @opcache_invalidate($filepath, $force = true); - } - if (function_exists('apc_delete_file')) { - @apc_delete_file($filepath); - } - } - } - - private function buildCacheLiteral($content) - { - $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 .= "?" . ">"; - - return $cache_literal; - } -} diff --git a/core/CacheId.php b/core/CacheId.php new file mode 100644 index 0000000000000000000000000000000000000000..e445424009c9faed96ce54a0167788e62de8a034 --- /dev/null +++ b/core/CacheId.php @@ -0,0 +1,30 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik; + +use Piwik\Translate; +use Piwik\Plugin\Manager; + +class CacheId +{ + public static function languageAware($cacheId) + { + return $cacheId . '-' . Translate::getLanguageLoaded(); + } + + public static function pluginAware($cacheId) + { + $pluginManager = Manager::getInstance(); + $pluginNames = $pluginManager->getLoadedPluginsName(); + $cacheId = $cacheId . '-' . md5(implode('', $pluginNames)); + $cacheId = self::languageAware($cacheId); + + return $cacheId; + } +} diff --git a/core/Columns/Updater.php b/core/Columns/Updater.php index 6c42ba0dff63f801aff531a9a584aa4696a5c131..4272f46f566c88ac161106515371068bac6153fb 100644 --- a/core/Columns/Updater.php +++ b/core/Columns/Updater.php @@ -14,14 +14,16 @@ use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Plugin\Dimension\ConversionDimension; use Piwik\Db; use Piwik\Updater as PiwikUpdater; -use Piwik\Cache\PersistentCache; use Piwik\Filesystem; +use Piwik\Cache as PiwikCache; /** * Class that handles dimension updates */ class Updater extends \Piwik\Updates { + private static $cacheId = 'AllDimensionModifyTime'; + /** * @var Updater */ @@ -315,15 +317,22 @@ class Updater extends \Piwik\Updates private static function cacheCurrentDimensionFileChanges() { $changes = self::getCurrentDimensionFileChanges(); - $persistentCache = new PersistentCache('AllDimensionModifyTime'); - $persistentCache->set($changes); + + $cache = self::buildCache(); + $cache->save(self::$cacheId, $changes); + } + + private static function buildCache() + { + return PiwikCache::getEagerCache(); } private static function getCachedDimensionFileChanges() { - $persistentCache = new PersistentCache('AllDimensionModifyTime'); - if ($persistentCache->has()) { - return $persistentCache->get(); + $cache = self::buildCache(); + + if ($cache->contains(self::$cacheId)) { + return $cache->fetch(self::$cacheId); } return array(); diff --git a/core/Container/StaticContainer.php b/core/Container/StaticContainer.php index b46f01e1ca77a1f5f8d1ce2dacb960b048a047e4..4e09d2bdb72d590fc400ac51475c7484d661f9c5 100644 --- a/core/Container/StaticContainer.php +++ b/core/Container/StaticContainer.php @@ -39,6 +39,11 @@ class StaticContainer return self::$container; } + public static function clearContainer() + { + self::$container = null; + } + /** * @link http://php-di.org/doc/container-configuration.html */ diff --git a/core/DeviceDetectorCache.php b/core/DeviceDetectorCache.php index ba65b82c9f639be3f99b44d4c31d61596d925182..c337b1b0a4e13371d56d2508b68108846ccebb3b 100644 --- a/core/DeviceDetectorCache.php +++ b/core/DeviceDetectorCache.php @@ -8,6 +8,7 @@ */ namespace Piwik; +use Piwik\Cache as PiwikCache; use Exception; /** @@ -17,10 +18,19 @@ use Exception; * * Static caching speeds up multiple detections in one request, which is the case when sending bulk requests */ -class DeviceDetectorCache extends CacheFile implements \DeviceDetector\Cache\CacheInterface +class DeviceDetectorCache implements \DeviceDetector\Cache\CacheInterface { protected static $staticCache = array(); + private $cache; + private $ttl; + + public function __construct($ttl = 300) + { + $this->ttl = (int) $ttl; + $this->cache = PiwikCache::getLazyCache(); + } + /** * Function to fetch a cache entry * @@ -33,13 +43,11 @@ class DeviceDetectorCache extends CacheFile implements \DeviceDetector\Cache\Cac return false; } - $id = $this->cleanupId($id); - if (array_key_exists($id, self::$staticCache)) { return self::$staticCache[$id]; } - return parent::get($id); + return $this->cache->fetch($id); } /** @@ -56,10 +64,9 @@ class DeviceDetectorCache extends CacheFile implements \DeviceDetector\Cache\Cac return false; } - $id = $this->cleanupId($id); - self::$staticCache[$id] = $content; - return parent::set($id, $content); + return $this->cache->save($id, $content, $this->ttl); } + } diff --git a/core/DeviceDetectorFactory.php b/core/DeviceDetectorFactory.php index c61da87a1407010e6739cca0e122516f81fdd752..c7962a96f056560e400301807745cb8e4505cc8b 100644 --- a/core/DeviceDetectorFactory.php +++ b/core/DeviceDetectorFactory.php @@ -28,7 +28,7 @@ class DeviceDetectorFactory $deviceDetector = new DeviceDetector($userAgent); $deviceDetector->discardBotInformation(); - $deviceDetector->setCache(new DeviceDetectorCache('tracker', 86400)); + $deviceDetector->setCache(new DeviceDetectorCache(86400)); $deviceDetector->parse(); self::$deviceDetectorInstances[$userAgent] = $deviceDetector; diff --git a/core/Filesystem.php b/core/Filesystem.php index 125c47bfda7192799a2c6dcdbf03713604a32c94..05e659a4bb7499da98a2c9c05d2e747085123c01 100644 --- a/core/Filesystem.php +++ b/core/Filesystem.php @@ -11,6 +11,7 @@ namespace Piwik; use Exception; use Piwik\Container\StaticContainer; use Piwik\Tracker\Cache; +use Piwik\Cache as PiwikCache; /** * Contains helper functions that deal with the filesystem. @@ -27,6 +28,7 @@ class Filesystem AssetManager::getInstance()->removeMergedAssets($pluginName); View::clearCompiledTemplates(); Cache::deleteTrackerCache(); + PiwikCache::flushAll(); self::clearPhpCaches(); } diff --git a/core/Metrics.php b/core/Metrics.php index 009fa361514ab05d44a590fc1260de79b0dc52f1..e76e8dd5e92cb245b25911faec5c7672b9f9b42c 100644 --- a/core/Metrics.php +++ b/core/Metrics.php @@ -8,8 +8,7 @@ */ namespace Piwik; -use Piwik\Cache\LanguageAwareStaticCache; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\Cache as PiwikCache; use Piwik\Metrics\Formatter; require_once PIWIK_INCLUDE_PATH . "/core/Piwik.php"; @@ -250,10 +249,11 @@ class Metrics public static function getDefaultMetricTranslations() { - $cache = new PluginAwareStaticCache('DefaultMetricTranslations'); + $cacheId = CacheId::pluginAware('DefaultMetricTranslations'); + $cache = PiwikCache::getTransientCache(); - if ($cache->has()) { - return $cache->get(); + if ($cache->contains($cacheId)) { + return $cache->fetch($cacheId); } $translations = array( @@ -302,17 +302,18 @@ class Metrics $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations); - $cache->set($translations); + $cache->save($cacheId, $translations); return $translations; } public static function getDefaultMetrics() { - $cache = new LanguageAwareStaticCache('DefaultMetrics'); + $cacheId = CacheId::languageAware('DefaultMetrics'); + $cache = PiwikCache::getTransientCache(); - if ($cache->has()) { - return $cache->get(); + if ($cache->contains($cacheId)) { + return $cache->fetch($cacheId); } $translations = array( @@ -323,17 +324,18 @@ class Metrics ); $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations); - $cache->set($translations); + $cache->save($cacheId, $translations); return $translations; } public static function getDefaultProcessedMetrics() { - $cache = new LanguageAwareStaticCache('DefaultProcessedMetrics'); + $cacheId = CacheId::languageAware('DefaultProcessedMetrics'); + $cache = PiwikCache::getTransientCache(); - if ($cache->has()) { - return $cache->get(); + if ($cache->contains($cacheId)) { + return $cache->fetch($cacheId); } $translations = array( @@ -345,7 +347,7 @@ class Metrics ); $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations); - $cache->set($translations); + $cache->save($cacheId, $translations); return $translations; } @@ -383,10 +385,11 @@ class Metrics public static function getDefaultMetricsDocumentation() { - $cache = new PluginAwareStaticCache('DefaultMetricsDocumentation'); + $cacheId = CacheId::pluginAware('DefaultMetricsDocumentation'); + $cache = PiwikCache::getTransientCache(); - if ($cache->has()) { - return $cache->get(); + if ($cache->contains($cacheId)) { + return $cache->fetch($cacheId); } $translations = array( @@ -412,7 +415,7 @@ class Metrics $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations); - $cache->set($translations); + $cache->save($cacheId, $translations); return $translations; } diff --git a/core/Plugin.php b/core/Plugin.php index f30c3ed23a2283cb096a4c84d43d9b4ac85f3169..fdef9f5dc8bbf8a1546fe0a5ccfd66fbb50a83a9 100644 --- a/core/Plugin.php +++ b/core/Plugin.php @@ -8,7 +8,6 @@ */ namespace Piwik; -use Piwik\Cache\PersistentCache; use Piwik\Plugin\Dependency; use Piwik\Plugin\MetadataLoader; @@ -108,10 +107,10 @@ class Plugin /** * As the cache is used quite often we avoid having to create instances all the time. We reuse it which is not - * perfect but efficient. If the cache is used we need to make sure to call setCacheKey() before usage as there + * perfect but efficient. If the cache is used we need to make sure to call setId() before usage as there * is maybe a different key set since last usage. * - * @var PersistentCache + * @var \Piwik\Cache\Eager */ private $cache; @@ -131,12 +130,12 @@ class Plugin } $this->pluginName = $pluginName; - $cache = new PersistentCache('Plugin' . $pluginName . 'Metadata'); + $cacheId = 'Plugin' . $pluginName . 'Metadata'; + $cache = Cache::getEagerCache(); - if ($cache->has()) { - $this->pluginInformation = $cache->get(); + if ($cache->contains($cacheId)) { + $this->pluginInformation = $cache->fetch($cacheId); } else { - $metadataLoader = new MetadataLoader($pluginName); $this->pluginInformation = $metadataLoader->load(); @@ -144,14 +143,14 @@ class Plugin throw new \Exception('Plugin ' . $pluginName . ' has defined the method getInformation() and as well as having a plugin.json file. Please delete the getInformation() method from the plugin class. Alternatively, you may delete the plugin directory from plugins/' . $pluginName); } - $cache->set($this->pluginInformation); + $cache->save($cacheId, $this->pluginInformation); } } private function createCacheIfNeeded() { if (is_null($this->cache)) { - $this->cache = new PersistentCache('Plugin' . $this->pluginName); + $this->cache = Cache::getEagerCache(); } } @@ -321,12 +320,12 @@ class Plugin { $this->createCacheIfNeeded(); - $this->cache->setCacheKey('Plugin' . $this->pluginName . $componentName . $expectedSubclass); + $cacheId = 'Plugin' . $this->pluginName . $componentName . $expectedSubclass; $componentFile = sprintf('%s/plugins/%s/%s.php', PIWIK_INCLUDE_PATH, $this->pluginName, $componentName); - if ($this->cache->has()) { - $klassName = $this->cache->get(); + if ($this->cache->contains($cacheId)) { + $klassName = $this->cache->fetch($cacheId); if (empty($klassName)) { return; // might by "false" in case has no menu, widget, ... @@ -337,7 +336,7 @@ class Plugin } } else { - $this->cache->set(false); // prevent from trying to load over and over again for instance if there is no Menu for a plugin + $this->cache->save($cacheId, false); // prevent from trying to load over and over again for instance if there is no Menu for a plugin if (!file_exists($componentFile)) { return; @@ -357,7 +356,7 @@ class Plugin return; } - $this->cache->set($klassName); + $this->cache->save($cacheId, $klassName); } return new $klassName; @@ -367,10 +366,10 @@ class Plugin { $this->createCacheIfNeeded(); - $this->cache->setCacheKey('Plugin' . $this->pluginName . $directoryWithinPlugin . $expectedSubclass); + $cacheId = 'Plugin' . $this->pluginName . $directoryWithinPlugin . $expectedSubclass; - if ($this->cache->has()) { - $components = $this->cache->get(); + if ($this->cache->contains($cacheId)) { + $components = $this->cache->fetch($cacheId); if ($this->includeComponents($components)) { return $components; @@ -381,7 +380,7 @@ class Plugin $components = $this->doFindMultipleComponents($directoryWithinPlugin, $expectedSubclass); - $this->cache->set($components); + $this->cache->save($cacheId, $components); return $components; } diff --git a/core/Plugin/Dimension/ActionDimension.php b/core/Plugin/Dimension/ActionDimension.php index bc09b01fc398ace7a1e55e20ae1077d41865f180..f0daaf547c84577905bb4b2c9e000ef6224f4292 100644 --- a/core/Plugin/Dimension/ActionDimension.php +++ b/core/Plugin/Dimension/ActionDimension.php @@ -8,7 +8,8 @@ */ namespace Piwik\Plugin\Dimension; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\CacheId; +use Piwik\Cache as PiwikCache; use Piwik\Columns\Dimension; use Piwik\Plugin\Manager as PluginManager; use Piwik\Plugin\Segment; @@ -212,9 +213,10 @@ abstract class ActionDimension extends Dimension */ public static function getAllDimensions() { - $cache = new PluginAwareStaticCache('ActionDimensions'); + $cacheId = CacheId::pluginAware('ActionDimensions'); + $cache = PiwikCache::getTransientCache(); - if (!$cache->has()) { + if (!$cache->contains($cacheId)) { $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated(); $instances = array(); @@ -225,10 +227,10 @@ abstract class ActionDimension extends Dimension } } - $cache->set($instances); + $cache->save($cacheId, $instances); } - return $cache->get(); + return $cache->fetch($cacheId); } /** diff --git a/core/Plugin/Dimension/ConversionDimension.php b/core/Plugin/Dimension/ConversionDimension.php index 7cf2a813c0ed2114e3933b7e3c4f9846b2b74ad2..34a800611193ff5689e26a190ff4d6f1e8929cbd 100644 --- a/core/Plugin/Dimension/ConversionDimension.php +++ b/core/Plugin/Dimension/ConversionDimension.php @@ -8,7 +8,8 @@ */ namespace Piwik\Plugin\Dimension; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\CacheId; +use Piwik\Cache as PiwikCache; use Piwik\Columns\Dimension; use Piwik\Plugin\Manager as PluginManager; use Piwik\Common; @@ -155,9 +156,10 @@ abstract class ConversionDimension extends Dimension */ public static function getAllDimensions() { - $cache = new PluginAwareStaticCache('ConversionDimensions'); + $cacheId = CacheId::pluginAware('ConversionDimensions'); + $cache = PiwikCache::getTransientCache(); - if (!$cache->has()) { + if (!$cache->contains($cacheId)) { $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated(); $instances = array(); @@ -168,10 +170,10 @@ abstract class ConversionDimension extends Dimension } } - $cache->set($instances); + $cache->save($cacheId, $instances); } - return $cache->get(); + return $cache->fetch($cacheId); } /** diff --git a/core/Plugin/Dimension/VisitDimension.php b/core/Plugin/Dimension/VisitDimension.php index b9aa3a9b2aa4235afe5f04b8eeba99e0e4b7025a..97dfd6f57b2e31a6e0906d2bf680edea3d415b24 100644 --- a/core/Plugin/Dimension/VisitDimension.php +++ b/core/Plugin/Dimension/VisitDimension.php @@ -8,7 +8,8 @@ */ namespace Piwik\Plugin\Dimension; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\CacheId; +use Piwik\Cache as PiwikCache; use Piwik\Columns\Dimension; use Piwik\Common; use Piwik\Db; @@ -294,9 +295,10 @@ abstract class VisitDimension extends Dimension */ public static function getAllDimensions() { - $cache = new PluginAwareStaticCache('VisitDimensions'); + $cacheId = CacheId::pluginAware('VisitDimensions'); + $cache = PiwikCache::getTransientCache(); - if (!$cache->has()) { + if (!$cache->contains($cacheId)) { $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated(); $instances = array(); @@ -309,10 +311,10 @@ abstract class VisitDimension extends Dimension usort($instances, array('self', 'sortByRequiredFields')); - $cache->set($instances); + $cache->save($cacheId, $instances); } - return $cache->get(); + return $cache->fetch($cacheId); } /** diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php index a85784f6d46b9caf509d0fa5ddf7a9e498b0f909..bca24d8b5ad676e9fc56dc933473ae5b8e8a0138 100644 --- a/core/Plugin/Manager.php +++ b/core/Plugin/Manager.php @@ -9,8 +9,7 @@ namespace Piwik\Plugin; -use Piwik\Cache\PersistentCache; -use Piwik\CacheFile; +use Piwik\Cache; use Piwik\Columns\Dimension; use Piwik\Common; use Piwik\Config as PiwikConfig; @@ -119,10 +118,11 @@ class Manager extends Singleton */ public function loadTrackerPlugins() { - $cache = new PersistentCache('PluginsTracker'); + $cacheId = 'PluginsTracker'; + $cache = Cache::getEagerCache(); - if ($cache->has()) { - $pluginsTracker = $cache->get(); + if ($cache->contains($cacheId)) { + $pluginsTracker = $cache->fetch($cacheId); } else { $this->unloadPlugins(); @@ -137,7 +137,7 @@ class Manager extends Singleton } if (!empty($pluginsTracker)) { - $cache->set($pluginsTracker); + $cache->save($cacheId, $pluginsTracker); } } @@ -697,7 +697,6 @@ class Manager extends Singleton $language = Translate::getLanguageToLoad(); } - $cache = new CacheFile('tracker', 43200); // ttl=12hours $cacheKey = 'PluginTranslations'; if (!empty($language)) { @@ -709,11 +708,12 @@ class Manager extends Singleton $cacheKey .= '-' . md5(implode('', $this->getLoadedPluginsName())); } - $translations = $cache->get($cacheKey); + $cache = Cache::getLazyCache(); + $translations = $cache->fetch($cacheKey); if (!empty($translations) && is_array($translations) && - !Development::isEnabled()) { + !Development::isEnabled()) { // TODO remove this one here once we have environments in DI Translate::mergeTranslationArray($translations); return; @@ -734,7 +734,7 @@ class Manager extends Singleton } } - $cache->set($cacheKey, $translations); + $cache->save($cacheKey, $translations, 43200); // ttl=12hours } /** diff --git a/core/Plugin/Report.php b/core/Plugin/Report.php index 1824b6774f1f946151620d5f69a37f2e5a7367a6..af61a33a0a45f5a45f8b67d205c3a67b7eb69fb9 100644 --- a/core/Plugin/Report.php +++ b/core/Plugin/Report.php @@ -10,11 +10,12 @@ namespace Piwik\Plugin; use Piwik\API\Proxy; use Piwik\API\Request; -use Piwik\Cache\LanguageAwareStaticCache; +use Piwik\CacheId; use Piwik\Columns\Dimension; use Piwik\DataTable; use Piwik\Menu\MenuReporting; use Piwik\Metrics; +use Piwik\Cache as PiwikCache; use Piwik\Piwik; use Piwik\Plugin\Manager as PluginManager; use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable; @@ -735,9 +736,10 @@ class Report public static function getAllReports() { $reports = self::getAllReportClasses(); - $cache = new LanguageAwareStaticCache('Reports' . implode('', $reports)); + $cacheId = CacheId::languageAware('Reports' . md5(implode('', $reports))); + $cache = PiwikCache::getTransientCache(); - if (!$cache->has()) { + if (!$cache->contains($cacheId)) { $instances = array(); foreach ($reports as $report) { @@ -746,10 +748,10 @@ class Report usort($instances, array('self', 'sort')); - $cache->set($instances); + $cache->save($cacheId, $instances); } - return $cache->get(); + return $cache->fetch($cacheId); } /** @@ -785,10 +787,10 @@ class Report foreach ($metricsToTranslate as $metric) { if ($metric instanceof Metric) { - $metricName = $metric->getName(); + $metricName = $metric->getName(); $translation = $metric->getTranslatedName(); } else { - $metricName = $metric; + $metricName = $metric; $translation = @$translations[$metric]; } diff --git a/core/Tracker/Cache.php b/core/Tracker/Cache.php index b8f0413c63cc686e6fb541f1425f41f3b5a72b24..3fa360986e34523c3670f01c10209a80e047b9fd 100644 --- a/core/Tracker/Cache.php +++ b/core/Tracker/Cache.php @@ -10,7 +10,7 @@ namespace Piwik\Tracker; use Piwik\Access; use Piwik\ArchiveProcessor\Rules; -use Piwik\CacheFile; +use Piwik\Cache as PiwikCache; use Piwik\Common; use Piwik\Config; use Piwik\Option; @@ -23,19 +23,29 @@ use Piwik\Tracker; */ class Cache { + private static $cacheIdGeneral = 'general'; + /** * Public for tests only - * @var CacheFile + * @var \Piwik\Cache\Lazy */ - public static $trackerCache = null; + public static $cache; - protected static function getInstance() + /** + * @return \Piwik\Cache\Lazy + */ + private static function getCache() { - if (is_null(self::$trackerCache)) { - $ttl = Config::getInstance()->Tracker['tracker_cache_file_ttl']; - self::$trackerCache = new CacheFile('tracker', $ttl); + if (is_null(self::$cache)) { + self::$cache = PiwikCache::getLazyCache(); } - return self::$trackerCache; + + return self::$cache; + } + + private static function getTtl() + { + return Config::getInstance()->Tracker['tracker_cache_file_ttl']; } /** @@ -55,8 +65,9 @@ class Cache return array(); } - $cache = self::getInstance(); - $cacheContent = $cache->get($idSite); + $cache = self::getCache(); + $cacheId = $idSite; + $cacheContent = $cache->fetch($cacheId); if (false !== $cacheContent) { return $cacheContent; @@ -91,7 +102,7 @@ class Cache // 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); + $cache->save($cacheId, $content, self::getTtl()); } return $content; @@ -102,7 +113,7 @@ class Cache */ public static function clearCacheGeneral() { - self::getInstance()->delete('general'); + self::getCache()->delete(self::$cacheIdGeneral); } /** @@ -113,10 +124,8 @@ class Cache */ public static function getCacheGeneral() { - $cache = self::getInstance(); - $cacheId = 'general'; - - $cacheContent = $cache->get($cacheId); + $cache = self::getCache(); + $cacheContent = $cache->fetch(self::$cacheIdGeneral); if (false !== $cacheContent) { return $cacheContent; @@ -162,11 +171,9 @@ class Cache */ public static function setCacheGeneral($value) { - $cache = self::getInstance(); - $cacheId = 'general'; - $cache->set($cacheId, $value); + $cache = self::getCache(); - return true; + return $cache->save(self::$cacheIdGeneral, $value, self::getTtl()); } /** @@ -193,8 +200,7 @@ class Cache */ public static function deleteCacheWebsiteAttributes($idSite) { - $idSite = (int)$idSite; - self::getInstance()->delete($idSite); + self::getCache()->delete((int) $idSite); } /** @@ -202,6 +208,6 @@ class Cache */ public static function deleteTrackerCache() { - self::getInstance()->deleteAll(); + self::getCache()->flushAll(); } } diff --git a/core/Tracker/SettingsStorage.php b/core/Tracker/SettingsStorage.php index 2e3ac5e17d2b90f0c3d8e3d3293866bf4dde2e29..7ffb3de8727e44f3524bd9c48e433609e3de854f 100644 --- a/core/Tracker/SettingsStorage.php +++ b/core/Tracker/SettingsStorage.php @@ -9,9 +9,9 @@ namespace Piwik\Tracker; -use Piwik\Cache\PersistentCache; use Piwik\Settings\Storage; use Piwik\Tracker; +use Piwik\Cache as PiwikCache; /** * Loads settings from tracker cache instead of database. If not yet present in tracker cache will cache it. @@ -20,14 +20,15 @@ class SettingsStorage extends Storage { protected function loadSettings() { + $cacheId = $this->getOptionKey(); $cache = $this->getCache(); - if ($cache->has()) { - $settings = $cache->get(); + if ($cache->contains($cacheId)) { + $settings = $cache->fetch($cacheId); } else { $settings = parent::loadSettings(); - $cache->set($settings); + $cache->save($cacheId, $settings); } return $settings; @@ -41,13 +42,18 @@ class SettingsStorage extends Storage private function getCache() { - return new PersistentCache($this->getOptionKey()); + return self::buildCache($this->getOptionKey()); } public static function clearCache() { Cache::deleteTrackerCache(); - PersistentCache::_reset(); + self::buildCache()->flushAll(); + } + + private static function buildCache() + { + return PiwikCache::getEagerCache(); } } diff --git a/core/WidgetsList.php b/core/WidgetsList.php index 943dfceb68a2879b54693ae2d97137cb82a07c41..c474061606d1a1140f258ebdf57c7672a7783408 100644 --- a/core/WidgetsList.php +++ b/core/WidgetsList.php @@ -8,7 +8,7 @@ */ namespace Piwik; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\Cache as PiwikCache; use Piwik\Plugin\Report; use Piwik\Plugin\Widgets; @@ -63,9 +63,11 @@ class WidgetsList extends Singleton */ public static function get() { - $cache = self::getCacheForCompleteList(); - if (!self::$listCacheToBeInvalidated && $cache->has()) { - return $cache->get(); + $cache = self::getCacheForCompleteList(); + $cacheId = self::getCacheId(); + + if (!self::$listCacheToBeInvalidated && $cache->contains($cacheId)) { + return $cache->fetch($cacheId); } self::addWidgets(); @@ -83,7 +85,7 @@ class WidgetsList extends Singleton $widgets[$category] = $v; } - $cache->set($widgets); + $cache->save($cacheId, $widgets); self::$listCacheToBeInvalidated = false; return $widgets; @@ -270,11 +272,16 @@ class WidgetsList extends Singleton { self::$widgets = array(); self::$hookCalled = false; - self::getCacheForCompleteList()->clear(); + self::getCacheForCompleteList()->delete(self::getCacheId()); + } + + private static function getCacheId() + { + return CacheId::pluginAware('WidgetsList'); } private static function getCacheForCompleteList() { - return new PluginAwareStaticCache('WidgetsList'); + return PiwikCache::getTransientCache(); } } diff --git a/plugins/API/Menu.php b/plugins/API/Menu.php index b01c686ac0432ad6c5f142aaa553779ac2e70a9f..a0f71ddf542ef7cb2d9a7c1b82a80eddc05a228b 100644 --- a/plugins/API/Menu.php +++ b/plugins/API/Menu.php @@ -43,7 +43,7 @@ class Menu extends \Piwik\Plugin\Menu } $ua = new OperatingSystem($_SERVER['HTTP_USER_AGENT']); - $ua->setCache(new DeviceDetectorCache('tracker', 86400)); + $ua->setCache(new DeviceDetectorCache(86400)); $parsedOS = $ua->parse(); if (!empty($parsedOS['short_name']) && in_array($parsedOS['short_name'], array(self::DD_SHORT_NAME_ANDROID, self::DD_SHORT_NAME_IOS))) { diff --git a/plugins/API/ProcessedReport.php b/plugins/API/ProcessedReport.php index a5ba529658c72cfe379f3f4e60543a57d62a075a..bd1a885f4d93fd9fd211d30e116ca109d64d59dd 100644 --- a/plugins/API/ProcessedReport.php +++ b/plugins/API/ProcessedReport.php @@ -11,7 +11,8 @@ namespace Piwik\Plugins\API; use Exception; use Piwik\API\Request; use Piwik\Archive\DataTableFactory; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\CacheId; +use Piwik\Cache as PiwikCache; use Piwik\Common; use Piwik\DataTable; use Piwik\DataTable\Row; @@ -154,10 +155,11 @@ class ProcessedReport // as they cache key contains a lot of information there would be an even better cache result by caching parts of // this huge method separately but that makes it also more complicated. leaving it like this for now. $key = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports); - $cache = new PluginAwareStaticCache($key); + $key = CacheId::pluginAware($key); + $cache = PiwikCache::getTransientCache(); - if ($cache->has()) { - return $cache->get(); + if ($cache->contains($key)) { + return $cache->fetch($key); } $parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date); @@ -332,7 +334,7 @@ class ProcessedReport } $actualReports = array_values($availableReports); - $cache->set($actualReports); + $cache->save($key, $actualReports); return $actualReports; // make sure array has contiguous key values } diff --git a/plugins/CorePluginsAdmin/MarketplaceApiClient.php b/plugins/CorePluginsAdmin/MarketplaceApiClient.php index 346b15770f743b7a4ddc3a91c54a5690178262a0..6472da3deac67322ebfaf8bac8642974ffa45116 100644 --- a/plugins/CorePluginsAdmin/MarketplaceApiClient.php +++ b/plugins/CorePluginsAdmin/MarketplaceApiClient.php @@ -8,7 +8,7 @@ */ namespace Piwik\Plugins\CorePluginsAdmin; -use Piwik\CacheFile; +use Piwik\Cache; use Piwik\Http; use Piwik\Version; @@ -22,20 +22,10 @@ class MarketplaceApiClient private $domain = 'http://plugins.piwik.org'; - /** - * @var CacheFile - */ - private $cache = null; - - public function __construct() - { - $this->cache = new CacheFile('marketplace', self::CACHE_TIMEOUT_IN_SECONDS); - } - public static function clearAllCacheEntries() { - $cache = new CacheFile('marketplace'); - $cache->deleteAll(); + $cache = Cache::getLazyCache(); + $cache->flushAll(); } public function getPluginInfo($name) @@ -137,7 +127,10 @@ class MarketplaceApiClient { ksort($params); $query = http_build_query($params); - $result = $this->getCachedResult($action, $query); + + $cacheId = $this->getCacheKey($action, $query); + $cache = $this->buildCache(); + $result = $cache->fetch($cacheId); if (false === $result) { $endpoint = $this->domain . '/api/1.0/'; @@ -155,29 +148,20 @@ class MarketplaceApiClient throw new MarketplaceApiException($result['error']); } - $this->cacheResult($action, $query, $result); + $cache->save($cacheId, $result, self::CACHE_TIMEOUT_IN_SECONDS); } return $result; } - private function getCachedResult($action, $query) - { - $cacheKey = $this->getCacheKey($action, $query); - - return $this->cache->get($cacheKey); - } - - private function cacheResult($action, $query, $result) + private function buildCache() { - $cacheKey = $this->getCacheKey($action, $query); - - $this->cache->set($cacheKey, $result); + return Cache::getLazyCache(); } private function getCacheKey($action, $query) { - return sprintf('api.1.0.%s.%s', str_replace('/', '.', $action), md5($query)); + return sprintf('marketplace.api.1.0.%s.%s', str_replace('/', '.', $action), md5($query)); } /** diff --git a/plugins/CustomAlerts b/plugins/CustomAlerts index e886aa43f4c248bf6aaeeef05885f4acdf190a82..8d6dd8428317c24e997f335f27f1d3fb522c1935 160000 --- a/plugins/CustomAlerts +++ b/plugins/CustomAlerts @@ -1 +1 @@ -Subproject commit e886aa43f4c248bf6aaeeef05885f4acdf190a82 +Subproject commit 8d6dd8428317c24e997f335f27f1d3fb522c1935 diff --git a/plugins/Goals/API.php b/plugins/Goals/API.php index acd99d9a8272ac0e382e60b5d1537d9a35cf4c54..1349c50e962e8289495de942344ce44077f28108 100644 --- a/plugins/Goals/API.php +++ b/plugins/Goals/API.php @@ -10,7 +10,8 @@ namespace Piwik\Plugins\Goals; use Exception; use Piwik\Archive; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\CacheId; +use Piwik\Cache as PiwikCache; use Piwik\Common; use Piwik\DataTable; use Piwik\Db; @@ -55,8 +56,9 @@ class API extends \Piwik\Plugin\API */ public function getGoals($idSite) { - $cache = $this->getGoalsInfoStaticCache($idSite); - if (!$cache->has()) { + $cacheId = self::getCacheId($idSite); + $cache = $this->getGoalsInfoStaticCache(); + if (!$cache->contains($cacheId)) { $idSite = Site::getIdSitesFromIdSitesString($idSite); if (empty($idSite)) { @@ -77,9 +79,10 @@ class API extends \Piwik\Plugin\API $cleanedGoals[$goal['idgoal']] = $goal; } - $cache->set($cleanedGoals); + $cache->save($cacheId, $cleanedGoals); } - return $cache->get(); + + return $cache->fetch($cacheId); } /** @@ -119,7 +122,7 @@ class API extends \Piwik\Plugin\API $idGoal = $this->getModel()->createGoalForSite($idSite, $goal); - $this->getGoalsInfoStaticCache($idSite)->clear(); + $this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite)); Cache::regenerateCacheWebsiteAttributes($idSite); return $idGoal; @@ -166,7 +169,7 @@ class API extends \Piwik\Plugin\API 'revenue' => $revenue, )); - $this->getGoalsInfoStaticCache($idSite)->clear(); + $this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite)); Cache::regenerateCacheWebsiteAttributes($idSite); } @@ -206,7 +209,7 @@ class API extends \Piwik\Plugin\API $this->getModel()->deleteGoal($idSite, $idGoal); $this->getModel()->deleteGoalConversions($idSite, $idGoal); - $this->getGoalsInfoStaticCache($idSite)->clear(); + $this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite)); Cache::regenerateCacheWebsiteAttributes($idSite); } @@ -567,8 +570,14 @@ class API extends \Piwik\Plugin\API } } - private function getGoalsInfoStaticCache($idSite) + + private function getCacheId($idSite) + { + return CacheId::pluginAware('Goals.getGoals.' . $idSite); + } + + private function getGoalsInfoStaticCache() { - return new PluginAwareStaticCache("Goals.getGoals.$idSite"); + return PiwikCache::getTransientCache(); } } diff --git a/plugins/Insights/tests/Integration/ApiTest.php b/plugins/Insights/tests/Integration/ApiTest.php index dfa76dcde17c245034c2966a971c087cfed09aa9..6eeac84700809ee2fabf189284b88cbf47c3035a 100644 --- a/plugins/Insights/tests/Integration/ApiTest.php +++ b/plugins/Insights/tests/Integration/ApiTest.php @@ -8,8 +8,7 @@ namespace Piwik\Plugins\Insights\tests; use Piwik\API\Request as ApiRequest; -use Piwik\Cache\PluginAwareStaticCache; -use Piwik\Cache\StaticCache; +use Piwik\Cache as PiwikCache; use Piwik\DataTable; use Piwik\DataTable\Row; use Piwik\Plugins\Insights\API; @@ -40,8 +39,7 @@ class ApiTest extends SystemTestCase { parent::setUp(); - StaticCache::clearAll(); - PluginAwareStaticCache::clearAll(); + PiwikCache::flushAll(); Translate::reloadLanguage('en'); $this->api = API::getInstance(); diff --git a/plugins/LanguagesManager/API.php b/plugins/LanguagesManager/API.php index 2c8d74978a316d9144f8c829e418b5cd17e7ab6f..f3f50ad57fb7d627e79d352ba6bbbe728b56351e 100644 --- a/plugins/LanguagesManager/API.php +++ b/plugins/LanguagesManager/API.php @@ -9,10 +9,10 @@ */ namespace Piwik\Plugins\LanguagesManager; -use Piwik\Cache\PersistentCache; use Piwik\Db; use Piwik\Filesystem; use Piwik\Piwik; +use Piwik\Cache as PiwikCache; use Piwik\Plugin\Manager as PluginManager; /** @@ -272,10 +272,11 @@ class API extends \Piwik\Plugin\API return; } - $cache = new PersistentCache('availableLanguages'); + $cacheId = 'availableLanguages'; + $cache = PiwikCache::getEagerCache(); - if ($cache->has()) { - $languagesInfo = $cache->get(); + if ($cache->contains($cacheId)) { + $languagesInfo = $cache->fetch($cacheId); } else { $filenames = $this->getAvailableLanguages(); $languagesInfo = array(); @@ -289,7 +290,7 @@ class API extends \Piwik\Plugin\API ); } - $cache->set($languagesInfo); + $cache->save($cacheId, $languagesInfo); } $this->availableLanguageNames = $languagesInfo; diff --git a/plugins/SitesManager/SiteUrls.php b/plugins/SitesManager/SiteUrls.php index b859085d921c810749c08a04c0c046a2bd4ce10e..a1fac67a89e349c96238935d409177f3a3eeb020 100644 --- a/plugins/SitesManager/SiteUrls.php +++ b/plugins/SitesManager/SiteUrls.php @@ -8,26 +8,25 @@ */ namespace Piwik\Plugins\SitesManager; -use Piwik\CacheFile; -use Piwik\Development; +use Piwik\Cache; class SiteUrls { - private static $allUrlsCacheKey = 'allSiteUrlsPerSite'; + private static $cacheId = 'allSiteUrlsPerSite'; public static function clearSitesCache() { - self::getCache()->delete(self::$allUrlsCacheKey); + self::getCache()->delete(self::$cacheId); } public function getAllCachedSiteUrls() { $cache = $this->getCache(); - $siteUrls = $cache->get(self::$allUrlsCacheKey); + $siteUrls = $cache->fetch(self::$cacheId); - if (empty($siteUrls) || Development::isEnabled()) { + if (empty($siteUrls)) { $siteUrls = $this->getAllSiteUrls(); - $cache->set(self::$allUrlsCacheKey, $siteUrls); + $cache->save(self::$cacheId, $siteUrls, 1800); } return $siteUrls; @@ -53,6 +52,6 @@ class SiteUrls private static function getCache() { - return new CacheFile('tracker', 1800); + return Cache::getLazyCache(); } } diff --git a/plugins/SitesManager/tests/Integration/SiteUrlsTest.php b/plugins/SitesManager/tests/Integration/SiteUrlsTest.php index 4614f7cecea2a186c547403c3d1cff62c2728d1d..f9362ae2f4b32bab59f4fef058ecc81dc3f3d4b5 100644 --- a/plugins/SitesManager/tests/Integration/SiteUrlsTest.php +++ b/plugins/SitesManager/tests/Integration/SiteUrlsTest.php @@ -7,7 +7,7 @@ */ namespace Piwik\Plugins\SitesManager\tests\Integration; -use Piwik\CacheFile; +use Piwik\Cache; use Piwik\Plugins\SitesManager\API; use Piwik\Plugins\SitesManager\SiteUrls; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -111,8 +111,8 @@ class SiteUrlsTest extends IntegrationTestCase public function testGetAllCachedSiteUrls_ShouldReadFromTheCacheFile() { $urlsToFake = array(1 => 'Whatever'); - $cache = new CacheFile('tracker', 600); - $cache->set('allSiteUrlsPerSite', $urlsToFake); + $cache = $this->buildCache(); + $cache->save('allSiteUrlsPerSite', $urlsToFake, 600); $actual = $this->siteUrls->getAllCachedSiteUrls(); @@ -138,9 +138,14 @@ class SiteUrlsTest extends IntegrationTestCase private function assertValueInCache($value) { - $cache = new CacheFile('tracker', 600); - $siteUrls = $cache->get('allSiteUrlsPerSite'); + $cache = $this->buildCache(); + $siteUrls = $cache->fetch('allSiteUrlsPerSite'); $this->assertEquals($value, $siteUrls); } + + private function buildCache() + { + return Cache::getLazyCache(); + } } diff --git a/tests/LocalTracker.php b/tests/LocalTracker.php index a86d3a565cc4b01ba428e378e1bb227738ba3699..98ef3e65019c37b93dbb2b50f0338c9de5dc46b2 100755 --- a/tests/LocalTracker.php +++ b/tests/LocalTracker.php @@ -40,7 +40,7 @@ class Piwik_LocalTracker extends PiwikTracker } // unset cached values - Cache::$trackerCache = null; + Cache::$cache = null; // save some values $plugins = Config::getInstance()->Plugins['Plugins']; diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php index a2d6a6327a819ad67dd9f186d933debd74fa7a4e..4f7aac46fb6db773eb07d8f0e73350ba864d5b85 100644 --- a/tests/PHPUnit/Framework/Fixture.php +++ b/tests/PHPUnit/Framework/Fixture.php @@ -8,8 +8,8 @@ namespace Piwik\Tests\Framework; use Piwik\Access; -use Piwik\Cache\StaticCache; -use Piwik\CacheFile; +use Piwik\Cache\Backend\File; +use Piwik\Cache as PiwikCache; use Piwik\Common; use Piwik\Config; use Piwik\DataAccess\ArchiveTableCreator; @@ -224,7 +224,7 @@ class Fixture extends \PHPUnit_Framework_Assert FakeAccess::$superUserLogin = 'superUserLogin'; SettingsPiwik::$cachedKnownSegmentsToArchive = null; - CacheFile::$invalidateOpCacheBeforeRead = true; + File::$invalidateOpCacheBeforeRead = true; if ($this->configureComponents) { IPAnonymizer::deactivate(); @@ -244,7 +244,7 @@ class Fixture extends \PHPUnit_Framework_Assert $this->getTestEnvironment()->executeSetupTestEnvHook(); Piwik_TestingEnvironment::addSendMailHook(); - StaticCache::clearAll(); + PiwikCache::getTransientCache()->flushAll(); if ($this->overwriteExisting || !$this->isFixtureSetUp() @@ -304,6 +304,8 @@ class Fixture extends \PHPUnit_Framework_Assert Option::clearCache(); Site::clearCache(); Cache::deleteTrackerCache(); + PiwikCache::getTransientCache()->flushAll(); + PiwikCache::getEagerCache()->flushAll(); Config::getInstance()->clear(); ArchiveTableCreator::clear(); \Piwik\Plugins\ScheduledReports\API::$cache = array(); diff --git a/tests/PHPUnit/Framework/TestCase/IntegrationTestCase.php b/tests/PHPUnit/Framework/TestCase/IntegrationTestCase.php index becfac3a1871a6263fe742dfe55501fcb6b59935..2a782b67c3e68b1cb5f47f3d3360a86db15322bc 100644 --- a/tests/PHPUnit/Framework/TestCase/IntegrationTestCase.php +++ b/tests/PHPUnit/Framework/TestCase/IntegrationTestCase.php @@ -8,10 +8,10 @@ namespace Piwik\Tests\Framework\TestCase; -use Piwik\Cache\StaticCache; use Piwik\Config; use Piwik\Db; use Piwik\Tests\Framework\Fixture; +use Piwik\Cache as PiwikCache; /** * Tests extending IntegrationTestCase are much slower to run: the setUp will @@ -78,7 +78,8 @@ abstract class IntegrationTestCase extends SystemTestCase self::restoreDbTables(self::$tableData); } - StaticCache::clearAll(); + PiwikCache::getEagerCache()->flushAll(); + PiwikCache::getTransientCache()->flushAll(); } /** @@ -86,8 +87,6 @@ abstract class IntegrationTestCase extends SystemTestCase */ public function tearDown() { - StaticCache::clearAll(); - self::$fixture->clearInMemoryCaches(); parent::tearDown(); diff --git a/tests/PHPUnit/Integration/CacheIdTest.php b/tests/PHPUnit/Integration/CacheIdTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ebdfd9c0351e170b9f40c430ac96361e3fe93808 --- /dev/null +++ b/tests/PHPUnit/Integration/CacheIdTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Tests\Integration; + +use Piwik\CacheId; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; +use Piwik\Translate; + +/** + * @group Cache + * @group CacheId + */ +class CacheIdTest extends IntegrationTestCase +{ + public function setUp() + { + Translate::loadEnglishTranslation(); + } + + public function tearDown() + { + Translate::unloadEnglishTranslation(); + } + + public function test_languageAware_shouldAppendTheLoadedLanguage() + { + $result = CacheId::languageAware('myrandomkey'); + + $this->assertEquals('myrandomkey-en', $result); + } + + public function test_pluginAware_shouldAppendLoadedPluginsAndLanguage() + { + $result = CacheId::pluginAware('myrandomkey'); + + // if this test fails most likely there is a new plugin loaded and you simple have to update the cache id. + $this->assertEquals('myrandomkey-8f88a1dea9163e86178e69a1293ec084-en', $result); + } +} diff --git a/tests/PHPUnit/Integration/CacheTest.php b/tests/PHPUnit/Integration/CacheTest.php new file mode 100644 index 0000000000000000000000000000000000000000..083e54fd0c05cd9440d2e1ffff1cec0dec30f988 --- /dev/null +++ b/tests/PHPUnit/Integration/CacheTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Tests\Integration; + +use Piwik\Cache; +use Piwik\Container\StaticContainer; +use Piwik\Piwik; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; +use Piwik\Translate; + +/** + * @group Cache + */ +class CacheTest extends IntegrationTestCase +{ + public function setUp() + { + } + + public function tearDown() + { + } + + public function test_getLazyCache_shouldCreateAnInstanceOfLazy() + { + $cache = Cache::getLazyCache(); + + $this->assertTrue($cache instanceof Cache\Lazy); + } + + public function test_getLazyCache_shouldAlwaysReturnTheSameInstance() + { + $cache1 = Cache::getLazyCache(); + $cache2 = Cache::getLazyCache(); + + $this->assertSame($cache1, $cache2); + } + + public function test_getEagerCache_shouldCreateAnInstanceOfEager() + { + $cache = Cache::getEagerCache(); + + $this->assertTrue($cache instanceof Cache\Eager); + } + + public function test_getEagerCache_shouldAlwaysReturnTheSameInstance() + { + $cache1 = Cache::getEagerCache(); + $cache2 = Cache::getEagerCache(); + + $this->assertSame($cache1, $cache2); + } + + public function test_getEagerCache_shouldPersistOnceEventWasTriggered() + { + StaticContainer::clearContainer(); + $storageId = 'eagercache-test-ui'; + $cache = Cache::getEagerCache(); + $cache->save('test', 'mycontent'); // make sure something was changed, otherwise it won't save anything + + /** @var \Piwik\Cache\Backend $backend */ + $backend = StaticContainer::getContainer()->get('Piwik\Cache\Backend'); + $this->assertFalse($backend->doContains($storageId)); + + Piwik::postEvent('Request.dispatch.end'); // should trigger save + + $this->assertTrue($backend->doContains($storageId)); + } + + public function test_getTransientCache_shouldCreateAnInstanceOfTransient() + { + $cache = Cache::getTransientCache(); + + $this->assertTrue($cache instanceof Cache\Transient); + } + + public function test_getTransientCache_shouldAlwaysReturnTheSameInstance() + { + $cache1 = Cache::getTransientCache(); + $cache2 = Cache::getTransientCache(); + + $this->assertSame($cache1, $cache2); + } + + public function test_flushAll_shouldActuallyFlushAllCaches() + { + $cache1 = Cache::getTransientCache(); + $cache2 = Cache::getLazyCache(); + $cache3 = Cache::getEagerCache(); + + $cache1->save('test1', 'content'); + $cache2->save('test2', 'content'); + $cache3->save('test3', 'content'); + + $this->assertTrue($cache1->contains('test1')); + $this->assertTrue($cache2->contains('test2')); + $this->assertTrue($cache3->contains('test3')); + + Cache::flushAll(); + + $this->assertFalse($cache1->contains('test1')); + $this->assertFalse($cache2->contains('test2')); + $this->assertFalse($cache3->contains('test3')); + } + +} diff --git a/tests/PHPUnit/Integration/Plugin/ManagerTest.php b/tests/PHPUnit/Integration/Plugin/ManagerTest.php index 3b6265b4a52943b0f6dbd96d35372758ff07c147..e9bd4ad801a9b3818a218450bd9dfaf1d7d210e3 100644 --- a/tests/PHPUnit/Integration/Plugin/ManagerTest.php +++ b/tests/PHPUnit/Integration/Plugin/ManagerTest.php @@ -8,10 +8,10 @@ namespace Piwik\Tests\Integration\Plugin; -use Piwik\Cache\PersistentCache; use Piwik\Db; use Piwik\Plugin; use Piwik\Settings\Storage; +use Piwik\Cache as PiwikCache; use Piwik\Tests\Integration\Settings\IntegrationTestCase; /** @@ -20,6 +20,8 @@ use Piwik\Tests\Integration\Settings\IntegrationTestCase; */ class ManagerTest extends IntegrationTestCase { + private $trackerCacheId = 'PluginsTracker'; + /** * @var Plugin\Manager */ @@ -43,18 +45,18 @@ class ManagerTest extends IntegrationTestCase public function test_loadTrackerPlugins_shouldCacheListOfPlugins() { $cache = $this->getCacheForTrackerPlugins(); - $this->assertFalse($cache->has()); + $this->assertFalse($cache->contains($this->trackerCacheId)); $pluginsToLoad = $this->manager->loadTrackerPlugins(); - $this->assertTrue($cache->has()); - $this->assertEquals($pluginsToLoad, $cache->get()); + $this->assertTrue($cache->contains($this->trackerCacheId)); + $this->assertEquals($pluginsToLoad, $cache->fetch($this->trackerCacheId)); } public function test_loadTrackerPlugins_shouldBeAbleToLoadPluginsCorrectWhenItIsCached() { $pluginsToLoad = array('CoreHome', 'UserSettings', 'Login', 'CoreAdminHome'); - $this->getCacheForTrackerPlugins()->set($pluginsToLoad); + $this->getCacheForTrackerPlugins()->save($this->trackerCacheId, $pluginsToLoad); $pluginsToLoad = $this->manager->loadTrackerPlugins(); @@ -65,7 +67,7 @@ class ManagerTest extends IntegrationTestCase public function test_loadTrackerPlugins_shouldUnloadAllPlugins_IfThereAreNoneToLoad() { $pluginsToLoad = array(); - $this->getCacheForTrackerPlugins()->set($pluginsToLoad); + $this->getCacheForTrackerPlugins()->save($this->trackerCacheId, $pluginsToLoad); $pluginsToLoad = $this->manager->loadTrackerPlugins(); @@ -75,7 +77,7 @@ class ManagerTest extends IntegrationTestCase private function getCacheForTrackerPlugins() { - return new PersistentCache('PluginsTracker'); + return PiwikCache::getEagerCache(); } private function assertOnlyTrackerPluginsAreLoaded($expectedPluginNamesLoaded) diff --git a/tests/PHPUnit/Integration/Tracker/SettingsStorageTest.php b/tests/PHPUnit/Integration/Tracker/SettingsStorageTest.php index 0aa2a49627d515abc255ad48641309610d594afe..dd17e673143bbeae7ce34cb272248933e0b74223 100644 --- a/tests/PHPUnit/Integration/Tracker/SettingsStorageTest.php +++ b/tests/PHPUnit/Integration/Tracker/SettingsStorageTest.php @@ -8,8 +8,7 @@ namespace Piwik\Tests\Integration\Tracker; -use Piwik\Cache\PersistentCache; -use Piwik\Option; +use Piwik\Cache as PiwikCache; use Piwik\Settings\Storage; use Piwik\Tests\Integration\Settings\StorageTest; use Piwik\Tracker\Cache; @@ -43,11 +42,16 @@ class SettingsStorageTest extends StorageTest { $this->setSettingValueInCache('my0815RandomName'); - $this->assertTrue($this->getCache()->has()); + $this->assertTrue($this->hasCache()); SettingsStorage::clearCache(); - $this->assertFalse($this->getCache()->has()); + $this->assertFalse($this->hasCache()); + } + + private function hasCache() + { + return $this->getCache()->contains($this->storage->getOptionKey()); } public function test_storageShouldNotCastAnyCachedValue() @@ -62,12 +66,12 @@ class SettingsStorageTest extends StorageTest $this->storage->setValue($this->setting, 5); $this->storage->save(); - $this->assertFalse($this->getCache()->has()); + $this->assertFalse($this->hasCache()); $this->assertNotFalse($this->getValueFromOptionTable()); // make sure saved in db $storage = $this->buildStorage(); $this->assertEquals(5, $storage->getValue($this->setting)); - $this->assertTrue($this->getCache()->has()); + $this->assertTrue($this->hasCache()); } public function test_storageCreateACacheEntryIfNoCacheExistsYet() @@ -77,7 +81,7 @@ class SettingsStorageTest extends StorageTest $this->setSettingValueAndMakeSureCacheGetsCreated('myVal'); - $cache = $this->getCache()->get(); + $cache = $this->getCache()->fetch($this->storage->getOptionKey()); $this->assertEquals(array( $this->setting->getKey() => 'myVal' @@ -91,13 +95,13 @@ class SettingsStorageTest extends StorageTest private function getCache() { - return new PersistentCache($this->storage->getOptionKey()); + return PiwikCache::getEagerCache(); } private function setSettingValueInCache($value) { $cache = $this->getCache(); - $cache->set(array( + $cache->save($this->storage->getOptionKey(), array( $this->setting->getKey() => $value )); } diff --git a/tests/PHPUnit/Integration/Tracker/VisitTest.php b/tests/PHPUnit/Integration/Tracker/VisitTest.php index ce5f4baf8a32aa38e474223ffe89932fa04fe727..2764e4a2aa9941166d8b3d1832445ae6f4e8af5c 100644 --- a/tests/PHPUnit/Integration/Tracker/VisitTest.php +++ b/tests/PHPUnit/Integration/Tracker/VisitTest.php @@ -9,7 +9,8 @@ namespace Piwik\Tests\Integration\Tracker; use Piwik\Access; -use Piwik\Cache\PluginAwareStaticCache; +use Piwik\Cache; +use Piwik\CacheId; use Piwik\Date; use Piwik\Network\IPUtils; use Piwik\Plugin\Manager; @@ -334,8 +335,8 @@ class VisitTest extends IntegrationTestCase $dimensions[] = $dim; } - $cache = new PluginAwareStaticCache('VisitDimensions'); - $cache->set($dimensions); + $cache = Cache::getTransientCache(); + $cache->save(CacheId::pluginAware('VisitDimensions'), $dimensions); } } diff --git a/tests/PHPUnit/TestingEnvironment.php b/tests/PHPUnit/TestingEnvironment.php index 3378f99444c6f245ef1ad0ded0a14bf23d432e66..9f31dfd0ed46f1a575fadd4b28594a11ace46495 100644 --- a/tests/PHPUnit/TestingEnvironment.php +++ b/tests/PHPUnit/TestingEnvironment.php @@ -145,7 +145,7 @@ class Piwik_TestingEnvironment $testingEnvironment->configFileGlobal, $testingEnvironment->configFileLocal, $testingEnvironment->configFileCommon )); - \Piwik\CacheFile::$invalidateOpCacheBeforeRead = true; + \Piwik\Cache\Backend\File::$invalidateOpCacheBeforeRead = true; Piwik::addAction('Access.createAccessSingleton', function($access) use ($testingEnvironment) { if (!$testingEnvironment->testUseRegularAuth) {