From 01e48f269df59e02798dad4a698c125d76b0ed70 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Thu, 9 Jul 2015 22:14:39 +0200 Subject: [PATCH] CachedPage: move to a proper file, add tests Modifications - rename `pageCache` to `CachedPage` - move utilities to `Cache` - do not access globals - apply coding rules - update LinkDB and test code - add test coverage Signed-off-by: VirtualTam --- application/Cache.php | 46 ++++++++++++ application/CachedPage.php | 63 +++++++++++++++++ application/LinkDB.php | 7 +- index.php | 113 +++++++++-------------------- tests/CacheTest.php | 63 +++++++++++++++++ tests/CachedPageTest.php | 121 ++++++++++++++++++++++++++++++++ tests/LinkDBTest.php | 8 +-- tests/utils/ReferenceLinkDB.php | 1 - 8 files changed, 334 insertions(+), 88 deletions(-) create mode 100644 application/Cache.php create mode 100644 application/CachedPage.php create mode 100644 tests/CacheTest.php create mode 100644 tests/CachedPageTest.php diff --git a/application/Cache.php b/application/Cache.php new file mode 100644 index 0000000..9c7e818 --- /dev/null +++ b/application/Cache.php @@ -0,0 +1,46 @@ +cacheDir = $cacheDir; + $this->url = $url; + $this->filename = $this->cacheDir.'/'.sha1($url).'.cache'; + $this->shouldBeCached = $shouldBeCached; + } + + /** + * Returns the cached version of a page, if it exists and should be cached + * + * @return a cached version of the page if it exists, null otherwise + */ + public function cachedVersion() + { + if (!$this->shouldBeCached) { + return null; + } + if (is_file($this->filename)) { + return file_get_contents($this->filename); + } + return null; + } + + /** + * Puts a page in the cache + * + * @param string $pageContent XML content to cache + */ + public function cache($pageContent) + { + if (!$this->shouldBeCached) { + return; + } + file_put_contents($this->filename, $pageContent); + } +} diff --git a/application/LinkDB.php b/application/LinkDB.php index 1e16fef..463aa47 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php @@ -269,8 +269,10 @@ You use the community supported version of the original Shaarli project, by Seba /** * Saves the database from memory to disk + * + * @param string $pageCacheDir page cache directory */ - public function savedb() + public function savedb($pageCacheDir) { if (!$this->_loggedIn) { // TODO: raise an Exception instead @@ -280,7 +282,7 @@ You use the community supported version of the original Shaarli project, by Seba $this->_datastore, self::$phpPrefix.base64_encode(gzdeflate(serialize($this->_links))).self::$phpSuffix ); - invalidateCaches(); + invalidateCaches($pageCacheDir); } /** @@ -439,4 +441,3 @@ You use the community supported version of the original Shaarli project, by Seba return $linkDays; } } -?> diff --git a/index.php b/index.php index 2c731e9..84b8f01 100755 --- a/index.php +++ b/index.php @@ -70,6 +70,8 @@ if (is_file($GLOBALS['config']['CONFIG_FILE'])) { } // Shaarli library +require_once 'application/Cache.php'; +require_once 'application/CachedPage.php'; require_once 'application/LinkDB.php'; require_once 'application/TimeZone.php'; require_once 'application/Utils.php'; @@ -202,63 +204,6 @@ function checkUpdate() } -// ----------------------------------------------------------------------------------------------- -// Simple cache system (mainly for the RSS/ATOM feeds). - -class pageCache -{ - private $url; // Full URL of the page to cache (typically the value returned by pageUrl()) - private $shouldBeCached; // boolean: Should this url be cached? - private $filename; // Name of the cache file for this url. - - /* - $url = URL (typically the value returned by pageUrl()) - $shouldBeCached = boolean. If false, the cache will be disabled. - */ - public function __construct($url,$shouldBeCached) - { - $this->url = $url; - $this->filename = $GLOBALS['config']['PAGECACHE'].'/'.sha1($url).'.cache'; - $this->shouldBeCached = $shouldBeCached; - } - - // If the page should be cached and a cached version exists, - // returns the cached version (otherwise, return null). - public function cachedVersion() - { - if (!$this->shouldBeCached) return null; - if (is_file($this->filename)) { return file_get_contents($this->filename); exit; } - return null; - } - - // Put a page in the cache. - public function cache($page) - { - if (!$this->shouldBeCached) return; - file_put_contents($this->filename,$page); - } - - // Purge the whole cache. - // (call with pageCache::purgeCache()) - public static function purgeCache() - { - if (is_dir($GLOBALS['config']['PAGECACHE'])) - { - $handler = opendir($GLOBALS['config']['PAGECACHE']); - if ($handler!==false) - { - while (($filename = readdir($handler))!==false) - { - if (endsWith($filename,'.cache')) { unlink($GLOBALS['config']['PAGECACHE'].'/'.$filename); } - } - closedir($handler); - } - } - } - -} - - // ----------------------------------------------------------------------------------------------- // Log to text file function logm($message) @@ -718,8 +663,16 @@ function showRSS() // Cache system $query = $_SERVER["QUERY_STRING"]; - $cache = new pageCache(pageUrl(),startsWith($query,'do=rss') && !isLoggedIn()); - $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } + $cache = new CachedPage( + $GLOBALS['config']['PAGECACHE'], + pageUrl(), + startsWith($query,'do=rss') && !isLoggedIn() + ); + $cached = $cache->cachedVersion(); + if (! empty($cached)) { + echo $cached; + exit; + } // If cached was not found (or not usable), then read the database and build the response: $LINKSDB = new LinkDB( @@ -798,11 +751,19 @@ function showATOM() // Cache system $query = $_SERVER["QUERY_STRING"]; - $cache = new pageCache(pageUrl(),startsWith($query,'do=atom') && !isLoggedIn()); - $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } - // If cached was not found (or not usable), then read the database and build the response: + $cache = new CachedPage( + $GLOBALS['config']['PAGECACHE'], + pageUrl(), + startsWith($query,'do=atom') && !isLoggedIn() + ); + $cached = $cache->cachedVersion(); + if (!empty($cached)) { + echo $cached; + exit; + } -// Read links from database (and filter private links if used it not logged in). + // If cached was not found (or not usable), then read the database and build the response: + // Read links from database (and filter private links if used it not logged in). $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'], @@ -884,7 +845,11 @@ function showATOM() function showDailyRSS() { // Cache system $query = $_SERVER["QUERY_STRING"]; - $cache = new pageCache(pageUrl(), startsWith($query, 'do=dailyrss') && !isLoggedIn()); + $cache = new CachedPage( + $GLOBALS['config']['PAGECACHE'], + pageUrl(), + startsWith($query,'do=dailyrss') && !isLoggedIn() + ); $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; @@ -1076,7 +1041,7 @@ function renderPage() // -------- User wants to logout. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout')) { - invalidateCaches(); + invalidateCaches($GLOBALS['config']['PAGECACHE']); logout(); header('Location: ?'); exit; @@ -1383,7 +1348,7 @@ function renderPage() $value['tags']=trim(implode(' ',$tags)); $LINKSDB[$key]=$value; } - $LINKSDB->savedb(); // Save to disk. + $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. echo ''; exit; } @@ -1400,7 +1365,7 @@ function renderPage() $value['tags']=trim(implode(' ',$tags)); $LINKSDB[$key]=$value; } - $LINKSDB->savedb(); // Save to disk. + $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. echo ''; exit; } @@ -1429,7 +1394,7 @@ function renderPage() 'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags)); if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. $LINKSDB[$linkdate] = $link; - $LINKSDB->savedb(); // Save to disk. + $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. pubsubhub(); // If we are called from the bookmarklet, we must close the popup: @@ -1462,7 +1427,7 @@ function renderPage() // - we are protected from XSRF by the token. $linkdate=$_POST['lf_linkdate']; unset($LINKSDB[$linkdate]); - $LINKSDB->savedb(); // save to disk + $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { echo ''; exit; } @@ -1751,7 +1716,7 @@ function importFile() } } } - $LINKSDB->savedb(); + $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); echo ''; } @@ -2386,14 +2351,6 @@ function resizeImage($filepath) return true; } -// Invalidate caches when the database is changed or the user logs out. -// (e.g. tags cache). -function invalidateCaches() -{ - unset($_SESSION['tags']); // Purge cache attached to session. - pageCache::purgeCache(); // Purge page cache shared by sessions. -} - try { mergeDeprecatedConfig($GLOBALS, isLoggedIn()); } catch(Exception $e) { diff --git a/tests/CacheTest.php b/tests/CacheTest.php new file mode 100644 index 0000000..4caf655 --- /dev/null +++ b/tests/CacheTest.php @@ -0,0 +1,63 @@ +assertFileNotExists(self::$testCacheDir.'/'.$page.'.cache'); + } + } + + /** + * Purge cached pages and session cache + */ + public function testInvalidateCaches() + { + $this->assertArrayNotHasKey('tags', $_SESSION); + $_SESSION['tags'] = array('goodbye', 'cruel', 'world'); + + invalidateCaches(self::$testCacheDir); + foreach (self::$pages as $page) { + $this->assertFileNotExists(self::$testCacheDir.'/'.$page.'.cache'); + } + + $this->assertArrayNotHasKey('tags', $_SESSION); + } +} diff --git a/tests/CachedPageTest.php b/tests/CachedPageTest.php new file mode 100644 index 0000000..e97af03 --- /dev/null +++ b/tests/CachedPageTest.php @@ -0,0 +1,121 @@ +assertFileNotExists(self::$filename); + $page->cache('

Some content

'); + $this->assertFileExists(self::$filename); + $this->assertEquals( + '

Some content

', + file_get_contents(self::$filename) + ); + } + + /** + * "Cache" a page's content - the page is not to be cached + */ + public function testShouldNotCache() + { + $page = new CachedPage(self::$testCacheDir, self::$url, false); + + $this->assertFileNotExists(self::$filename); + $page->cache('

Some content

'); + $this->assertFileNotExists(self::$filename); + } + + /** + * Return a page's cached content + */ + public function testCachedVersion() + { + $page = new CachedPage(self::$testCacheDir, self::$url, true); + + $this->assertFileNotExists(self::$filename); + $page->cache('

Some content

'); + $this->assertFileExists(self::$filename); + $this->assertEquals( + '

Some content

', + $page->cachedVersion() + ); + } + + /** + * Return a page's cached content - the file does not exist + */ + public function testCachedVersionNoFile() + { + $page = new CachedPage(self::$testCacheDir, self::$url, true); + + $this->assertFileNotExists(self::$filename); + $this->assertEquals( + null, + $page->cachedVersion() + ); + } + + /** + * Return a page's cached content - the page is not to be cached + */ + public function testNoCachedVersion() + { + $page = new CachedPage(self::$testCacheDir, self::$url, false); + + $this->assertFileNotExists(self::$filename); + $this->assertEquals( + null, + $page->cachedVersion() + ); + } +} diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index 504c819..451f1d6 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php @@ -3,6 +3,7 @@ * Link datastore tests */ +require_once 'application/Cache.php'; require_once 'application/LinkDB.php'; require_once 'application/Utils.php'; require_once 'tests/utils/ReferenceLinkDB.php'; @@ -180,11 +181,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase 'tags'=>'unit test' ); $testDB[$link['linkdate']] = $link; - - // TODO: move PageCache to a proper class/file - function invalidateCaches() {} - - $testDB->savedb(); + $testDB->savedb('tests'); $testDB = new LinkDB(self::$testDatastore, true, false); $this->assertEquals($dbSize + 1, sizeof($testDB)); @@ -514,4 +511,3 @@ class LinkDBTest extends PHPUnit_Framework_TestCase ); } } -?> diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php index 0b22572..47b5182 100644 --- a/tests/utils/ReferenceLinkDB.php +++ b/tests/utils/ReferenceLinkDB.php @@ -125,4 +125,3 @@ class ReferenceLinkDB return $this->_privateCount; } } -?>