From 095c15d557b0cdc13dd2e9eaced191465a0bf32b Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 1 Aug 2011 22:54:49 -0400 Subject: [PATCH] Fixing issues with duplicate content/empty tags with CacheHelper. Added internal tag munging proposed by 'FelipePtChO'. Uncommented a test that was failing. Fixes #1857 --- cake/libs/view/helpers/cache.php | 39 ++++++++++++++++++- cake/libs/view/view.php | 2 +- .../cases/libs/view/helpers/cache.test.php | 27 +++++++------ 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index b22b890d69d..cdc70c202a1 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -54,6 +54,13 @@ class CacheHelper extends AppHelper { * @access public */ var $cacheAction; +/** + * Counter used for counting nocache section tags. + * + * @var integer + */ + var $_counter = 0; + /** * Main method used to cache a view * @@ -134,10 +141,13 @@ function cache($file, $out, $cache = false) { } if ($cacheTime != '' && $cacheTime > 0) { + $out = preg_replace_callback('//', array($this, '_replaceSection'), $out); + $this->__parseFile($file, $out); if ($cache === true) { $cached = $this->__parseOutput($out); $this->__writeFile($cached, $cacheTime, $useCallbacks); + $out = $this->_stripTags($out); } return $out; } else { @@ -157,7 +167,8 @@ function __parseFile($file, $cache) { } elseif ($file = fileExistsInPath($file)) { $file = file_get_contents($file); } - preg_match_all('/((?<=)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $outputResult, PREG_PATTERN_ORDER); + + preg_match_all('/((?<=)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $outputResult, PREG_PATTERN_ORDER); preg_match_all('/(?<=)([\\s\\S]*?)(?=<\/cake:nocache>)/i', $file, $fileResult, PREG_PATTERN_ORDER); $fileResult = $fileResult[0]; $outputResult = $outputResult[0]; @@ -183,6 +194,30 @@ function __parseFile($file, $cache) { } } } +/** + * Munges the output from a view with cache tags, and numbers the sections. + * This helps solve issues with empty/duplicate content. + * + * @param string $content The content to munge. + * @return string The content with cake:nocache tags replaced. + */ + function _replaceSection($matches) { + $this->_counter += 1; + return sprintf('', $this->_counter); + } + +/** + * Strip cake:nocache tags from a string. Since View::render() + * only removes un-numbered nocache tags, remove all the numbered ones. + * This is the complement to _replaceSection. + * + * @param string $content String to remove tags from. + * @return string String with tags removed. + */ + function _stripTags($content) { + return preg_replace('#<\/?cake\:nocache(\:\d{3})?>#', '', $content); + } + /** * Parse the output and replace cache tags * @@ -290,4 +325,4 @@ function __writeFile($content, $timestamp, $useCallbacks = false) { return cache('views' . DS . $cache, $file, $timestamp); } } -?> \ No newline at end of file +?> diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index b6470c91512..eecdedc5db1 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -687,7 +687,7 @@ function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = fal $cache->controllerName = $this->name; $cache->layout = $this->layout; $cache->cacheAction = $this->cacheAction; - $cache->cache($___viewFn, $out, $cached); + $out = $cache->cache($___viewFn, $out, $cached); } } return $out; diff --git a/cake/tests/cases/libs/view/helpers/cache.test.php b/cake/tests/cases/libs/view/helpers/cache.test.php index 6dc47cc7472..819f7661cfe 100644 --- a/cake/tests/cases/libs/view/helpers/cache.test.php +++ b/cake/tests/cases/libs/view/helpers/cache.test.php @@ -352,11 +352,17 @@ function testCacheBaseNameControllerName() { * This test must be uncommented/fixed in next release (1.2+) * * @return void - * @access public - * - function testCacheEmptySections () { + */ + function testCacheEmptySections() { $this->Controller->cache_parsing(); - $this->Controller->cacheAction = array('cacheTest' => 21600); + $this->Controller->params = array( + 'controller' => 'cacheTest', + 'action' => 'cache_empty_sections', + 'url' => array(), + 'pass' => array(), + 'named' => array() + ); + $this->Controller->cacheAction = array('cache_empty_sections' => 21600); $this->Controller->here = '/cacheTest/cache_empty_sections'; $this->Controller->action = 'cache_empty_sections'; $this->Controller->layout = 'cache_empty_sections'; @@ -379,17 +385,16 @@ function testCacheEmptySections () { $this->assertNoPattern('/cake:nocache/', $contents); $this->assertPattern( '@\s*Posts\s*' . - "<\?php \$x = 1; \?>\s*" . + '<\?php \$x \= 1; \?>\s*' . '\s*' . '\s*' . - "<\?php \$x\+\+; \?>\s*" . - "<\?php \$x\+\+; \?>\s*" . + '<\?php \$x\+\+; \?>\s*' . + '<\?php \$x\+\+; \?>\s*' . 'View Content\s*' . - "<\?php \$y = 1; \?>\s*" . - "<\?php echo 'cached count is:' . \$x; \?>\s*" . + '<\?php \$y = 1; \?>\s*' . + '<\?php echo \'cached count is: \' . \$x; \?>\s*' . '@', $contents); @unlink($filename); } -*/ } -?> \ No newline at end of file +?>